From eb63e05dd266da6c05b70375168d7565bf74eda1 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sat, 9 Sep 2023 01:00:13 -0700 Subject: [PATCH] audio manager --- Assets/Music/gillette.mp3.import | 6 +- Utils/AudioManager.cs | 191 +++++++++++++++++++++++++++++++ Utils/World.cs | 21 ++-- project.godot | 1 + 4 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 Utils/AudioManager.cs diff --git a/Assets/Music/gillette.mp3.import b/Assets/Music/gillette.mp3.import index 35c9a70..21f3d81 100644 --- a/Assets/Music/gillette.mp3.import +++ b/Assets/Music/gillette.mp3.import @@ -12,8 +12,8 @@ dest_files=["res://.godot/imported/gillette.mp3-5dd6f93f1f9df01778f80e3dd2caeb1e [params] -loop=false -loop_offset=0 -bpm=0 +loop=true +loop_offset=0.0 +bpm=0.0 beat_count=0 bar_beats=4 diff --git a/Utils/AudioManager.cs b/Utils/AudioManager.cs new file mode 100644 index 0000000..45b9185 --- /dev/null +++ b/Utils/AudioManager.cs @@ -0,0 +1,191 @@ +using Godot; +using System.Collections.Generic; + +namespace SupaLidlGame.Utils; + +public sealed partial class AudioManager : Node +{ + public enum Layer + { + Ambient, + BackgroundMusic, + ActiveMusic, + }; + + //private Array _players; + + private Dictionary _players; + + public override void _Ready() + { + _players = new Dictionary(); + _players.Add(Layer.Ambient, null); + _players.Add(Layer.BackgroundMusic, null); + _players.Add(Layer.ActiveMusic, null); + } + + public void PlayAmbient(AudioStream stream) + { + StopPlayback(Layer.Ambient); + _players[Layer.Ambient] = CreateAudioStreamPlayer(stream); + FadeIn(_players[Layer.Ambient]); + } + + public void PlayBackground(AudioStream stream) + { + StopPlayback(Layer.BackgroundMusic); + _players[Layer.BackgroundMusic] = CreateAudioStreamPlayer(stream); + if (!IsLayerValid(Layer.ActiveMusic)) + { + FadeIn(_players[Layer.BackgroundMusic]); + } + } + + public void StopBackground() + { + StopPlayback(Layer.BackgroundMusic); + } + + public void PlayActive(AudioStream stream) + { + _players[Layer.ActiveMusic] = CreateAudioStreamPlayer(stream); + _players[Layer.ActiveMusic].Play(); + if (IsLayerValid(Layer.BackgroundMusic)) + { + Pause(Layer.BackgroundMusic); + } + } + + public void StopActive() + { + StopPlayback(Layer.ActiveMusic); + if (IsLayerValid(Layer.BackgroundMusic)) + { + if (_players[Layer.BackgroundMusic].StreamPaused) + { + Unpause(Layer.BackgroundMusic); + } + else + { + _players[Layer.BackgroundMusic].Play(); + } + } + } + + public void Play(AudioStream stream, Layer layer) + { + switch (layer) + { + case Layer.Ambient: + PlayAmbient(stream); + break; + case Layer.BackgroundMusic: + PlayBackground(stream); + break; + case Layer.ActiveMusic: + PlayActive(stream); + break; + } + } + + public void Stop(Layer layer) + { + switch (layer) + { + case Layer.Ambient: + case Layer.BackgroundMusic: + StopPlayback(layer); + break; + case Layer.ActiveMusic: + StopActive(); + break; + } + } + + private void Pause(Layer layer) + { + var player = _players[layer]; + + if (player is null || !IsInstanceValid(player)) + { + return; + } + + FadeOut(player, pause: true); + } + + private void Unpause(Layer layer) + { + var player = _players[layer]; + + if (player is null || !IsInstanceValid(player)) + { + return; + } + + FadeIn(player, unpause: true); + } + + private void StopPlayback(Layer layer) + { + var player = _players[layer]; + + if (player is null || !IsInstanceValid(player)) + { + return; + } + + FadeOut(player, kill: true); + _players[layer] = null; + } + + private AudioStreamPlayer CreateAudioStreamPlayer(AudioStream stream) + { + var player = new AudioStreamPlayer(); + AddChild(player); + player.Stream = stream; + return player; + } + + private void FadeOut( + AudioStreamPlayer player, + double time = 1.0, + bool kill = false, + bool pause = false) + { + var tween = player.GetTree().CreateTween().BindNode(player); + tween.TweenProperty(player, "volume_db", 0, time); + if (kill) + { + tween.TweenCallback(Callable.From(player.QueueFree)); + } + else if (pause) + { + tween.TweenCallback( + Callable.From(() => player.StreamPaused = true)); + } + } + + private void FadeIn(AudioStreamPlayer player, + double time = 1.0, + bool unpause = false) + { + if (unpause) + { + player.StreamPaused = false; + } + else + { + player.Play(); + } + player.VolumeDb = 0; + var tween = player.GetTree().CreateTween().BindNode(player); + tween.TweenProperty(player, "volume_db", 1, time); + } + + public bool IsLayerValid(Layer layer) + { + var player = _players[layer]; + return player is not null && IsInstanceValid(player); + } +} diff --git a/Utils/World.cs b/Utils/World.cs index 6867df1..614a7d0 100644 --- a/Utils/World.cs +++ b/Utils/World.cs @@ -117,23 +117,19 @@ public partial class World : Node private void RegisterBoss(Boss boss) { + if (boss is null) + { + DeregisterBoss(CurrentBoss); + return; + } CurrentBoss = boss; - MusicPlayer.Stream = boss?.Music; - // TODO: use an audio manager - if (MusicPlayer.Stream is null) - { - MusicPlayer.Stop(); - } - else - { - MusicPlayer.Play(); - } + GetNode("/root/AudioManager").PlayActive(boss.Music); } private void DeregisterBoss(Boss boss) { CurrentBoss = null; - MusicPlayer.Stop(); + GetNode("/root/AudioManager").StopActive(); } private void LoadMap(Map map) @@ -230,6 +226,9 @@ public partial class World : Node SpawnPlayer(); }; GlobalState.Stats.DeathCount++; + + //EventBus.EmitSignal(EventBus.SignalName.DeregisteredBoss, + // CurrentBoss); }; return CurrentPlayer; diff --git a/project.godot b/project.godot index 64ee799..51ef6fe 100644 --- a/project.godot +++ b/project.godot @@ -22,6 +22,7 @@ GlobalState="*res://State/Global/GlobalState.cs" EventBus="*res://Events/EventBus.cs" BaseUI="*res://UI/Base.tscn" World="*res://Scenes/Level.tscn" +AudioManager="*res://Utils/AudioManager.cs" DebugConsole="*res://Debug/DebugConsole.cs" Panku="*res://addons/panku_console/console.tscn"