DESIGN DOC · 09 技术与多端 · #s13
随时暂停 · 手机上的"地铁友好"设计
Cocos Creator 3.8 · 微信小游戏 · Steam — 《热血骑手·物语》设计案按节成页:一个 section 一个文件,左侧目录全站可跳。
13
随时暂停 · 手机上的"地铁友好"设计
退出即存、回来即续,BGM 不能停
微信小游戏的真实使用场景是地铁上、排队时、老板不在的三分钟。玩家会被随时打断,所以"任何一帧都能安全暂停"不是设置项,而是底层架构约束。这条会反过来影响战斗系统怎么写 —— 必须在 M0 就定下来。
13.1 四层暂停模型(已定实现方案)
| 层级 | 触发方式 | 冻结什么 / 保留什么 | 恢复耗时 |
|---|---|---|---|
| L0 硬暂停 (切后台) | 微信 onHide / iOS 来电 / 安卓 Home 键 / 窗口失焦 | 整个逻辑循环停止、自动写存档;BGM 由系统接管(小游戏 onHide 时我们主动 pause,回前台 resume 并从原位置继续)。 | < 300ms 无缝续玩 |
| L1 软暂停 (游戏内菜单) | ESC / 手柄 Start / 屏幕右上"≡" | 冻结角色、敌人、计时器、掉落物;保留背景视差微动、灯光呼吸、BGM 降到 60% 音量 + 低通滤波(不停,避免"游戏死了"的错觉)。 | 瞬时 |
| L2 对话跳过 | 点击文字区 / A 键 / "跳过全部" | 打字机立即补全本句或整段;剧情状态机照常推进,不会漏 flag。 | 瞬时 |
| L3 慢想模式 (辅助选项) | 设置里"手残友好"开关 | 受击前 0.4 秒自动子弹时间(0.35×)、狗扑咬前摇高亮描边、QTE 判定放宽。给被地铁打断回来的玩家一个台阶。 | 常驻 |
13.1B 双端同步首发下的暂停差异(微信是主战场)
| 场景 | 微信小游戏 | Steam 桌面 | 为什么必须这样分开 |
|---|---|---|---|
| 切后台 / 来电 | onHide → L0 硬暂停,同步落盘 + 停 AudioContext;onShow 显示"继续跑单"大按钮,点一下才恢复 | 窗口失焦 → L1 软暂停(不弹界面,只降速与静音),重新聚焦立刻继续 | 手机上玩家回来时往往已经过了十分钟,需要明确的"接着来"入口;PC 上捡个水杯不该看到菜单。 |
| 锁屏 / 静音键 | iOS 锁屏后 InnerAudioContext 可能无法自动恢复 → onShow 显式重建实例并 seek 到记录位置;实时合成音乐天然免疫这个问题(§14.3) | 无此问题;提供"暂停即静音"可选开关 | 这是小游戏最常被投诉的体验事故,必须在 M1 验收而不是上线后修。 |
| 战斗中的暂停 | 禁止在 S2 双线程 / 门禁倒计时中关闭页面就当作没发生:倒计时按真实时间推进并存档,回来从检查点继续(不是回到关底) | 同规则,但允许 F5 快速重开本段 | 潜行关的时间限制如果靠"关掉游戏"就能冻结,玩法直接失效。 |
| 体力制章节票 | 暂停不影响体力结算;体力只在"开始新的一天"时扣,中途退出不重复扣 | 不适用(全开) | 避免"我退出是为了省体力结果被扣两次"这种最容易招差评的实现失误。 |
| 分享时机 | L1 菜单里放"喊人来撑一场"按钮 —— 卡 BOSS 时的求助是最强裂变点,但只在失败页和菜单出现,绝不在胜利时弹 | 不做分享按钮,只做截图导出(Steam 自带分享) | 克制原则:骚扰式分享会被微信处罚,也会在情绪好的时候惹人烦。 |
13.2 为了"随便暂停"必须遵守的 6 条编码纪律
① 逻辑与渲染彻底分离固定步长 60Hz 逻辑 tick + 插值渲染。暂停只是不再调用 tick,不存在"半帧状态"残留。
② 禁止 wall-clock 依赖所有计时用累加的
dt,不用 Date.now()。切后台 3 小时回来不会瞬间超时扣钱。③ 输入缓冲可清空暂停时丢弃未消费的输入队列,防止回来立刻放出一个误触的必杀。
④ 随机数走存档种子掉落/舔狗刷新用
save.rngSeed 派生,SL 大法可用且公平。⑤ 单帧原子提交每帧结束才允许写关键状态(HP/现金/好感),保证任意时刻 kill 进程都是合法存档点。
⑥ BOSS 战中途存档BOSS 分 2~3 阶段,每阶段结束自动存一次。CH.09 四场连打不能要求玩家一口气打完 —— 那在小游戏上是劝退。
13.3 存档点设计(与暂停联动)
自动
进安全区 / 换章 / BOSS 阶段结束
骑手站门口、面馆、花店、医院走廊都是"安全屋"(致敬热血物语的回血点)。进场即存,玩家无需思考。
强制
onHide 立刻落盘
切后台回调里同步写本地存储(setStorageSync),异步上报云端节流 5 秒一次。宁可多写也不要丢。
反挫败
掉钱不掉进度
失败只回到本场战斗起点,扣少量现金;但送单途中倒地一定扣这一单的奖金(§7.6B)——因为"钱在流血、进度没在流血",玩家重来的意愿才不会被摧毁。连续败 3 次自动降低一档难度(可在设置里关掉,照顾 Steam 硬核玩家)。
13.4 音频系统规范(含暂停行为)
| 通道 | 内容 | 暂停 / 切后台时的行为 | 并发上限 |
|---|---|---|---|
| BGM | 每章 1~2 首循环曲 | L1 软暂停:音量 → 60%、低通 1200Hz,继续播放;L0 硬暂停:audio.pause() 并记录 currentTime,回前台 play() 续播。 | 1 路 |
| INTENSITY | 打斗叠层(鼓/贝斯) | 进入战斗淡入 400ms 叠加,脱战淡出。与 BGM 同相位对齐小节,靠预先烘好的分段轨实现,不做实时混音。 | 1 路 |
| AMBIENT | 街道人声、电动车、狗叫、雨 | 暂停时保留但降到 40%,让菜单界面仍有"活着"的底噪。 | 2 路 |
| SFX | 打击/受击/KO/拾取/UI | 暂停时全部立即停止并清空队列(避免回来一堆爆音)。 | 8 路池化 |
| VOICE | 无配音,仅 beep 打字音 | 随对话推进;跳过时静默补字。 | 1 路 |
为什么 BGM 在暂停时不该静音:静音会让玩家误判"游戏卡死 / 掉线",小游戏中途退出重进的流失极高。保留一段低通处理的音乐,是成本最低的"我还在"信号。Steam 版则提供"暂停即静音"选项,尊重主机玩家的听感习惯。
⚠️ 微信限制提前处理:iOS 上
InnerAudioContext 在锁屏/切后台后可能无法自动恢复,需要在 onShow 里显式重建实例并 seek 到记录的 currentTime;另外首次 BGM 必须由用户手势触发(点击"开始跑单"按钮)才能通过 autoplay 策略。