为什么这个玩法不能只写成演示
玩家在夜间博物馆寻找十件失窃文物线索:展柜角落的裂纹、画框背后的编号、地毯下的钥匙。画面是静态场景,但每个可点击热点、缩放区域和提示都要准确,否则玩家会觉得自己是在和像素作战。
找物玩法的难点不是把物品藏起来,而是让隐藏公平。玩家点到正确位置必须被系统识别,点错要有节制反馈,提示不能破坏谜题,也不能让玩家卡死。Phaser 的输入系统足够灵活,但热点和提示逻辑要独立于图片。 本文按一个可上线的小系统拆解,重点不是罗列 Phaser API,而是把输入、规则、表现、调试和内容配置的边界说明白。只要这些边界清楚,后续加关卡、加活动、加存档或加移动端适配,都不会反复推倒。
核心架构
flowchart TD
N1["SceneImage"] --> N2["HotspotMap"]
N2["HotspotMap"] --> N3["MissClickGuard"]
N2["HotspotMap"] --> N4["HintResolver"]
N5["ZoomLens"] --> N2["HotspotMap"]
N4["HintResolver"] --> N6["ProgressStore"]
N6["ProgressStore"] --> N7["HUD"]
N8["AccessibilityLayer"] --> N5["ZoomLens"]
这套结构的关键是让 SceneImage、HotspotMap、ZoomLens、MissClickGuard、HintResolver、ProgressStore、AccessibilityLayer 各司其职。输入层提交意图,规则层产出确定结果,Phaser 层负责把结果演出来。不要让 Tween 完成回调、Sprite 是否可见或某个音效是否播放成为规则事实。规则事实必须能被序列化、测试和回放。
热点用数据描述
每个热点应有 id、形状、可见条件、命中范围、提示文本、完成状态和奖励。形状可以是矩形、多边形或圆,不要只用透明 PNG 判断命中。热点数据独立后,同一张博物馆背景可以支持普通模式、限时模式和剧情模式。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
缩放区域要和热点同步
找物游戏常有放大镜或双指缩放。缩放后,屏幕坐标到场景坐标的转换必须统一,否则玩家放大后点中物体却被判误点。ZoomLens 负责坐标转换,HotspotMap 只接收场景坐标。这个边界能避免绝大多数缩放点击错位。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
误点惩罚要克制
误点可以扣时间、震动或短暂锁输入,但不要太频繁。MissClickGuard 应有节流窗口,连续误点只触发一次反馈。对移动端还要过滤拖拽结束时的轻触,避免玩家平移画面被误判点击。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
提示系统分层
第一层提示可以高亮大致区域,第二层缩小范围,第三层直接指出物品。HintResolver 根据剩余目标、玩家停留时间和提示资源选择合适层级。提示消耗要记录,不能因为切场景或刷新页面重置。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
进度保存要细
ProgressStore 保存已找到热点、已用提示、当前缩放状态、剧情变量和限时剩余。找物关卡常被玩家中途离开,读档后不能让已找到物品重新出现,也不能让提示资源恢复。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
无障碍不是降低难度
小物体、低对比度和色彩差异会影响可读性。可以提供轮廓辅助、放大倍率上限提高、减少误点惩罚等设置。辅助不必直接显示答案,但要让玩家能辨认目标。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
调试工具要给内容团队用
开发模式可以显示所有热点轮廓、命中次数、误点热力图和提示触发历史。内容团队能看到哪个目标长期找不到,哪个热点命中范围太窄,然后调整数据而不是找程序改代码。
实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。
TypeScript 实现骨架
type HotspotShape = { kind: "rect"; x: number; y: number; w: number; h: number } | { kind: "circle"; x: number; y: number; r: number };
interface Hotspot { id: string; shape: HotspotShape; found: boolean; hint: string }
function hit(shape: HotspotShape, x: number, y: number) {
if (shape.kind === "rect") return x >= shape.x && x <= shape.x + shape.w && y >= shape.y && y <= shape.y + shape.h;
return Phaser.Math.Distance.Between(x, y, shape.x, shape.y) <= shape.r;
}
function findHotspot(hotspots: Hotspot[], x: number, y: number) {
return hotspots.find(h => !h.found && hit(h.shape, x, y));
}
class MissClickGuard {
private last = 0;
accept(now: number) { const ok = now - this.last > 550; if (ok) this.last = now; return ok; }
}
这段代码只展示核心边界。真实项目里还需要配置加载、错误码、事件总线、对象池、存档字段和测试夹具。原则是核心系统不依赖 Scene,Scene 只把玩家输入和系统结果连接到 Phaser 的显示对象。
落地步骤
- 第一步,先把 SceneImage 和 HotspotMap 写成纯数据模型,准备两三个最小样例。
- 第二步,给 ZoomLens 增加调试可视化,确保中间状态能被看见。
- 第三步,把 Phaser 动画接到规则结果上,而不是让动画反过来提交规则。
- 第四步,补齐失败原因、暂停恢复、重复点击保护和读档恢复。
- 第五步,用正常流程、边界流程、错误配置三类夹具做校验。
常见坑
- 把画面当作状态来源。显示对象可能被对象池回收、被镜头隐藏或被动画临时改值,不能作为规则真相。
- 只为第一关写逻辑。第一关对象少、节奏慢,很多问题不会暴露;内容扩张后,重复触发和配置错误会一起出现。
- 失败反馈太笼统。玩家需要知道是条件不满足、资源不足、路径不可达、输入太晚,还是系统正在等待确认。
- 调试面板缺失。复杂玩法没有中间状态可视化,后期只能靠录屏和猜测定位。
运行时观测
建议记录每个热点的平均发现时间、误点周边坐标、提示使用层级和放大倍率。若某个目标大量依赖第三层提示,说明隐藏过深;若误点集中在目标边缘,说明命中范围或美术轮廓不一致。 这些指标不一定都要上报到线上,但至少应该在开发版能导出。玩法系统越依赖手感和解释,越需要用数据区分规则问题、表现问题和关卡配置问题。
边界测试与移动端验证
找物场景 在桌面浏览器里跑通,只能说明主流程成立,还不能说明它适合发布。建议为它准备一组专门的边界测试:玩家双指缩放后立即点击、拖动画面结束时误触热点、提示资源在读档后恢复、两个热点区域重叠、低对比度目标在夜间模式下不可读。这些测试不用都做成复杂自动化,至少要有可重复的调试入口,让开发、策划和 QA 能在同一状态下观察同一个问题。每次测试都要记录 场景坐标、热点 id、提示层级和误点节流,否则失败只会变成“刚才好像不对”。如果玩法会出现在移动端,还要额外检查触控误差、浏览器切后台、低电量降频、横竖屏切换和音频恢复。很多 Phaser 小游戏不是输在核心规则,而是输在这些边界恢复上。
移动端验证还要关注触摸反馈和文字密度。按钮按下后要有立即响应,即使规则结果需要等待;长文本提示要能在窄屏换行;关键数值不能只靠颜色表达。若系统在低端机关闭粒子、阴影或轨迹后仍能保持同样的规则结果,就说明表现层和规则层边界清楚。发布前把这些用例整理成清单,后续每次改配置、换美术或加活动,都可以快速回归。
发布前检查
发布前至少确认四件事:第一,所有配置引用的 id 都存在;第二,核心状态能存档并恢复;第三,快速输入和跳过动画不会重复结算;第四,低端机可以关闭高成本表现但不改变规则。若系统涉及奖励、货币或排行榜,还要确认事件 id 幂等,避免重复发放或重复扣除。
内容团队的热点审核
找物关卡上线前应做热点审核,而不是只让策划试玩一遍。审核脚本可以导出所有热点的面积、屏幕占比、中心点、是否在缩放区域内、是否有提示文本、是否和其他热点重叠。面积过小的热点要标记为高风险,重叠热点要人工确认优先级。很多找物 bug 不是程序错误,而是内容上把两个可点区域摆得太近,玩家点中 A 却以为自己在点 B。对移动端还要按实际物理尺寸评估,桌面上 20 像素能点,手机上可能已经过小。
提示消耗的节奏
提示系统不应只考虑单个目标,还要考虑整关节奏。如果玩家开局就连续使用三次提示,说明场景第一眼缺少入口;如果玩家最后一个目标反复卡住,说明该目标可能过度隐藏。可以给提示系统加冷却和递进文案:第一次提示给区域,第二次给视觉描述,第三次才圈出位置。这样既保留谜题尊严,也避免玩家因为一个像素点放弃整关。
找物关卡还要准备截图回归。每次热点或背景图调整后,导出带热点轮廓的开发截图,和上一版对比。这样能发现背景被裁切、热点偏移、缩放锚点变化等肉眼难以在试玩中稳定复现的问题。若场景有多语言文本贴片,也要确认文本不会挡住关键目标。
验收标准
这个系统的第一版不需要覆盖所有商业化变化,但至少要能回答三类问题:玩家为什么成功,玩家为什么失败,内容配置为什么非法。验收时可以让一名没有参与开发的人按测试清单操作,如果他能从画面反馈和调试面板里解释当前状态,就说明系统边界基本成立。若每次都需要开发者口头说明,说明 UI、日志或规则命名还不够清楚。
结语
找物解谜场景:热点、缩放、误点惩罚和提示系统 的价值在于可解释。Phaser 可以把反馈做得很快,但真正决定项目能不能持续扩展的,是规则层是否稳定、表现层是否服从结果、调试层是否能讲清楚每一次失败。把这些边界立住,玩法才能从一个好看的 Demo 变成可维护的系统。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。