SupaLidlGame/Audio/AudioManager.cs

119 lines
3.0 KiB
C#

using Godot;
using System.Collections.Generic;
namespace SupaLidlGame.Audio;
public sealed partial class AudioManager : Node
{
private ManagedAudioPlayer _ambientPlayer;
private List<ManagedAudioPlayer> _bgPlayers;
public enum Layer
{
Ambient,
Background
}
public AudioManager()
{
_bgPlayers = new();
for (int i = 0; i < 4; i++)
{
_bgPlayers.Add(null);
}
}
public ManagedAudioPlayer CreateAudioPlayer(AudioStream stream)
{
var player = new ManagedAudioPlayer();
player.Stream = stream;
AddChild(player);
return player;
}
/// <summary>
/// Plays ambient audio. Ambient audio will play alongside the current
/// background audio and will replace the current ambient audio.
/// </summary>
public void PlayAmbient(AudioStream stream, float fade = 1)
{
if (IsPlayerValid(_ambientPlayer))
{
_ambientPlayer.FadeOut(fade, true);
}
_ambientPlayer = CreateAudioPlayer(stream);
_ambientPlayer.Play();
}
/// <summary>
/// Plays background audio. Background audio will play if no sublayer above
/// is playing, pause all sublayers below, and replace the current sublayer
/// if it is playing.
/// </summary>
public void PlayBackground(AudioStream stream, int sublayer = 0, float fade = 1)
{
// stop current sublayer if playing
if (IsPlayerValid(_bgPlayers[sublayer]))
{
_bgPlayers[sublayer].FadeOut(fade, true);
}
_bgPlayers[sublayer] = CreateAudioPlayer(stream);
// pause all sublayers below this
for (int i = 0; i < sublayer; i++)
{
if (IsPlayerValid(_bgPlayers[i]))
{
if (!_bgPlayers[i].StreamPaused)
{
_bgPlayers[i]?.FadeOut(fade, pause: true);
}
}
}
// if a sublayer above is not playing then play
if (!IsSublayerAboveValid(sublayer))
{
_bgPlayers[sublayer].Play();
}
}
public void StopBackground(int sublayer, float fade = 1)
{
// kill current sublayer
_bgPlayers[sublayer]?.FadeOut(fade, true);
// if sublayer above is not plyaing, play lowest sublayer
if (!IsSublayerAboveValid(sublayer))
{
for (int i = sublayer - 1; i >= 0; i--)
{
if (IsPlayerValid(_bgPlayers[i]))
{
_bgPlayers[i].FadeIn(fade, unpause: true);
break;
}
}
}
}
private bool IsSublayerAboveValid(int sublayer)
{
for (int i = sublayer + 1; i < 4; i++)
{
if (IsPlayerValid(_bgPlayers[i]))
{
return true;
}
}
return false;
}
private bool IsPlayerValid(ManagedAudioPlayer player)
{
return player is not null && IsInstanceValid(player) && !player.IsDead;
}
}