Phaser 魔法商店订单系统:顾客队列、配方交付和耐心值评分

讲解魔法商店经营玩法中的顾客队列、订单生成、配方匹配、耐心值、交付动画、评分和调试统计。

为什么这个玩法不能只写成演示

玩家经营一家魔法药剂店。顾客排队进门,有人要治疗药水,有人要火抗护符,还有人只说自己怕冷,需要玩家从库存里判断该交付什么。顾客等待太久会离开,交错物品会降低评分。

订单玩法不是简单倒计时。顾客生成、需求表达、库存匹配、交付判断、耐心值、连击评分和失败补救都要统一。Phaser 负责排队动画和 UI,但订单状态必须可测试。 本文按一个可上线的小系统拆解,重点不是罗列 Phaser API,而是把输入、规则、表现、调试和内容配置的边界说明白。只要这些边界清楚,后续加关卡、加活动、加存档或加移动端适配,都不会反复推倒。

核心架构

flowchart TD
  N1["CustomerSpawner"] --> N2["OrderModel"]
  N2["OrderModel"] --> N3["QueueLayout"]
  N2["OrderModel"] --> N4["PatienceTimer"]
  N5["InventoryMatcher"] --> N6["DeliveryResolver"]
  N4["PatienceTimer"] --> N7["RatingSystem"]
  N6["DeliveryResolver"] --> N7["RatingSystem"]
  N7["RatingSystem"] --> N8["HUD"]

这套结构的关键是让 CustomerSpawner、OrderModel、QueueLayout、InventoryMatcher、PatienceTimer、DeliveryResolver、RatingSystem 各司其职。输入层提交意图,规则层产出确定结果,Phaser 层负责把结果演出来。不要让 Tween 完成回调、Sprite 是否可见或某个音效是否播放成为规则事实。规则事实必须能被序列化、测试和回放。

顾客生成要控制节奏

CustomerSpawner 根据关卡阶段生成顾客类型、订单难度和到达间隔。不要完全随机,否则可能连续出现高难订单导致玩家崩盘。生成器应有压力预算,当前排队人数多时降低新订单频率。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

订单需求可以模糊

有些订单直接写明物品,有些通过描述暗示属性。OrderModel 可以记录 requiredTags,例如 heal、fireResist、coldComfort。InventoryMatcher 根据物品标签判断是否满足。这样谜题和经营能共用一套交付规则。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

队列布局要稳定

顾客排队位置由 QueueLayout 分配,前面的人离开后后排补位。不要让每个顾客自己找位置,否则会互相挤。队列状态改变时,动画队列按顺序移动,规则层已经知道谁在第几位。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

耐心值要受多种因素影响

PatienceTimer 基础下降,稀有顾客可能更没耐心,店铺装饰或音乐可以减缓下降。玩家点击顾客查看订单也可以短暂停顿,但不能无限暂停。耐心条低时给表情、脚步和声音反馈。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

交付判断要具体

交付失败要告诉玩家原因:物品类型错误、属性不足、数量不够、订单已过期。DeliveryResolver 返回错误码,UI 显示简短反馈。不要直接吞掉物品,除非规则明确顾客会收下错误物品并给差评。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

评分服务后续成长

RatingSystem 记录等待时间、交付准确度、连击、稀有订单和顾客满意度。评分可以影响金币、小费和声望。评分细分能让玩家知道自己是慢了,还是配方判断错了。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

调试统计帮助平衡

开发模式显示当前顾客队列、剩余耐心、订单标签、匹配候选和预计收益。订单经营玩法很容易出现某个阶段压力陡增,统计面板能帮助设计师看出是生成频率问题还是库存供应问题。

实现时建议先用调试图形把这部分规则跑通,再接正式美术。比如先画命中范围、路径、候选区域、分数来源或状态机阶段,确认数据没有问题后,再加入粒子、音效、镜头和 UI 动效。这样做看似慢,实际会减少大量返工。

TypeScript 实现骨架

interface Order { id: string; requiredTags: string[]; patienceMs: number; arrivedAt: number }
interface Item { id: string; tags: string[]; count: number }
function matchOrder(order: Order, item: Item) {
  return order.requiredTags.every(tag => item.tags.includes(tag));
}
function patienceRatio(order: Order, now: number) {
  return Phaser.Math.Clamp(1 - (now - order.arrivedAt) / order.patienceMs, 0, 1);
}
function scoreDelivery(order: Order, item: Item, now: number) {
  if (!matchOrder(order, item)) return { ok: false, score: 0, reason: "wrong-item" };
  const patience = patienceRatio(order, now);
  return { ok: true, score: Math.round(60 + patience * 40), reason: "served" };
}

这段代码只展示核心边界。真实项目里还需要配置加载、错误码、事件总线、对象池、存档字段和测试夹具。原则是核心系统不依赖 Scene,Scene 只把玩家输入和系统结果连接到 Phaser 的显示对象。

