COC Like 游戏中的寻路算法

  • Post author:
  • Post category:IT
  • Post comments:0评论

同样是一篇老文章, 2013 年初我刚玩 COC 的时候写给公司内部分享的。由于当时公司还没有决定开手游项目,但有意向做一款 COC Like 的产品,并希望开发期间保密,所以相关技术文章都没有公开。

目前,我们的游戏上线,就可以把当初写的东西陆续贴到 blog 上了。

COC 的地图有 40×40 格,边界还有两格不可以放建筑的格子。所以整个地图是 44×44 格的。但在做坐标判定时,基于格子是远远不够的。COC 官方版本很可能是基于像素级的精度的,和本文所述方法不一致,所以本文仅提出一种可行的数据结构,

地图至少要基于网格顶点来建立坐标系统。每个格子由中心点以及四角为顶点,一共有 9 个坐标点。也就是说,最小单位是半个格子。坐标系是 [0,88]

下面的示意图是一个格子,以及 9 个坐标点:

+--+--+
|  |  |
+--+--+
|  |  |
+--+--+

关于建筑,除了表面上看到的占据格子的面积外,还有实际的尺寸。

比如矿,空间上占 3×3 个格子,但实体则可能是这样的:

..+++..
.+###+.
+#####+
+#####+
+#####+
.+###+.
..+++..

也就是说,对于一个 3×3 的建筑来说,它占据了 9 个坐标点 # 。当步兵攻击它的时候,需要站在周围的一圈坐标 + 上。实体不是方的,可以让兵围起来的时候大致成一个八边形,而不是方形。

对于 2×2 的建筑,则是这样的:

..+..
.+#+.
+###+
.+#+.
..+..

像营地这样的 5×5 建筑,建筑实际占地和 3×3 一样,步兵看起来是靠近攻击的。步兵在攻击的时候,必须坐标轴对齐毗邻建筑,但是播放攻击动画是朝向建筑中心的。

关于寻路:

COC 不同于 RTS ,它基本上是运动的单位寻路去攻击静止建筑。(部队交火例外,这个先撇开不谈)地形在破坏之前,大体上路线其实大体上是固定的。而建筑也有限。加上地图规模不大,这让寻路模块也有了极大的优化空间。

我认为预处理可以极大的简化计算。

我们可以针对每类建筑设置一张寻路图。以 3×3 的普通建筑为例:

2100012
10###01
0#####0
0#####0
0#####0
10###01
2100012

这里的 0,1,2 只是到建筑的实际距离。我们只需要做一次全地图填充,就可以写入地图上所有坐标点到建筑的最短距离。陆军在移动时,只需要找到周围 8 个坐标中距离建筑更近的一个,移动过去即可。如果距离为 0 就可以展开进攻。注意,斜向移动并不会更快。

对于不同攻击距离的单位,可以分别生成不同的图表。这样,弓箭手就会在刚好在射程最远处就展开进攻了。

关于墙:

墙不是建筑,除了炸弹骷髅,所有兵种都不以墙为寻路目的地。所以墙不需要生成上面的图(炸弹骷髅的移动逻辑另做)。

墙对于寻路系统来说,只是一个权值很高的障碍(可以跳跃后则忽略)。比如,一个 3×3 建筑围了墙后该怎么计算呢?(如下图,我故意留了两个口)。

####.
#ooo#
#ooo#
#ooo#
##.##

展现为坐标点是这样的。# 表示建筑,X 表示墙,. 表示路。

...........
.XXXXXXX...
.X.........
.X..###..X.
.X.#####.X.
.X.#####.X.
.X.#####.X.
.X..###..X.
.X.......X.
.XXX...XXX.
...........

如果我们认为通过墙的难度是 6 (就是说,拆墙好过走 6 个格子。实际设置的值肯定比 6 大) ,那么按同样的方法标注前面的图就好了。

ba987765456
a9876667345
98210001234
8710###0165
760#####066
760#####067
760#####067
8710###0178
88210001288
79871117897
65432223456

如果在行军路线上,下一个目标点是墙,那么就先攻击墙就可以了。

总结一下,其实我们只需要为每类兵种,针对它所偏好攻击的建筑群生成一张路图,标记了一个士兵在地图任何位置所需要做的动作:是向某个方向移动?还是站在原地开始攻击。那么士兵每到任何一个新坐标,他都可以通过查表 O(1) 时间得到要做的事情。

只有地形破坏后,路图才需要重新计算。计算的时间复杂度是 O(n) 的,只跟地图尺寸有关。我的试验代码可以在毫秒级完成重算。

ps. COC 应该不是采用这样的算法这可能和他们采用的地图数据结构有关,因为它的士兵 AI 有明显的迟钝,大约 6 秒才会重算一次。但我认为上面的算法更优不必追究 COC 的原版算法是怎样的。

对于炸弹人的逻辑,大致应该是寻找附近封闭空间中最近目标,炸毁路径上的障碍。详细算法另开一篇。

发表回复