xiandie/manager/audio_manager/vibe_group_player.gd

108 lines
3.2 KiB
GDScript3
Raw Normal View History

2025-06-25 17:53:16 +00:00
@tool
class_name VibeGroupPlayer
extends Node
var vibe_group: VibeGroup
var _base_player: AudioStreamPlayer
var _embellishment_players = [] as Array[AudioStreamPlayer]
var _embellishment_timers = [] as Array[Timer]
2025-07-03 09:49:00 +00:00
var _base_db := 0.0:
set(val):
_base_db = val
_base_player.volume_db = val
2025-06-25 17:53:16 +00:00
func _init(group: VibeGroup):
vibe_group = group
# 初始化基础播放器
_base_player = AudioStreamPlayer.new()
_base_player.name = "BasePlayer"
_base_player.bus = "game_sfx"
_base_player.stream = group.base_sound
2025-07-03 09:49:00 +00:00
_refresh_base_player_db()
2025-06-25 17:53:16 +00:00
# 循环播放
if vibe_group.base_sound.get_length() > 0:
_base_player.finished.connect(_base_player.play)
add_child(_base_player)
_embellishment_players.resize(group.embellishments.size())
_embellishment_timers.resize(group.embellishments.size())
# 初始化点缀音播放器池
for i in range(group.embellishments.size()):
if group.embellishments[i] == null:
continue
var player = AudioStreamPlayer.new()
player.name = "EPlayer" + str(i)
player.bus = "game_sfx"
player.stream = group.embellishments[i].sound
add_child(player)
_embellishment_players.append(player)
var timer = Timer.new()
timer.one_shot = true
timer.name = "ETimer" + str(i)
timer.autostart = false
add_child(timer)
_embellishment_timers.append(timer)
timer.timeout.connect(_on_embellishment_timer_timeout.bind(i))
func _on_embellishment_timer_timeout(id: int):
var embellishment = vibe_group.embellishments[id] as Embellishment
if not embellishment:
return
var player = _embellishment_players[id] as AudioStreamPlayer
var timer = _embellishment_timers[id] as Timer
# 增加随机性
timer.wait_time = randf_range(embellishment.min_interval, embellishment.max_interval)
timer.start()
2025-07-03 09:49:00 +00:00
player.volume_db = _base_db + (vibe_group.group_db + embellishment.db) * randf_range(0.8, 1.2)
2025-06-25 17:53:16 +00:00
player.pitch_scale = randf_range(0.8, 1.2)
player.play()
2025-07-03 09:49:00 +00:00
func _refresh_base_player_db() -> void:
_base_player.volume_db = _base_db + vibe_group.group_db + vibe_group.base_sound_db
func _refresh_embellishment_player_db(id: int) -> void:
if _embellishment_players[id] == null:
2025-06-25 17:53:16 +00:00
return
2025-07-03 09:49:00 +00:00
_embellishment_players[id].volume_db = (
_base_db + vibe_group.group_db + vibe_group.embellishments[id].db
)
func set_volume_linear(volume: float):
_base_db = linear_to_db(volume)
for i in range(vibe_group.embellishments.size()):
_refresh_embellishment_player_db(i)
_refresh_base_player_db()
2025-06-25 17:53:16 +00:00
func play():
_base_player.play()
# 设置并启动所有点缀音的计时器
for i in range(vibe_group.embellishments.size()):
var embellishment = vibe_group.embellishments[i]
if not is_instance_valid(embellishment) or not is_instance_valid(embellishment.sound):
continue
var timer = _embellishment_timers[i]
# 如果 loop则 min_interval 与 max_interval 无效
if embellishment.loop:
var player = _embellishment_players[i]
2025-07-03 09:49:00 +00:00
_refresh_embellishment_player_db(i)
2025-06-25 17:53:16 +00:00
if player.stream:
player.play()
player.finished.connect(player.play)
else:
# 首次启动计时器
var random_wait_time = randf_range(
embellishment.min_interval, embellishment.max_interval
)
timer.start(random_wait_time)
func stop_and_free():
if not is_queued_for_deletion():
queue_free()