Phaser 无人机配送:航线规划、电量、禁飞区和动态改道

拆解无人机配送玩法中的路径规划、电量预算、禁飞区、风场、订单优先级、动态改道和调试可视化。

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

玩家管理一队城市配送无人机。订单从餐厅发往公寓楼,地图上有临时禁飞区、强风街区和充电站。无人机电量有限,飞错路线可能半路返航,延误订单会扣评分。

无人机配送的乐趣来自规划和应变。它不是简单让 Sprite 沿直线移动,而是要处理航点、禁飞区、电量、天气、订单优先级和临时改道。核心规划应独立于 Phaser 表现。 本文按一个可上线的小系统拆解,重点不是罗列 Phaser API,而是把输入、规则、表现、调试和内容配置的边界说明白。只要这些边界清楚,后续加关卡、加活动、加存档或加移动端适配,都不会反复推倒。

核心架构

flowchart TD
  N1["OrderQueue"] --> N2["RoutePlanner"]
  N3["AirGraph"] --> N2["RoutePlanner"]
  N4["NoFlyZone"] --> N2["RoutePlanner"]
  N5["BatteryModel"] --> N2["RoutePlanner"]
  N2["RoutePlanner"] --> N6["DroneView"]
  N7["RerouteEvent"] --> N2["RoutePlanner"]
  N6["DroneView"] --> N8["HUD"]

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

空域建成图

AirGraph 用节点和边描述可飞航线,边上记录距离、风险、风阻和是否经过充电站。禁飞区可以临时禁用某些边。这样路线规划不必每次做复杂几何避障,关卡设计也更可控。

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

电量是硬约束

BatteryModel 根据距离、载重、风阻和机型计算消耗。RoutePlanner 必须先判断能否完成路线,不能等无人机飞到半路才发现没电。若必须中途充电,路线应自动加入充电站,并在 UI 上显示额外时间。

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

订单队列有优先级

订单不只是先来先送。易腐、VIP、近超时和顺路订单可以有不同权重。OrderQueue 输出候选任务,RoutePlanner 估算收益和风险。玩家可以手动覆盖,但系统要给出延误提示。

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

动态改道要有原因

禁飞区出现、风场变化、电量不足或目标关闭都可能触发 RerouteEvent。改道时不要瞬间改变无人机方向,先显示新路径和原因,再让无人机转向。若玩家允许手动确认,高压模式可以暂停等待选择。

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

碰撞可以抽象处理

大多数管理玩法不需要真实飞行碰撞。可以把空域边当成占用资源,多个无人机进入同一窄边时增加风险或排队。这样性能更好,也更容易解释延误。

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

地图反馈要分层

普通路线、危险路线、禁飞区、充电站和订单目的地应有不同视觉层。不要让所有线都亮成一个颜色。玩家需要一眼知道哪条路线安全、哪条路线快、哪条路线风险高。

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

调试要显示规划成本

开发模式显示每条候选路线的距离、电量消耗、预计时间、风险和收益。路线规划如果只输出最终路径,调参会很痛苦;看到被淘汰的候选,才能理解系统为什么选择绕路。

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

TypeScript 实现骨架

interface AirEdge { from: string; to: string; distance: number; wind: number; blocked?: boolean }
interface Drone { id: string; battery: number; capacity: number }
function edgeCost(edge: AirEdge, payload: number) { return edge.distance * (1 + edge.wind * 0.3 + payload * 0.05); }
function routeCost(route: AirEdge[], payload: number) {
  return route.reduce((sum, edge) => sum + edgeCost(edge, payload), 0);
}
function canFly(drone: Drone, route: AirEdge[], payload: number) {
  return route.every(e => !e.blocked) && routeCost(route, payload) <= drone.battery;
}
function delayRisk(minutesLeft: number, eta: number) { return eta > minutesLeft ? "late" : eta > minutesLeft * 0.8 ? "tight" : "safe"; }

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

落地步骤

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

常见坑

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

运行时观测

记录每次路线选择的候选成本、电量余量、改道原因和订单延误。若系统频繁选择玩家不理解的绕路,说明成本展示或规划权重需要调整。 这些指标不一定都要上报到线上,但至少应该在开发版能导出。玩法系统越依赖手感和解释,越需要用数据区分规则问题、表现问题和关卡配置问题。

边界测试与移动端验证

无人机配送 在桌面浏览器里跑通,只能说明主流程成立,还不能说明它适合发布。建议为它准备一组专门的边界测试:航线中途出现禁飞区、无人机低电量返航、充电站排队、订单临近超时、玩家手动覆盖系统路线。这些测试不用都做成复杂自动化,至少要有可重复的调试入口,让开发、策划和 QA 能在同一状态下观察同一个问题。每次测试都要记录 routeId、电量余量、禁飞区版本和改道原因,否则失败只会变成“刚才好像不对”。如果玩法会出现在移动端,还要额外检查触控误差、浏览器切后台、低电量降频、横竖屏切换和音频恢复。很多 Phaser 小游戏不是输在核心规则,而是输在这些边界恢复上。

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

发布前检查

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

地图事件和玩家决策

无人机配送的动态事件要给玩家选择,而不是只制造麻烦。禁飞区出现时,可以提供绕行、等待、转交其他无人机三种方案,每种方案展示预计延误和电量影响。强风区域也可以临时提高风险,但如果玩家愿意冒险,系统应允许。这样事件成为经营决策,而不是随机惩罚。Phaser 表现层可以用路径颜色、警告图标和倒计时表达选择窗口。

充电站的容量

充电站如果无限使用,电量规划会变得简单;如果有容量,就会出现排队和调度。BatteryModel 可以和 ChargingStationState 结合,记录充电口数量、充电速度和等待队列。路线规划时不仅要看能否到达充电站,还要估算等待时间。这个细节能让配送网络更有经营味道。

配送路线还要考虑玩家撤销。玩家手动改道后,如果发现电量不够,应能回到系统推荐路线,或选择最近安全点降落。撤销不是简单回滚坐标,而是恢复路线、订单锁定和电量预估状态。

验收标准

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

无人机验收还要任选一条订单路线,依次关闭边、降低电量、加入强风和占满充电站。系统每次都应给出不同改道原因,而不是只画一条新线。

调试面板还应保留被淘汰路线,方便比较成本。

如果玩家手动选择高风险路线,系统也要记录这是玩家决策,而不是规划器失误。

这会减少误判。

结语

无人机配送:航线规划、电量、禁飞区和动态改道 的价值在于可解释。Phaser 可以把反馈做得很快,但真正决定项目能不能持续扩展的,是规则层是否稳定、表现层是否服从结果、调试层是否能讲清楚每一次失败。把这些边界立住,玩法才能从一个好看的 Demo 变成可维护的系统。

继续阅读

探索更多技术文章

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

全部文章 返回首页