90 lines
2.7 KiB
GDScript
90 lines
2.7 KiB
GDScript
@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]
|
||
|
||
|
||
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
|
||
_base_player.volume_db = group.group_db + group.base_sound_db
|
||
# 循环播放
|
||
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()
|
||
player.volume_db = (vibe_group.group_db + embellishment.db) * randf_range(0.8, 1.2)
|
||
player.pitch_scale = randf_range(0.8, 1.2)
|
||
player.play()
|
||
|
||
|
||
func _ready():
|
||
if Engine.is_editor_hint():
|
||
return
|
||
|
||
|
||
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]
|
||
player.volume_db = vibe_group.group_db + embellishment.db
|
||
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()
|