extends Node ## SoundManager (автоматически запускается как Autoload). ## Этап 4: звуковое сопровождение. Проигрывает короткие SFX через AudioManager2D. # Пулы проигрывателей для каждого эффекта (чтобы звуки могли накладываться) var _pool: Dictionary = {} var master_bus: String = "Master" func _ready() -> void: print("[SoundManager] Звуковой менеджер готов.") # Играть эффект по имени: play("coin"), play("bump"), ... func play(name: String) -> void: if not has_method(name): return call(name) # ---- Конкретные эффекты ---- func coin() -> void: _play("sound_coin") func bump() -> void: _play("sound_bump") func brick() -> void: _play("sound_brick") func die() -> void: _play("sound_die") func win() -> void: _play("sound_win") func over() -> void: _play("sound_over") func _play(key: String) -> void: var players: Array = _pool.get(key, Array()) # Находим свободный проигрыватель var player: AudioStreamPlayer2D = null for p in players: if not p.playing: player = p break if player == null: # Создаём новый player = AudioStreamPlayer2D.new() player.bus = master_bus add_child(player) players.push_back(player) # Не выставляем owner — это autoload, дерево сцены не наше player.stream = load("res://audio/%s.ogg" % key) if player.stream == null: printerr("[SoundManager] Не удалось загрузить: ", key) return player.play(0.0) func _exit_tree() -> void: for p in _pool.values(): for player in p: if is_instance_valid(player): player.queue_free() _pool.clear()