40250 classic: increment 50 (W4) — map BGM selection + background volume save/restore
§9.1 map BGM selection (bgm_director.gd): - server bgm_changed(name, volume): non-empty name plays it as field music; empty name falls back to musicInfo.fieldMusic (METIN2THEMA = "M2BG.mp3") - volume < 0 (server unspecified, GC_MAIN_CHARACTER3_BGM) -> default 1/5*0.1 = 0.02; otherwise server volume; volume applied before play_bgm() fade-in (matches game.py:190 SetMusicVolume/SetSoundVolume then FadeInMusic) - connect M2Client.world_reset -> re-run selection on map change - new musicinfo.gd: METIN2THEMA/loginMusic/createMusic/selectMusic/fieldMusic constants + save/load_last_play_field_music -> user://BGM/lastplay.inf §9.2 background/foreground volume save-restore: - audio.gd: save_volume()/restore_volume() (backup fields echo reference m_fBackupMusicVolume / m_fBackupSoundVolume) + set_music_volume() - app_lifecycle.gd: _enter_background() uses save_volume() + mute instead of stop_bgm(); _exit_background() calls restore_volume(); _bgm_name never cleared §9.3 lifecycle ownership: DOC ONLY — design confirmed, deferred to Phase 2 / W0 (AppFlow sole lifecycle owner; M2Client drops NOTIFICATION_* keeps suspend/resume). game_scene.gd / app_flow.gd / m2_client.* left untouched per workflow constraints. Tests: bgm_test.gd (new) PASS; gamescene_test / netplay_test / p9_test green. Docs: CLIENT-GAP.md increment 50 bullet + W4 progress row; CLIENT-GAP-FIX.md §9.1 §9.2 状态/改动/测试/验收, §9.3 deferred note, C.5 batch record. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014yvAPqPivoY7vmBbzgqK4W
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f32064c74a
commit
9732f2799e
+50
-8
@@ -1,8 +1,14 @@
|
||||
# BgmDirector —— 把 M2Client.bgm_changed 信号翻译成 Audio 的 BGM 播放。
|
||||
#
|
||||
# 存在的理由:§9.1 的地图 BGM 消费点,从 net_world.gd 里拆出来,避免 W2(可见性)
|
||||
# 和 W4(音频)同时改 net_world.gd。真正的「地图 → 曲目」解析和音量应用由 W4 在
|
||||
# 这里补全(见 docs/CLIENT-GAP-FIX.md §9.1)。
|
||||
# 和 W4(音频)同时改 net_world.gd。地图 → 曲目解析和音量应用在这里(§9.1)。
|
||||
#
|
||||
# 选曲逻辑对标 game.py:190(GameWindow.Open 内):
|
||||
# snd.SetMusicVolume(...); snd.SetSoundVolume(...) # 先应用音量
|
||||
# name = net.GetFieldMusicFileName()
|
||||
# if name: snd.FadeInMusic("BGM/" + name)
|
||||
# elif musicInfo.fieldMusic: snd.FadeInMusic("BGM/" + musicInfo.fieldMusic)
|
||||
# 默认音量 gs_fieldMusic_volume = 1.0f/5.0f*0.1f = 0.02f(服务器未下发时)。
|
||||
#
|
||||
# 用法:
|
||||
# var bd := preload("res://bgm_director.gd").new()
|
||||
@@ -10,6 +16,11 @@
|
||||
# bd.bind(client, audio)
|
||||
extends Node
|
||||
|
||||
const MusicInfo = preload("res://musicinfo.gd")
|
||||
|
||||
# gs_fieldMusic_volume 默认值(PythonNetworkStreamPhaseLoading.cpp:299)。
|
||||
const DEFAULT_FIELD_MUSIC_VOLUME := 1.0 / 5.0 * 0.1 # = 0.02
|
||||
|
||||
var _client: Node
|
||||
var _audio: Node
|
||||
|
||||
@@ -22,18 +33,49 @@ func bind(client: Node, audio: Node) -> void:
|
||||
_audio = audio
|
||||
if _client and _client.has_signal("bgm_changed"):
|
||||
_client.bgm_changed.connect(_on_bgm_changed)
|
||||
# 换图(§1.3):world_reset 后重跑选曲逻辑。新图的 BGM 包到达前沿用当前曲目。
|
||||
if _client and _client.has_signal("world_reset"):
|
||||
_client.world_reset.connect(_on_world_reset)
|
||||
|
||||
func _on_bgm_changed(name: String, volume: float) -> void:
|
||||
# M2Client 已在 EntityStore 侧做音量保留(BGM3 只带名、BGM4 带名+音量),
|
||||
# 这里拿到的 volume 就是「有效音量」,<0 仅表示从未收到过 BGM4。
|
||||
current_track = name
|
||||
if volume >= 0.0:
|
||||
current_volume = volume
|
||||
if _audio and "master_bgm" in _audio:
|
||||
_audio.master_bgm = clampf(volume, 0.0, 1.0)
|
||||
current_volume = volume
|
||||
_select()
|
||||
|
||||
func _on_world_reset() -> void:
|
||||
_select()
|
||||
|
||||
# game.py:190 的三行选曲 + 先置音量。
|
||||
func _select() -> void:
|
||||
if _audio == null:
|
||||
return
|
||||
if name == "":
|
||||
|
||||
# 1) 选曲:服务端名优先,否则回落 musicInfo.fieldMusic(METIN2THEMA = "M2BG.mp3")。
|
||||
var track := current_track
|
||||
if track == "":
|
||||
track = String(MusicInfo.fieldMusic)
|
||||
|
||||
# 2) 音量:服务端未指定(<0)用默认 0.02,否则用服务端值。
|
||||
var vol := current_volume if current_volume >= 0.0 else DEFAULT_FIELD_MUSIC_VOLUME
|
||||
vol = clampf(vol, 0.0, 1.0)
|
||||
|
||||
# 3) 先应用音量再淡入:Audio.play_bgm() 的淡入目标是 linear_to_db(master_bgm),
|
||||
# 对标 game.py 先 SetMusicVolume/SetSoundVolume 再 FadeInMusic。
|
||||
# 声音(SFX)音量在参考里取自系统设置(systemSetting.GetSoundVolume),
|
||||
# 不随 BGM 包下发,这里不改 master_sfx。
|
||||
if "master_bgm" in _audio:
|
||||
_audio.master_bgm = vol
|
||||
if _audio.has_method("set_music_volume"):
|
||||
_audio.set_music_volume(vol)
|
||||
|
||||
if track == "":
|
||||
if _audio.has_method("stop_bgm"):
|
||||
_audio.stop_bgm()
|
||||
return
|
||||
|
||||
if _audio.has_method("play_bgm"):
|
||||
_audio.play_bgm(name)
|
||||
_audio.play_bgm(track)
|
||||
# musicInfo.SaveLastPlayFieldMusic 语义:记录本次战场曲目。
|
||||
MusicInfo.save_last_play_field_music(track)
|
||||
|
||||
Reference in New Issue
Block a user