class_name JuggleBoardAudio extends Node ## Audio e BGM del JuggleBoard. Nessuna logica di gameplay. const BGM_STREAM := preload("res://games/juggleboard/assets/audio/circus.ogg") const MUSIC_FALLBACK := preload("res://games/juggleboard/scripts/audio/circus_music.gd") var launch: AudioStreamWAV var error: AudioStreamWAV var timeout: AudioStreamWAV var milestone: AudioStreamWAV var victory: AudioStreamWAV var defeat: AudioStreamWAV var lose_heart: AudioStreamWAV var ball_tones: Dictionary = {} var bgm: AudioStreamPlayer func _ready() -> void: _build_effects() _build_bgm() func _build_effects() -> void: launch = AudioFactory.create_tone(660.0, 0.18, 0.3) error = AudioFactory.create_tone(220.0, 0.15, 0.16) timeout = AudioFactory.create_tone(330.0, 0.2, 0.16) milestone = AudioFactory.create_arpeggio([523.25, 659.25, 783.99, 1046.5], 0.12) victory = AudioFactory.create_arpeggio([523.25, 659.25, 783.99, 1046.5, 1318.51, 1567.98], 0.16) defeat = AudioFactory.create_arpeggio([392.0, 329.63, 261.63], 0.18) lose_heart = AudioFactory.create_tone(330.0, 0.15, 0.2) for color_name in JuggleBoardConfig.BALL_NOTES: ball_tones[color_name] = AudioFactory.create_tone(JuggleBoardConfig.BALL_NOTES[color_name], 0.2, 0.3) func _build_bgm() -> void: bgm = AudioStreamPlayer.new() bgm.stream = BGM_STREAM if BGM_STREAM else MUSIC_FALLBACK.generate() bgm.volume_db = -14.0 bgm.process_mode = Node.PROCESS_MODE_ALWAYS add_child(bgm) func play(stream: AudioStream) -> void: if stream: AudioFactory.play_once(self, stream) func play_ball(color_name: String) -> void: play(ball_tones.get(color_name, launch)) func start_music() -> void: bgm.play() func stop_music() -> void: bgm.stop()