chill-jam-10-2024/scripts/AudioCollection.cs

93 lines
1.7 KiB
C#

using System;
using Godot;
public partial class AudioCollection : Node
{
[Signal] public delegate void FinishedEventHandler();
private enum State
{
Error,
Ready,
Playing,
Timeout
}
[Export] public bool Shuffle = false;
[Export] public double Timeout = 0;
[Export] public bool RandomPitch;
[Export] public float PitchStart;
[Export] public float PitchEnd;
private State _state;
private RandomNumberGenerator _rng = new RandomNumberGenerator();
private int _count;
private int _currentChild;
private double _currentTimeout = 0;
private AudioStreamPlayer _currentPlayer;
public override void _Ready()
{
_rng.Randomize();
_count = GetChildCount();
_currentChild = Shuffle ? _rng.RandiRange(0, _count) : 0;
_state = _count == 0 ? State.Error : State.Ready;
}
public override void _Process(double delta)
{
switch (_state)
{
case State.Playing:
if (!_currentPlayer.IsPlaying())
{
_state = State.Timeout;
EmitSignal(SignalName.Finished);
}
break;
case State.Timeout:
if (_currentTimeout < Timeout)
{
_currentTimeout += delta;
}
else
{
_state = State.Ready;
_currentTimeout = 0;
}
break;
}
}
public void Play()
{
switch (_state)
{
case State.Ready:
var player = GetChild<AudioStreamPlayer>(_currentChild);
player.PitchScale = RandomPitch ? _rng.RandfRange(PitchStart, PitchEnd) : 1;
player.Play();
_state = State.Playing;
_currentChild = Shuffle ? _rng.RandiRange(0, _count) : (_currentChild + 1) % _count;
_currentPlayer = player;
break;
}
}
public void Stop()
{
switch (_state)
{
case State.Playing:
_currentPlayer.Stop();
break;
}
}
}