extends Node ## Small synthesized arcade effects; no external audio assets required. var voices: Array[AudioStreamPlayer] = [] var sounds: Dictionary = {} var voice_index := 0 func _ready() -> void: for i in range(6): var voice := AudioStreamPlayer.new() voice.volume_db = -17.0 add_child(voice) voices.append(voice) sounds["fire"] = tone(1300.0, 220.0, 0.09) sounds["hit"] = tone(170.0, 40.0, 0.18) sounds["zap"] = tone(1700.0, 70.0, 0.55) sounds["death"] = tone(440.0, 35.0, 0.7) sounds["level"] = tone(220.0, 880.0, 0.4) func tone(start: float, finish: float, duration: float) -> AudioStreamWAV: var samples := PackedByteArray() var count := int(22050 * duration) samples.resize(count * 2) var phase := 0.0 for i in range(count): var t := float(i) / count phase += lerpf(start, finish, t) * TAU / 22050.0 var envelope := minf(t * 50.0, 1.0) * pow(1.0 - t, 1.5) var value := int((sin(phase) + sin(phase * 2.0) * 0.25) * envelope * 18000) samples.encode_s16(i * 2, value) var stream := AudioStreamWAV.new() stream.format = AudioStreamWAV.FORMAT_16_BITS stream.mix_rate = 22050 stream.data = samples return stream func play(effect: String) -> void: if not sounds.has(effect) or voices.is_empty(): return var voice := voices[voice_index] voice_index = (voice_index + 1) % voices.size() voice.stream = sounds[effect] voice.play() func stop() -> void: for voice in voices: voice.stop()