guide层v1: 全局向导交互层落地(状态签名earcon/turn cue/静默看门狗/纠错) + 6游戏接线 + 8句向导语音 + 测试全绿

- engine/guide.js 运行时合成8个签名earcon(方法论L2硬参数),off档零定时器,插播queue不顶对白
- settings: guide三档(full/standard/off默认full) + 语速2.2视障档;audio: isVoicePlaying()/setRateBoostEnabled() 清两个已知问题
- 6游戏按schemes§2接线: storyline看门狗+无效手势纠错、simon免扣重听看门狗、escape turn cue+提前卡关提示、rhythm gd_answer/gd_miss+结算看门狗+快进豁免、space首撞指令提示+结算看门狗、rpg格挡纠错+60s催促+状态签名
- 大厅设置面板+向导文档(14-guide-layer.md)+00-global-ux §6;R5台词表补4条一致性
- 试玩转写含向导事件;6 playtest(guide=off断言零改动)+guide.test(34断言)+资产终检全绿
This commit is contained in:
SoundGame Dev
2026-08-30 22:46:05 +08:00
parent 7eb9e7f025
commit 79dffac01e
69 changed files with 2466 additions and 144 deletions
+26
View File
@@ -66,6 +66,13 @@ const HAPTIC_NAME = {
};
const hapticName = (p) => HAPTIC_NAME[JSON.stringify(p)] || `自定义震型 ${JSON.stringify(p)}`;
// 向导层事件(engine/guide.js setEventHook)→ 玩家可感知的 earcon / 插播语音
const GUIDE_LABEL = {
menu: '系统界面', explore: '探索/安全', battle: '战斗/对抗', choice: '抉择/等待输入',
settle: '结算', danger: '危险', turn: '轮到你', nudge: '看门狗轻提醒',
error: '出错了', watchdog: '看门狗升级',
};
// ---------------------------------------------------------------- 装载引擎与游戏
const { WebAudioEngine } = await import('../engine/audio.js');
@@ -85,6 +92,8 @@ function capture(audio) {
lastBgm = id;
pending.push(`${fmtT()} ♫ BGM 切换 → ${id}${opts?.fadeMs ? `(淡入 ${opts.fadeMs}ms)` : ''}`);
}
} else if (isVoice && id.startsWith('voice/gd_')) {
// 向导语音经事件钩子渲染(▶ 向导语音),此处不重复记行
} else if (isVoice) {
pending.push(t
? `${fmtT()} ▶ 语音:「${t}」`
@@ -96,6 +105,22 @@ function capture(audio) {
};
}
/** 向导实例接入事件流(每个 earcon/插播语音都转写成玩家可感知的一行)。 */
function captureGuide(game) {
if (!game.guide) return;
game.guide.setEventHook((evt) => {
if (evt.voiceId) {
const t = textOf(`voice/${evt.voiceId}`);
pending.push(t
? `${fmtT()} ▶ 向导语音:「${t}」`
: `${fmtT()} ▶ 向导语音 ${evt.voiceId}(无台词表文本)`);
} else {
const label = GUIDE_LABEL[evt.name] || '';
pending.push(`${fmtT()} ♪ 向导音:${evt.name}${label ? `(${label})` : ''}`);
}
});
}
function drain() {
for (const m of mock.vibrateLog.splice(0)) {
pending.push(`${fmtT()} 〰 震动:${hapticName(m.pattern)}`);
@@ -166,6 +191,7 @@ async function run() {
const audio = new WebAudioEngine('audio/');
const game = new GameClass(audio, {});
capture(audio);
captureGuide(game); // 向导层事件 → 转写行(♪ 向导音 / ▶ 向导语音)
await audio.unlock();
lines.push(`${fmtT()} (玩家点开游戏,轻触屏幕开始)`);
game.start();