在游戏中应用A*算法主要是以下步骤:
1.将地图划分包含多个等大区域的网络:传统做法是将地图划分为多个等大的正方形小格子,或者也有将地图划分为由菱形小格子组成;另外如果将地图划分为多个凸多边形情况下,便是NAV导航网格寻路的思路了。
每个小格子就是一个导航路点(waypoint),这种寻路算法就是常说的路点寻路算法。
疑问:地图有多大,小格子多大一个,就会对寻路的效率(对空间、时间消耗均有影响),以及人物行走的视觉效果有直接影响。
2.生成相应的地图数据:主要用于标记各路点可否通过,及其他相应的一些地图信息。
疑问: 通常不同的地形通过的代价应该是不同的,比如通过1米宽的沼泽的代码要大于通过3米长的道路,这时候较短路径应该是起道路而不是沼泽。所在在寻路算法中的最短路径一般是指最小代价路径。对于路点寻路算法来说可对waypoint加上权值来描述。
3.将地图数据、起点、终点交给A*算法,即可得到一条由多个waypoint组成的路径
针对A*算法本身,也有很多值得优化的地方;
A*算法本质是一个启发式搜索算法(BFS等算法其实是A*的一个特例),在计算过种中会主要涉及这么两个重点:
Ø 计算过程中的临时空间:包括一个待搜索点表(open表)和一个已搜索点表(close表);
Ø 路径长度的估价等式:f(n) = g(n) + h(n)
其中f(n)是节点n的估价函数,g(n)是在状态空间中从起点到n节点的实际代价,h(n)是从n到终点的最佳路径的估计代价。需要特别关注h(n),因为g(n)一般是已知的。
???在该算法中,对空间是有一定消耗的,尤其在找不到一条通达的路径时,open表是可能比较庞大的。针对open表是需要做一些添加、删除、排序的操作。比较常见的做法是使用二叉堆来存储这个结构(这会增加“添加或者删除”操作的时间及一些存储空间,但会大大减少排序时间),地图路点越多时性能提升越明显,这需要根据应用场景做不同的取舍。经过实际的HTML5动画的javanoxss实现,性能提升是非常明显的。
对角线距离、欧几里得距离、曼哈顿距离等等。这个计算会在算法中经常用到,需要较为高效,计算简单使用最精简有效的公式。目前的实现中一般使用曼哈顿距离方式。
4.在得到由多个waypoint组成的路径后,再按照游戏的动画方式让精灵沿此路径行走即可。对于这种算法,精灵可能走出Z字形或者锯齿形的路线,如果游戏有需求需要更平滑,还可以做一些额外的处理使其更平滑。
???目前一般弗洛伊德路径平滑算法进行后期处理。
以上便是在游戏中应用A*路点寻路的一些过程和思考。
其他一些算法的优化:性能上可以对地图数据做一些提前处理和运算,记录下结果,空间换时间;另外对于不同语言实现的算法本身细节做一些优化;针对效果:鼠标点击到障碍点无路可走的处理等等。在具体的游戏场景中,也有一些细节优化即可得到大效果的处理方式,或者一些变种的寻路算法。另外还有结合寻路算法的一些相关处理,如动态的运动障碍物等。