落地步骤

  1. 第一步,先把 CustomerSpawner 和 OrderModel 写成纯数据模型,准备两三个最小样例。
  2. 第二步,给 QueueLayout 增加调试可视化,确保中间状态能被看见。
  3. 第三步,把 Phaser 动画接到规则结果上,而不是让动画反过来提交规则。
  4. 第四步,补齐失败原因、暂停恢复、重复点击保护和读档恢复。
  5. 第五步,用正常流程、边界流程、错误配置三类夹具做校验。

常见坑

  • 把画面当作状态来源。显示对象可能被对象池回收、被镜头隐藏或被动画临时改值,不能作为规则真相。
  • 只为第一关写逻辑。第一关对象少、节奏慢,很多问题不会暴露;内容扩张后,重复触发和配置错误会一起出现。
  • 失败反馈太笼统。玩家需要知道是条件不满足、资源不足、路径不可达、输入太晚,还是系统正在等待确认。
  • 调试面板缺失。复杂玩法没有中间状态可视化,后期只能靠录屏和猜测定位。

运行时观测

记录顾客离开原因、平均等待时间、错误交付标签和每阶段队列长度。若玩家总在同类订单出错,说明描述文案或标签映射不清楚。 这些指标不一定都要上报到线上,但至少应该在开发版能导出。玩法系统越依赖手感和解释,越需要用数据区分规则问题、表现问题和关卡配置问题。

边界测试与移动端验证

魔法商店订单 在桌面浏览器里跑通,只能说明主流程成立,还不能说明它适合发布。建议为它准备一组专门的边界测试:顾客耐心归零时交付、错误物品是否扣库存、同一订单被双击提交、库存变化后候选匹配刷新、队列满员时新顾客生成。这些测试不用都做成复杂自动化,至少要有可重复的调试入口,让开发、策划和 QA 能在同一状态下观察同一个问题。每次测试都要记录 orderId、requiredTags、patienceRatio 和交付结果,否则失败只会变成“刚才好像不对”。如果玩法会出现在移动端,还要额外检查触控误差、浏览器切后台、低电量降频、横竖屏切换和音频恢复。很多 Phaser 小游戏不是输在核心规则,而是输在这些边界恢复上。

移动端验证还要关注触摸反馈和文字密度。按钮按下后要有立即响应,即使规则结果需要等待;长文本提示要能在窄屏换行;关键数值不能只靠颜色表达。若系统在低端机关闭粒子、阴影或轨迹后仍能保持同样的规则结果,就说明表现层和规则层边界清楚。发布前把这些用例整理成清单,后续每次改配置、换美术或加活动,都可以快速回归。

发布前检查

发布前至少确认四件事:第一,所有配置引用的 id 都存在;第二,核心状态能存档并恢复;第三,快速输入和跳过动画不会重复结算;第四,低端机可以关闭高成本表现但不改变规则。若系统涉及奖励、货币或排行榜,还要确认事件 id 幂等,避免重复发放或重复扣除。

订单文案和规则一致

魔法商店的趣味来自理解顾客需求,但文案不能和标签脱节。顾客说“我今晚要去雪山”,规则上就应该对应 coldResist 或 warm 标签;顾客说“伤口还在流血”,就不能只接受普通恢复药水而拒绝止血药。建议给每条订单文案绑定 requiredTags,并在内容审核中自动列出可匹配物品。内容团队新增物品后,也要能反查它能满足哪些订单,避免某个道具看起来有用却永远不会被系统接受。

高峰期的手感

经营玩法最容易在高峰期变得混乱。顾客队列、制作台、库存格和交付按钮都在争夺注意力。可以在高峰期降低新顾客生成方差,让压力逐渐上升;也可以让同类订单在视觉上成组,减少玩家搜索成本。失败时优先保护玩家理解,不要同时弹出多个差评提示。

订单系统还要照顾颜色和图标识别。不同药水不能只靠颜色区分,最好同时有瓶形、标签或图案。顾客需求也不要只用小图标表达,鼠标或长按时应能看到文字说明。这样内容复杂后仍然可读。

验收标准

这个系统的第一版不需要覆盖所有商业化变化,但至少要能回答三类问题:玩家为什么成功,玩家为什么失败,内容配置为什么非法。验收时可以让一名没有参与开发的人按测试清单操作,如果他能从画面反馈和调试面板里解释当前状态,就说明系统边界基本成立。若每次都需要开发者口头说明,说明 UI、日志或规则命名还不够清楚。

结语

魔法商店订单系统:顾客队列、配方交付和耐心值评分 的价值在于可解释。Phaser 可以把反馈做得很快,但真正决定项目能不能持续扩展的,是规则层是否稳定、表现层是否服从结果、调试层是否能讲清楚每一次失败。把这些边界立住,玩法才能从一个好看的 Demo 变成可维护的系统。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页