round2: 看门狗礼仪F1(不重播/单句升级/idle-skip) + 分档归因F2 + 交接count-in/answer F3 + 教学看表现F4-F5 + 警报去叠F6 + 回绕F7 + 开场瘦身F8 + 10句新语音 + 测试全绿(6playtest零改动+guide52断言+资产终检)
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
/**
|
||||
* 《音序回响》新手会话剧本:教学六音一步一步学(中间故意做错一次听纠错)、
|
||||
* 第 1 轮答对、第 2 轮中途忘序列僵住 11 秒(触发向导「双击可重听」提示)、
|
||||
* 第 3 轮故意答错第一下(消耗机会自动重播),然后答对完成第 3 轮收工。
|
||||
* 收尾听完机会经济句(免费重听两次、用完扣机会);第 1 轮直接答对;第 2 轮开局
|
||||
* 忘序列僵住 10 秒,听到向导「双击可以重新听」提示后 5 秒内照做——用掉一次免费
|
||||
* 重听(round2:25s 升级已不再自动重播序列,坐着等答案重念的路子废了);第 3 轮
|
||||
* 凭记忆答对,在**整轮边界**收工(round2 剧本修正:不在轮中退出——round1 转写
|
||||
* 「第 4 轮报数后再没人说话」与「干晾 85 秒」都是剧本失真,不是游戏失真)。
|
||||
*/
|
||||
export function describe(game) {
|
||||
const GN = { up: '上滑', down: '下滑', left: '左滑', right: '右滑', tap: '单击', doubletap: '双击' };
|
||||
@@ -14,7 +17,7 @@ export function describe(game) {
|
||||
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 'roundend': return '刚答完一轮,播报中';
|
||||
case 'gameover': return `游戏结束,完成 ${game.round - 1} 轮。单击再来一局,下滑开菜单`;
|
||||
case 'menu': return '菜单里:单击切选项,双击确认,上滑听规则';
|
||||
default: return '开场,稍等一下';
|
||||
@@ -35,36 +38,50 @@ export async function session(ctx, mock) {
|
||||
await ctx.waitCond(() => game.phase === 'tutorial' && game.teachAwait);
|
||||
}
|
||||
await ctx.gesture(G[i]); // 照指令做对
|
||||
await ctx.waitIdle();
|
||||
if (i === G.length - 1) {
|
||||
// 收尾链(t7 两句 + 机会经济句)播完直达对局——一到 input 就接手,
|
||||
// 不裸 waitIdle(会把 input 的看门狗窗口整段空烧掉,round1 剧本失真根源)
|
||||
await ctx.waitCond(() => game.phase === 'playback' || game.phase === 'input'
|
||||
|| game.phase === 'gameover');
|
||||
} else {
|
||||
await ctx.waitIdle();
|
||||
}
|
||||
}
|
||||
ctx.status('教学讲完了,机会经济也交代清楚了:免费重听两次,用完要扣机会');
|
||||
|
||||
// 正式对局:打到完成第 3 轮
|
||||
let wrongDone = false;
|
||||
let stallDone = false;
|
||||
while (mock.now < 12 * 60 * 1000 && game.phase !== 'gameover' && game.round < 4) {
|
||||
// 正式对局:完整打完第 3 轮,在轮边界收工
|
||||
let relistenDone = false;
|
||||
while (mock.now < 12 * 60 * 1000 && game.phase !== 'gameover') {
|
||||
if (game.phase === 'input') {
|
||||
// 第 2 轮开局先失忆僵住 11 秒:触发向导「双击可以重新听一遍序列」提示
|
||||
if (game.round === 2 && game.inputIdx === 0 && !stallDone) {
|
||||
stallDone = true;
|
||||
// 第 2 轮先失忆僵住 10 秒:听向导「双击可以重新听一遍序列」,5 秒内照做。
|
||||
//(期望输入恰为双击时先答这一下,下一步再演示重听——双击语境判定)
|
||||
if (game.round === 2 && !relistenDone
|
||||
&& game.inputIdx <= 1 && game.sequence[game.inputIdx] !== 'doubletap') {
|
||||
relistenDone = true;
|
||||
ctx.status('序列有点长,先僵一会儿');
|
||||
ctx.silence(11, '想不起来序列了');
|
||||
await ctx.waitVirtual(11000);
|
||||
ctx.silence(10, '想不起来序列了');
|
||||
await ctx.waitVirtual(10600); // 10s 看门狗:nudge + gd_relisten
|
||||
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 + 自动重播同一序列
|
||||
ctx.note('照提示双击,用掉一次免费重听');
|
||||
await ctx.gesture('doubletap');
|
||||
await ctx.waitCond(() => game.phase === 'playback' || game.phase === 'input');
|
||||
continue;
|
||||
}
|
||||
ctx.status('轮到我复现了');
|
||||
if (game.round === 3 && game.inputIdx === game.sequence.length - 1) {
|
||||
ctx.status('最后一轮最后一个音,打完这轮就收');
|
||||
} else {
|
||||
ctx.status('轮到我复现了');
|
||||
}
|
||||
await ctx.gesture(game.sequence[game.inputIdx]);
|
||||
continue;
|
||||
}
|
||||
await ctx.waitIdle();
|
||||
// 整轮边界收尾:第 3 轮答完(roundend),不等第 4 轮报数
|
||||
if (game.phase === 'roundend' && game.round === 3) break;
|
||||
// announce/playback/roundend:等阶段推进即可,不裸 waitIdle(防吞掉 input 窗口)
|
||||
const ph = game.phase;
|
||||
const r = game.round;
|
||||
await ctx.waitCond(() => game.phase !== ph || game.round !== r);
|
||||
}
|
||||
|
||||
ctx.status(`收工:完成了 ${game.round - 1} 轮`);
|
||||
ctx.status(`收工:完整打完 ${game.round} 轮,在轮与轮的边界停手(免费重听剩 ${game.chances} 次)`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user