A- star算法在游戏寻路中的应用和优化
摘要
在即时战略游戏(简称RTS)中,玩家可以用鼠标选定一组单元,然后单击地图上某个位置,或者某个要攻击的敌人,这时寻路模块便会为这组单元找到一条能够避开障碍物的路径,让这组单元能够通过这条路径到达指定位置。这个功能就是路径规划,也称之为“寻路”。
本文先介绍A*寻路的基本算法,然后通过示例一步步观察A*寻路是如何工作的。在了解了算法原理后,我从最小运行时间和运行效率两方面对算法进行了优化,结果证明优化后的A*算法具有更快的运行速度。
关键词:游戏寻路 A*算法 优化
1. 绪论
A*寻路方式通常有三种:基于单元的导航图、基于可视点导航图和导航网格。
1.1基本术语
地图:“地图”是一个空间,也可以称为“图”,它定义了场景中相互连接的可行区域,形成一个可行走网络,A*在这个空间内寻找两个点之间的路径。
目标估计:是指在寻路过程中估算代价的方法。通过采用不同的目标估计方法,可以实现更为智能、有趣的AI角色。
代价:在寻路过程中,有许多影响因素,例如时间,能量,金钱、地形、距离等。对于起始节点和目标节点之间的每一条可行路径,都可以用代价的大小来描述。
节点:节点与地图上的位置相对应,可以用它来记录搜索进度。节点中存放了A*算法的关键信息,首先,节点的位置信息是不可少的,除此之外,每个节点还记录了这条路径的上一个节点,即它的父节点,这样在达到目标节点后,可以通过反向回溯确定最终路径。另外,每个节点还有三个重要的属性值,分别是g、h、f。
g:从起始节点到当前节点的代价。
h:从当前节点到目标节点的估计代价。
f=g+h:是对经过当前节点的这条路径的代价的一个最好估计值,f值越小,认为路径越好。
导航图:要进行寻路,首先需要将游戏环境用一个图表示出来,这个图就称为导航图。导航图可以有多种形式,这里将介绍其中最重要的三种,即基于单元的导航图、可视点导航图和导航网格。它们各有特点,应用时,需要根据实际情况进行选择。
2. 数学模型
为了更好地理解A*寻路算法法,我们来看一个实例。图1可以看做一个基于单元的导航图,其中白色方格表示可行走区域,黑色方格含有障碍物,是不可行走区域。节点存储了每个可行走方格的中心位置以及相关的寻路数据。
如果用方格所在的行和列来表示位置,则左上角坐标为(1,A),起点为(4,C),终点为(2,I)。
图1 A*寻路示意图
这里应用A*算法找出起始位置与目标位置之间的最短路径,并且避开障碍物。首先,它会从起始节点开始,逐步扩散到相邻节点,直到抵达目标位置所在节点,或因无法找到可达路径而终止。
开始搜索前,需要记录待考察的节点,将这些记录在一个表中,称为Open表。最初的Open表只有一个节点,就是起始节点。
除了Open表,还需要一个Closed表,来记录已经被考察过,不需要再做考察的那些节点。起初这个表为空。在寻路过程中,每当每个节点的相邻节点都已经检查过,就会将这个节点加入Closed表中。
2.1 A*算法执行步骤
Step1:取出Open表中当前代价最小的节点(4,C),检查它的8个相邻节点,看它们是否能够行走,由于它们都时可行走的,因此,将这8个节点都加入Open表,如图2所示。
图2.A*算法第一步
因此,这一步执行的结果是将8个新节点加入Open表中,而起始节点从Open表中移除,加入Closed表中。
Step2:接下来,开始第二轮循环,这需要从Open表中选出新的节点进行检查。首先我们需要计算这8个节点的行走代价。
g:从起点到当前节点的欧氏距离。
h:从当前起点到目标节点的曼哈顿距离。
f=g+h:从起始位置到该位置,再从该位置到目标节点的估算距离。
如图2所示,(3,C)是当前代价最小的节点,我们选中(2,C)。计算其相邻节点代价:
图3.A*算法第二步
将节点(2,C)放入Closed表中,更新节点信息。
重复以上步骤,直到找到目标节点。
2.2 A*算法优化
从上面计算过程中可以发现,从起点到终点只需经过8个节点,而A*算法却需要搜索33个节点,这浪费了大量的时间,而且占用了很多内存,我们需要对算法进行优化。
分层寻路是一种比较有效的优化A*算法的方法。其基本思想是把二维地图按不同的复杂层次来划分,如图4所示。图中有4个屋子,标号为1、2、3、4,屋子之间有门,如虚线所示。假设要从1号屋子里的起始点走到3号屋子的目的地,首先可以把地图分为两层:第一层只包括屋子和屋子之间的关系(门),不考虑屋子里的细节,这层最简单,第二层是屋子内部的细节,比如桌椅等,这层比较复杂,所以采取的步骤为:
(1)对各个屋子之间整体使用A*算法,找到屋子1到屋子3的路径为1-2-4-3;
(2)在2号4号屋子之间设定中间目的地“子目的地1”,对1号和2号屋子内部细节使用A*算法,找到从起始点到“子目的地1”之间的路径;
(3)让游戏角色走到2号屋子门外。
(4)再确定中间目的地“子目的地2”,以此类推。
3.算法仿真
上一节已经构建出A*寻路算法的数学模型,并讨论了优化方法,现在我们需要在游戏中对A*算法进行仿真。考虑10x10m2的二维平面区域,如图5,图中白色区域是障碍物,我们需要用A*算法让游戏角色通过这些障碍物。
图5.A*仿真区域图
在场景中添加一个游戏角色如下图(黄色的是角色,红色的是目的地),可以看到,运行游戏后,角色准确的找到了路径(绿色的线)。
图6.A*算法仿真结果
4.总结
本文讨论了A*算法在游戏寻路中的应用与优化,并给出了具体的仿真实例。A*算法是游戏人工智能领域最为常用的算法之一,A*算法在效率与寻路准确性方面性能都不错,本文针对经典A*算法进行了进一步优化,使其性能有了一定提升。通过这篇论文,我对游戏领域有了进一步认识,希望有后能成为优秀的游戏程序员。