1. WayPoint寻路
下图是一个典型的路点寻路
另一种方法是使用多边形来记录路径信息,它可以提供更多的信息给ai角色使用。下图就是一个navigation mesh。
以下列出几个WayPoint的不足之处:
如下图A点和B点之间的路径
NAV寻路如下图
下图是路点寻路,如黄线,会产生“Z”字形
下图为文章开始时展示的地图的比较,红线是wayPoint寻路,蓝线是nav。
3. 不能进行动态修正,如果地图中有动态障碍,处理起来会很困难
如要实现即时战略游戏中,一辆在路上行走的坦克会挡住你军队的去路,这个移动的坦克就是一个动态障碍。
4. 不能根据角色的特性(不同宽度、高度等)改变路径
如一个狭窄的通道,普通的人能够通过,而一辆马车的宽度超过通道宽度,应该不能通过。
5. 不能保存地形的附加信息,如地表高度、地面特征(水面、沙地等)
比如一个游戏中的角色在走到沙地上时会降低移动速度,或走在一个斜坡上时人物会发生倾斜等。
2. NavMesh寻路:
nav寻路一般包含两部分,首先是使用工具根据地图信息生成寻路用的nav mesh,接下来就是在游戏中根据生成的nav mesh来自动寻路。
一般人首先关心的就是寻路方法,所以这里把顺序颠倒下,先说寻路。
一. 使用A*寻找所经过网格路径
下图为一个已经生成nav网格的地图,深红色区域为不可行走区域,浅红色区域为可以行走的区域。
如下图,现在如果要寻找从A点到B点的路径,首先要从所有可行走的网格中找到一条最优的网格路径(图中紫色的网格),然后再根据这些网格生成所需要的路径点。
计算最优网格路径的方法可以使用流行的A*,也可以使用其它方法。A*算法网上很多就不说了,至于三角网格的A*实现因为涉及网格的数据结构会在系列的最后给出。
二. 生成路径点
nav寻路最常用的就是光照射线法 了,这个在neoragex2002的blog上有讲,这里就不说了
http://www.cnblogs.com/neoragex2002/archive/2007/09/09/887556.html
另一种方法就是拐角点法 ,如下图
下图的5个凸多边形是已经生成的导航网格,多边形外部的区域为不可行走区域,current为起点,goal为终点,从图中就可以看出最短路径为图中红线,蓝色圈出的点为我们需要找出的点。所有多边形顶点均按逆时针方向存储(这些均在生成导航网格时处理,以后会讲到)。
(1)下图显示出各区域之间的入口,即多边形的临边。由图中可以看出每个临边均为起点穿出该多边形区域的边,故以下称该边为穿出边。
(2)首先找到起始点所在的多边形和穿出边的两个端点,由起点连接两个端点,形成两个线段lineLeft 和lineRight。如下图。绿色圈表示左点,红色表示右点(左点、右点是根据多边形顶点保存顺序而来)。
(3)继续找到下一个穿出边的两个端点,判断新的左点是否在lineLeft 和lineRigh之间,如果在,则更新lineLeft为起点到新左点的线段。
同样处理新穿出边的右点,如下图
该步最后得到两个新的线段,如下图。
(4) 继续判断下一个穿出边的两个端点,如下图,新的左点在lineLeft和lineRight的外面,则不更新线段。
下图说明新的右点在两条直线之间,更新lineRight。
该步最后得到两个新的线段,如下图。
(5) 继续循环判断下一个穿出边的两个端点,该穿出边的两个端点都 在lineRight的右侧,表示lineRight的终点 即为路径的一个拐角点 。
(6) 循环以上步骤都可以找到从起点到终点的一条完整路径。
在继续下面的nav网格生成算法之前,先介绍一下涉及到的计算几何知识。这里只罗列出结论,要详细了解参考相关书籍。
–主多边形:被裁剪多边形,记为A
–裁剪多边形:裁剪窗口,记为B
多边形顶点的排列顺序(使多边形区域位于有向边的左侧 )外环:逆时针 ;内环:顺时针
主多边形和裁剪多边形把二维平面分成两部分。
内裁剪:A∩B
外裁剪:A-B
裁剪结果区域的边界由A的部分边界和B的部分边界两部分构成,并且在交点处边界发生交替,即由A的边界转至B的边界,或由B的边界转至A的边界。
如果主多边形与裁剪多边形有交点,则交点成对出现,它们被分为如下两类:
进点 :主多边形边界由此进入裁剪多边形内 如,I1,I3, I5, I7, I9, I11
出点 :主多边形边界由此离开裁剪多边形区域. 如, I0,I2, I4, I6, I8, I10
算法步骤
(1)建立空的裁剪结果多边形的顶点表.
(2)选取任一没有被跟踪过的交点为始点,将其输出到结果多边形顶点表中.
(3)如果该交点为进点,跟踪主多边形边边界;否则跟踪裁剪多边形边界.
(4) 跟踪多边形边界,每遇到多边形顶点,将其输出到结果多边形顶点表中,直至遇到新的交点.
(5)将该交点输出到结果多边形顶点表中,并通过连接该交点的双向指针改变跟踪方向(如果上一步跟踪的是主多边形边界,现在改为跟踪裁剪多边形边界;如果上一步跟踪裁剪多边形边界,现在改为跟踪主多边形边界).
(6)重复(4)、(5)直至回到起点