格子移动与碰撞:从规则到实现
文章基于网格与物理标签,拆解格子移动与碰撞分层机制。通过占用表与可达性模型,详解推箱子位移及阻挡判定逻辑,直接提供从规则定义到代码实现的技术路径,助读者掌握核心物理交互原理。
玩法拆解
- 占用表 occupancy[x,y] → entityId
- 层级:地形/单位/投射物
- 先算意图,再做 resolve
- 支持链式推动(可选)
关键代码
Demo
最小可试玩:网格移动 + 墙体阻挡(用于演示占用/阻挡模型)。
文章
格子移动与碰撞:从规则到实现
一句话本质
表面上是处理实体在网格上的位移;实际上核心机制是将所有移动(含技能)收敛为“意图采集 + 快照结算 + 事件回放”的统一流程;本文重点解释如何通过分层占用表与解析器实现安全、可回滚的碰撞判定。
这篇文章聚焦一个很常见但很容易“越写越乱”的系统:网格移动 + 阻挡 + 推动 + 多层碰撞。
目标是把所有判定收敛到一个统一模型里,让你后续加上:
- 推箱子/推动链(A 推 B 推 C…)
- 位移技能(冲刺/击退/牵引)
- 多层碰撞(地形 / 单位 / 投射物 / 机关)
- 关卡机制(门、开关、冰面、传送)
都不会变成“到处 if-else 补洞”。
---
1. 核心结论:用“占用表 + 解析器”统一规则
不要让每个系统各写各的判定(移动系统写一次、技能系统再写一次、怪物 AI 再写一次)。
推荐的中心结构:
- 占用表(Occupancy):网格上每个格子当前被谁占用(按层)。
- 移动意图(Intent):某个实体希望从 A → B,原因是什么(玩家输入/AI/技能/击退)。
- 解析器(Resolver):把意图在占用表上“结算”为一个可执行的结果(成功 / 被阻挡 / 推动链成功 / 失败回滚)。
> 你要做到的是:所有移动最终都走同一个 Resolver。
---
2. 数据模型:层(Layer)比“类型 if-else”更省命
一个格子可能同时存在:
- 地形(墙、地板、陷阱、传送带)
- 单位(玩家、敌人、箱子)
- 临时物(投射物、范围提示、特效占位)
因此占用表建议按层存:
terrain[x,y] -> terrainIdunit[x,y] -> unitIdprojectile[x,y] -> projectileId(可选,通常投射物更适合连续空间)
这样“能不能走进来”就是按层组合规则,而不是写成“如果是箱子且是冰面且是门…”。
---
3. 移动结算:两阶段(意图 → 结算)比“边走边改”安全
错误做法:玩家按键时直接改坐标,再检查碰撞,发现不行再改回来。 这会导致连锁推动、多人同时移动、以及回放/撤销时非常痛苦。
推荐做法:先构造意图,再统一结算:
- 输入阶段:收集意图
MoveIntent(entityId, from, dir) - 结算阶段:在“快照占用表”上运行 resolver,得到
MoveResult - 应用阶段:把
MoveResult变成一个“可回放”的事件序列(写入事件日志)
---
4. 推动链(Push Chain):递归/迭代都行,但要可回滚
推动链的本质:
- 我想进入格子 B,但 B 被箱子占用
- 如果箱子能被推到 C,则我可以进入 B
- 如果 C 被另一个箱子占用,则继续尝试
- 直到遇到空格(成功)或墙/不可推物(失败)
关键点:
- 一次结算里,不要反复读写真实占用表;在临时结构里模拟。
- 失败时能“整条链一起失败”,不出现半成功导致穿模。
一个实用的实现套路:
tryMove(entity, dir)返回{ ok, moves[] }moves[]是按顺序的位移列表(例如先推最后一个箱子,再推前一个,最后移动玩家)
---
5. 位移技能(冲刺/击退/牵引):把它当“多步移动”
很多人写技能位移时会绕过网格移动系统,直接改坐标,然后再补一堆特殊判定。
更稳的方式:
- 冲刺 = 连续 N 次
MoveIntent(每步都走 resolver) - 击退 = 由受击事件触发的
MoveIntent(方向由攻击者到受击者) - 牵引 = 由技能触发的
MoveIntent(方向相反)
好处:
- 技能不会“穿墙”
- 推动链自然生效
- 你还能统一做“碰到墙停止”“碰到机关触发”等规则
---
6. 常见坑与验收清单(写完就用来对照)
6.1 常见坑
- 顺序依赖:两个单位同时想进入同一格,先处理谁会影响结果。
- 幽灵占用:实体移动后忘记更新占用表,导致后续判定认为格子仍被占。
- 半成功:推动链中途失败但前面的箱子已经被移动了。
- 只在“移动”判定墙:技能位移/击退没有走同一套判定,导致穿墙。
6.2 最小验收(建议写成自动测试)
- [ ] 不能走进墙
- [ ] 推动 1 个箱子成功/失败都正确
- [ ] 推动链 2~3 个箱子成功/失败都正确
- [ ] 冲刺/击退不会穿墙,且与箱子交互正确
- [ ] 事件回放后状态一致(占用表与坐标一致)
---
7. 下一步扩展(建议优先顺序)
- 死局检测/可达性(关卡生成、提示系统会用到)
- 机关层(地形触发:开关、传送带、陷阱)
- 视野/碰撞形状(从网格扩展到“网格 + 子格/半格”)
边界条件
- 需要处理两个或多个实体在同一帧争夺同一格子的顺序依赖问题。
- 需要处理实体移动后未及时更新占用表导致的幽灵占用问题。
- 需要处理推动链中途失败但前置实体已移动导致的半成功状态问题。
- 需要处理技能位移若绕过统一判定逻辑可能产生的穿墙问题。
- 需要处理结算结束后是否立即应用坐标变更,以确保状态与事件日志一致。
设计取舍
- 收益:所有移动系统(移动、技能、AI)共用一套 Resolver,避免了到处 if-else 补洞;代价:技能实现需拆解为多步移动意图,增加了逻辑复杂度;替代:放弃直接改坐标的“边走边改”模式,改用两阶段结算。
- 收益:使用分层占用表(地形/单位/临时物)替代类型 if-else 组合规则;代价:需要维护多层数据结构;替代:放弃针对每种物体类型写独立碰撞判定的方案。
- 收益:推动链在临时结构模拟且支持整条链失败回滚;代价:实现逻辑比单次移动稍复杂;替代:放弃在真实占用表上反复读写或允许半成功状态。
你可能也喜欢

拆解拉针解谜的惩罚机制与假难度设计。文章分析顺序错误如何触发直接重开,通过低容错率制造“看似难、实为假”的挑战体验,揭示利用规则逻辑而非复杂操作构建关卡的底层逻辑,为解谜游戏提供高价值策划参考。

文章深度拆解 Match-3 核心玩法机制,聚焦 3/4/5 消的强度分层逻辑。通过量化分析消除爽点投放节点与动态卡点控制策略,揭示如何以规则驱动用户留存。内容涵盖可控随机生成算法与关卡节奏设计,旨在帮助开发者构建高粘性消除体验,提升游戏数值平衡度与可玩性。

文章深度拆解多结局触发条件编写与玩家路径引导机制。通过量化核心要素明确通关门槛,构建从强提示到无引导的分级提示体系,并设计动态反馈以平衡探索自由度,帮助开发者高效构建多结局叙事结构。