现有的寻路算法有许多, A* 寻路, 随机寻路, 广度优先的遍历算法,还有遗传算法寻路, 以上的算法在网上介绍很多, 在这里不详细介绍了。 A* 是比较有名的寻路算法, 简单,高效, 但缺点也很明显, 不稳定,且得到的解不是最优解, 特别是在路径复杂的情况下,A* 得到的路径与最优解的路径相差很大。 广度优先的遍历算法资源开销极其巨大, 把所有的路找出来并比较一遍,开销是难以想象的。
在游戏开发的过程中, 如何取得高效且最优的路径是相当重要的。 经过琢磨, 思路如下: 假设有一个拥有无限复制能力的机器人, 开始寻找目标点, 每前进一步做一个标记(标识该路已经被经过),如果遇到分叉路口,就复制自身, 丁字路口就复制2个,十字路口就复制3个,已经被经过的路不再重复经过, 无路可走(遇到障碍或者前面的路都已经被其他机器人经过)时, 原地销毁; 有路走时,一直走,遇到路口就复制,如此重复, 直到找到目标点。
由于每个机器人都是复制品, 移动能力是相等的, 所以最先找到目标点的机器人所经过的路径肯定是最优解!
代码建模如下:
测试所用的图形渲染如下:
测试窗体代码:
如果想看一下寻路的步骤,可以去掉窗体中的注释, 一步一步观察寻路的过程。
测试结果:
上面采用的算法,可以算是广度遍历寻路算法的一个变种, 不再重复走已经走过的路径, 并且不需要做很多搜索和开销, 通过竞争的方式来取得最优解。
===========================================================================
在游戏中, 可能路径不会那么简单, 有些路比较难走,象沼泽、沙漠, 经过的路需要耗费的移动点数很多, 有些路比较好走, 象已经开辟的马路,不太需要耗费移动点数, 这样的情况下, 我们需要对该算法进行一些改变。
首先, 我们建立一张带耗费移动力权值的地图表, 0 不可走, >=1 为需要耗费的移动力权值
原理如下: 假设有一个拥有无限复制能力的机器人, 开始寻找目标点, 每前进一步做一个标记(标识该路已经被经过),如果遇到分叉路口,就复制自身, 丁字路口就复制2个,十字路口就复制3个,已经被经过的路不再重复经过, 无路可走(遇到障碍或者前面的路都已经被其他机器人经过)时, 原地销毁; 有路走时,一直走,每个坐标点耗费的时间为地图表对应的权值,遇到路口就复制,如此重复, 直到找到目标点, 优先找到目标的机器人的路径为最佳路径。
对 SNode 类进行改造,
/// <summary>
/// 寻路结点
/// </summary>
public class Node
{
public List<Node> Children = new List<Node>();
public Node Parent = null;
public Point Pos;
public int NodeValue = 0; //路耗费权值
/// <summary>
/// 目前寻路者在该结点的位移
/// </summary>
public int Moved = 0;
}
对 WayFinder 也进行改造:
图形渲染观察类:
窗体代码:
效果如下:
大家有好的想法,欢迎一起探讨。 QQ 512624668