first commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
extends Node
|
||||
|
||||
var player_a: AudioStreamPlayer
|
||||
var player_b: AudioStreamPlayer
|
||||
var current_player: AudioStreamPlayer
|
||||
|
||||
var max_volume: float = -5.0
|
||||
var min_volume: float = -80.0
|
||||
|
||||
var active_enemies: Array = []
|
||||
var current_track: AudioStream = null
|
||||
|
||||
# Словарь для сохранения позиции (секунды) каждого трека индивидуально
|
||||
var saved_positions: Dictionary = {}
|
||||
|
||||
func _ready() -> void:
|
||||
# Инициализируем аудио-плееры
|
||||
player_a = AudioStreamPlayer.new()
|
||||
player_b = AudioStreamPlayer.new()
|
||||
add_child(player_a)
|
||||
add_child(player_b)
|
||||
|
||||
# Принудительно подключаем к главному аудио-каналу Godot (Bus 0)
|
||||
if AudioServer.get_bus_count() > 0:
|
||||
player_a.bus = AudioServer.get_bus_name(0)
|
||||
player_b.bus = AudioServer.get_bus_name(0)
|
||||
|
||||
player_a.volume_db = min_volume
|
||||
player_b.volume_db = min_volume
|
||||
current_player = player_a
|
||||
|
||||
# Метод, вызываемый мобом, когда он ЗАМЕЧАЕТ игрока напрямую
|
||||
func register_enemy_vision(enemy: Node, track: AudioStream) -> void:
|
||||
if track == null: return
|
||||
|
||||
if not active_enemies.has(enemy):
|
||||
active_enemies.append(enemy)
|
||||
# Включаем трек последнего заметившего нас врага
|
||||
switch_to_track(track)
|
||||
|
||||
# Метод, вызываемый мобом, когда он ТЕРЯЕТ игрока или УМИРАЕТ
|
||||
func unregister_enemy_vision(enemy: Node, track: AudioStream) -> void:
|
||||
if active_enemies.has(enemy):
|
||||
active_enemies.erase(enemy)
|
||||
|
||||
if active_enemies.size() == 0:
|
||||
fade_out_current()
|
||||
else:
|
||||
# Если остались другие зоркие враги, включаем трек последнего активного моба
|
||||
var remaining_enemy = active_enemies[-1]
|
||||
if remaining_enemy and "custom_battle_music" in remaining_enemy and remaining_enemy.custom_battle_music:
|
||||
switch_to_track(remaining_enemy.custom_battle_music)
|
||||
|
||||
# Логика бесшовного переключения (Crossfade)
|
||||
func switch_to_track(new_track: AudioStream) -> void:
|
||||
if current_track == new_track and current_player.playing:
|
||||
return
|
||||
|
||||
# Запоминаем текущую секунду старого трека перед тем, как его приглушить
|
||||
if current_track != null and current_player.playing:
|
||||
saved_positions[current_track] = current_player.get_playback_position()
|
||||
|
||||
current_track = new_track
|
||||
|
||||
# Выбираем противоположный (свободный) плеер для кроссфейда
|
||||
var next_player = player_b if current_player == player_a else player_a
|
||||
next_player.stream = new_track
|
||||
|
||||
# Принудительно включаем встроенное зацикливание трека в Godot 4 через код
|
||||
if "loop" in next_player.stream:
|
||||
next_player.stream.loop = true
|
||||
elif next_player.stream is AudioStreamOggVorbis:
|
||||
next_player.stream.loop = true
|
||||
|
||||
# Выясняем, с какой секунды продолжить трек
|
||||
var start_pos = saved_positions.get(new_track, 0.0)
|
||||
next_player.play(start_pos)
|
||||
|
||||
# Запускаем плавное выравнивание громкости плееров за 1 секунду
|
||||
var tween = create_tween().set_parallel(true)
|
||||
tween.tween_property(current_player, "volume_db", min_volume, 1.0)
|
||||
tween.tween_property(next_player, "volume_db", max_volume, 1.0)
|
||||
|
||||
var old_player = current_player
|
||||
current_player = next_player
|
||||
|
||||
# Полностью останавливаем старый плеер только после завершения затухания
|
||||
tween.chain().tween_callback(func(): old_player.stop())
|
||||
print("[МУЗЫКА] Боевой режим! Трек запущен/продолжен с секунды: ", start_pos)
|
||||
|
||||
# Логика плавного выключения при выходе из боя
|
||||
func fade_out_current() -> void:
|
||||
current_track = null
|
||||
var tween = create_tween()
|
||||
tween.tween_property(current_player, "volume_db", min_volume, 2.0)
|
||||
tween.tween_callback(func():
|
||||
if active_enemies.size() == 0 and current_player.playing:
|
||||
if current_player.stream:
|
||||
saved_positions[current_player.stream] = current_player.get_playback_position()
|
||||
current_player.stop()
|
||||
print("[МУЗЫКА] Зона безопасна. Боевой трек поставлен на паузу.")
|
||||
)
|
||||
Reference in New Issue
Block a user