- 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断言)+资产终检全绿
71 lines
3.4 KiB
JavaScript
71 lines
3.4 KiB
JavaScript
/**
|
||
* 《音序回响》新手会话剧本:教学六音一步一步学(中间故意做错一次听纠错)、
|
||
* 第 1 轮答对、第 2 轮中途忘序列僵住 11 秒(触发向导「双击可重听」提示)、
|
||
* 第 3 轮故意答错第一下(消耗机会自动重播),然后答对完成第 3 轮收工。
|
||
*/
|
||
export function describe(game) {
|
||
const GN = { up: '上滑', down: '下滑', left: '左滑', right: '右滑', tap: '单击', doubletap: '双击' };
|
||
const GESTURES = ['up', 'down', 'left', 'right', 'tap', 'doubletap'];
|
||
switch (game.phase) {
|
||
case 'tutorial':
|
||
return game.teachAwait
|
||
? `教学:该做「${GN[GESTURES[game.teachIdx]]}」了`
|
||
: '教学旁白在播,先听着';
|
||
case 'announce': return `第 ${game.round} 轮报数呢,听好了`;
|
||
case 'playback': return `第 ${game.round} 轮序列演奏中(${game.sequence.length} 个音),记住顺序,先别动手`;
|
||
case 'input': return `第 ${game.round} 轮轮到你了:已对上 ${game.inputIdx}/${game.sequence.length},照原顺序做手势`;
|
||
case 'roundend': return game.chances < (game.round > 4 ? 2 : 1) ? '答错了,正在重播刚才的序列' : '刚答完,播报中';
|
||
case 'gameover': return `游戏结束,完成 ${game.round - 1} 轮。单击再来一局,下滑开菜单`;
|
||
case 'menu': return '菜单里:单击切选项,双击确认,上滑听规则';
|
||
default: return '开场,稍等一下';
|
||
}
|
||
}
|
||
|
||
export async function session(ctx, mock) {
|
||
const { game } = ctx;
|
||
const G = ['up', 'down', 'left', 'right', 'tap', 'doubletap'];
|
||
|
||
// 教学 T0-T6:教一个练一个
|
||
for (let i = 0; i < G.length; i++) {
|
||
await ctx.waitCond(() => game.phase === 'tutorial' && game.teachAwait);
|
||
ctx.status(`教学第 ${i + 1}/6 个音色`);
|
||
if (i === 2) {
|
||
ctx.note('把「左滑」记混了,先来了个右滑');
|
||
await ctx.gesture('right'); // 听纠错语音(t_wrong_left)
|
||
await ctx.waitCond(() => game.phase === 'tutorial' && game.teachAwait);
|
||
}
|
||
await ctx.gesture(G[i]); // 照指令做对
|
||
await ctx.waitIdle();
|
||
}
|
||
|
||
// 正式对局:打到完成第 3 轮
|
||
let wrongDone = false;
|
||
let stallDone = false;
|
||
while (mock.now < 12 * 60 * 1000 && game.phase !== 'gameover' && game.round < 4) {
|
||
if (game.phase === 'input') {
|
||
// 第 2 轮开局先失忆僵住 11 秒:触发向导「双击可以重新听一遍序列」提示
|
||
if (game.round === 2 && game.inputIdx === 0 && !stallDone) {
|
||
stallDone = true;
|
||
ctx.status('序列有点长,先僵一会儿');
|
||
ctx.silence(11, '想不起来序列了');
|
||
await ctx.waitVirtual(11000);
|
||
ctx.status('听到提示:需要的话,双击可以重新听一遍序列');
|
||
}
|
||
// 第 2 轮第二拍故意答错:触发"用一次机会,再听一遍"(复活重听)
|
||
if (game.round === 2 && game.inputIdx === 1 && !wrongDone) {
|
||
wrongDone = true;
|
||
ctx.note('这一下故意点错,听听游戏怎么说');
|
||
await ctx.gesture(G[(G.indexOf(game.sequence[game.inputIdx]) + 1) % G.length]);
|
||
await ctx.waitIdle(); // retry_use + 自动重播同一序列
|
||
continue;
|
||
}
|
||
ctx.status('轮到我复现了');
|
||
await ctx.gesture(game.sequence[game.inputIdx]);
|
||
continue;
|
||
}
|
||
await ctx.waitIdle();
|
||
}
|
||
|
||
ctx.status(`收工:完成了 ${game.round - 1} 轮`);
|
||
}
|