using System; using System.Runtime.InteropServices; using Godot; namespace GodotspaceShooter.Scripts; public partial class SoundManager : Node { [Export] private AudioStreamPlayer backgroundMusic; [Export] private AudioStreamPlayer gameOverMusic; [Export] private AudioStreamPlayer3D asteroidExplosionSound; [Export] private AudioStreamPlayer3D playerExplosionSound; [Export] private AudioStreamPlayer3D laserSound; public static SoundManager Instance { get; private set; } public enum Sound { BackgroundMusic, AsteroidExplosion, PlayerExplosion, Laser, GameOver } public override void _Ready() => Instance = this; public void Play(Sound sound, [Optional] Vector3 position) { float pitchScale = 0; if (sound is Sound.Laser or Sound.AsteroidExplosion or Sound.PlayerExplosion) pitchScale = (float)GD.RandRange(0.25f, 1.75f); switch (sound) { case Sound.AsteroidExplosion: asteroidExplosionSound.Position = position; asteroidExplosionSound.PitchScale = pitchScale; asteroidExplosionSound.Play(); break; case Sound.Laser: laserSound.Position = position; laserSound.PitchScale = pitchScale; laserSound.Play(); break; case Sound.PlayerExplosion: playerExplosionSound.Position = position; playerExplosionSound.PitchScale = pitchScale; playerExplosionSound.Play(); break; case Sound.BackgroundMusic: backgroundMusic.Play(); break; case Sound.GameOver: gameOverMusic.Play(); break; default: throw new ArgumentOutOfRangeException(nameof(sound), sound, null); } } public void Stop(Sound sound) { switch (sound) { case Sound.AsteroidExplosion: asteroidExplosionSound.Stop(); break; case Sound.Laser: laserSound.Stop(); break; case Sound.PlayerExplosion: playerExplosionSound.Stop(); break; case Sound.BackgroundMusic: backgroundMusic.Stop(); break; case Sound.GameOver: gameOverMusic.Stop(); break; default: throw new ArgumentOutOfRangeException(nameof(sound), sound, null); } } }