目的
一群物体到达某个目的地时,需要对这些海量单位做寻路和避障,类似塔防类游戏的怪物步行到终点的过程。
参考视频:https://www.bilibili.com/video/BV12bzZY2EfA
演示动画:https://howtorts.github.io/examples/4-basic-flow-fields/index.html
介绍
Flower Field流场寻路算法,相对于A*算法,不需要计算每一个单位的路径,而是建立一个向量场。这个向量场像是地标一样,告诉在场的所有物体应该朝哪个方向移动。每个位置都有地标,因此物体无论在哪个位置都能找到下一步移动的方向。
思路
在网格化的地图中生成指向目标格子的向量,单位只需要根据向量就可以达到目标。向量场的计算与物体数量无关,只与地图大小相关,因此当单位数量较多时,其性能的优势更加明显。
实现
(1)计算热力图
即每个格子到达目标最短的距离,可以使用BFS广度优先搜索算法。
上述代码的解析:定义一个队列,先将目标格子推入队列,将其取出后寻找其邻居,每个邻居的距离等于当前格子距离+1。计算好后再将邻居推入队列。以此类推,直到队列为空。
广度优先是一种树的遍历方式,和深度优先是相对的。广度优先是指先将目标格子的所有邻居塞入队列,而如果是深度优先,做法则是找到目标格子的一个邻居,然后继续找这个邻居的邻居,“一条道走到底”。广度优先比较适合本文的算法,因为格子的距离比较好计算(为当前格子距离+1)。
举个形象的例子,如果老师需要遍历全班的同学到办公室一个一个谈话,那么老师先叫其中一名同学到办公室谈话,结束后让他回教室叫上前后左右位置的同学来办公室排队,每位同学都如此操作,已谈过的不必再谈,就实现了全班的遍历。
(2)计算向量场
每个格子从8个邻居(如果格子处于边缘,则邻居数目小于8)中判断距离,并指向距离值最小的格子。
(3)向量插值
在构造向量场后,物体移动时其脚步很可能横跨多个格子。如果我们规定这种情况让游戏物体按固定的一个格子(比如左下角)的向量方向移动,可能不符合预期,无法到达终点。
如上图所示,正方体横跨了4个格子。使用双线性插值,先根据横坐标将A、B按2、8加权,C、D按2、8加权,分别得到2个向量,然后根据纵坐标7:3将两个向量融合,得到最终向量。此时物体就会根据横跨4个格子的深浅加权,得到综合的方向。