游戏脚本0寻路算法
㈠ unity2d 做横版平台游戏有什么好的寻路算法或插件
并没一种寻路适合所有场合,选择都是基于需求而定的。
1. A* 算法与贪婪算法不一样,贪婪算法适合动态规划,寻找局部最优解,不保证最优解。
A*是静态网格中求解最短路最有效的方法。也是耗时的算法,不宜寻路频繁的场合。一般来说适合需求精确的场合。
与启发式的搜索一样,能够根据改变网格密度、网格耗散来进行调整精确度。
使用的地方:
a. 策略游戏的策略搜索
b. 方块格子源歼肆雹轿游戏中的格子寻路
2. Unity 自带的导航网格系统
Unity 内置了NavMesh导航网格改告系统,一般来说导航网格算法大多是“拐角点算法”。
效率是比较高的,但是不保证最优解算法。
使用的地方:
a.游戏场景的怪物寻路
b.动态规避障碍
㈡ 梦幻西游自动寻路的寻路算法怎么算
A*寻路算法 A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。
公式表示为: f(n)=g(n)+h(n),
其中f(n) 是节点n从初始点到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n)是从n到目标节点最佳路径的估计代价。
保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:
估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
估价值与实际值越接近,估价函数取得就越好。
例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。
conditions of heuristic
Optimistic (must be less than or equal to the real cost)
As close to the real cost as possible
主要搜索过程:
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
遍历当前节点的各个节点,将n节点放入CLOSE中,取n节点的子节点X,->算X的估价值->
While(OPEN!=NULL)
{
从OPEN表中取估价值f最小的节点n;
if(n节点==目标节点) break;
else
{
if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于OPEN表的估价值 )
更新OPEN表中的估价值; //取最小路径的估价值
if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于CLOSE表的估价值 )
更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值
if(X not in both)
求X的估价值;
并将X插入OPEN表中; //还没有排序
}
将n节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
启发式搜索其实有很多的算法,比如:局部择优搜索法、最好优先搜索法等等。当然A*也是。这些算法都使用了启发函数,但在具体的选取最佳搜索节点时的策略不同。象局部择优搜索法,就是在搜索的过程中选取“最佳节点”后舍弃其他的兄弟节点,父亲节点,而一直得搜索下去。这种搜索的结果很明显,由于舍弃了其他的节点,可能也把最好的
节点都舍弃了,因为求解的最佳节点只是在该阶段的最佳并不一定是全局的最佳。最好优先就聪明多了,他在搜索时,便没有舍弃节点(除非该节点是死节点),在每一步的估价
中都把当前的节点和以前的节点的估价值比较得到一个“最佳的节点”。这样可以有效的防止“最佳节点”的丢失。那么A*算法又是一种什么样的算法呢?其实A*算法也是一种最
好优先的算法。只不过要加上一些约束条件罢了。由于在一些问题求解时,我们希望能够求解出状态空间搜索的最短路径,也就是用最快的方法求解问题,A*就是干这种事情的!
我们先下个定义,如果一个估价函数可以找出最短的路径,我们称之为可采纳性。A*算法是一个可采纳的最好优先算法。A*算法的估价函数可表示为:
f'(n) = g'(n) + h'(n)
这里,f'(n)是估价函数,g'(n)是起点到终点的最短路径值,h'(n)是n到目标的最断路经的启发值。由于这个f'(n)其实是无法预先知道的,所以我们用前面的估价函数f(n)做
近似。g(n)代替g'(n),但 g(n)>=g'(n)才可(大多数情况下都是满足的,可以不用考虑),h(n)代替h'(n),但h(n)<=h'(n)才可(这一点特别的重要)。可以证明应用这样的估价
函数是可以找到最短路径的,也就是可采纳的。我们说应用这种估价函数的最好优先算法就是A*算法。哈。你懂了吗?肯定没懂。接着看。
举一个例子,其实广度优先算法就是A*算法的特例。其中g(n)是节点所在的层数,h(n)=0,这种h(n)肯定小于h'(n),所以由前述可知广度优先算法是一种可采纳的。实际也是
。当然它是一种最臭的A*算法。
再说一个问题,就是有关h(n)启发函数的信息性。h(n)的信息性通俗点说其实就是在估计一个节点的值时的约束条件,如果信息越多或约束条件越多则排除的节点就越多,估价函
数越好或说这个算法越好。这就是为什么广度优先算法的那么臭的原因了,谁叫它的h(n)=0,一点启发信息都没有。但在游戏开发中由于实时性的问题,h(n)的信息越多,它的计
算量就越大,耗费的时间就越多。就应该适当的减小h(n)的信息,即减小约束条件。但算法的准确性就差了,这里就有一个平衡的问题。
}
㈢ A*算法——启发式路径搜索
A*是一种路径搜索算法,比如为游戏中的角色规划行动路径。
A* 算法的输入是, 起点(初始状态) 和 终点(目标状态) ,以及两点间 所有可能的路径 ,以及涉及到的 中间节点(中间状态) ,每两个节点间的路径的 代价 。
一般还需要某种 启发函数 ,即从任意节点到终点的近似代价,启发函数能够非常快速的估算出该代价值。
输出是从 起点到终点的最优路径 ,即代价最小。同时,好的启发函数将使得这一搜索运算尽可能高效,即搜索尽量少的节点/可能的路径。
f(n)=g(n)+h(n)
f(n) 是从初始状态经由状态n到目标状态的代价估计
g(n) 是在状态空间中从初始状态到状态n的实际代价
h(n) 是从状态n到目标状态的最佳路径的估计代价
A*算法是从起点开始,检查所有可能的扩展点(它的相邻点),对每个点计算g+h得到f,在所有可能的扩展点中,选择f最小的那个点进行扩展,即计算该点的所有可能扩展点的f值,并将这些新的扩展点添加到扩展点列表(open list)。当然,忽略已经在列表中的点、已经考察过的点。
不断从open list中选择f值最小的点进行扩展,直到到达目标点(成功找到最优路径),或者节点用完,路径搜索失败。
算法步骤:
参考
A* 算法步骤的详细说明请参考 A*寻路算法 ,它包含图文案例清楚的解释了A*算法计算步骤的一些细节,本文不再详细展开。
看一下上面参考文档中的案例图,最终搜索完成时,蓝色边框是close list中的节点,绿色边框是open list中的节点,每个方格中三个数字,左上是f(=g+h),左下是g(已经过路径的代价),右下是h(估计未经过路径的代价)。蓝色方格始终沿着f值最小的方向搜索前进,避免了对一些不好的路径(f值较大)的搜索。(图片来自 A*寻路算法 )
现在我们可以理解,A*算法中启发函数是最重要的,它有几种情况:
1) h(n) = 0
一种极端情况,如果h(n)是0,则只有g(n)起作用,此时A*演变成Dijkstra算法,这保证能找到最短路径。但效率不高,因为得不到启发。
2) h(n) < 真实代价
如果h(n)经常都比从n移动到目标的实际代价小(或者相等),则A*保证能找到一条最短路径。h(n)越小,A*扩展的结点越多,运行就得越慢。越接近Dijkstra算法。
3) h(n) = 真实代价
如果h(n)精确地等于从n移动到目标的代价,则A*将会仅仅寻找最佳路径而不扩展别的任何结点,这会运行得非常快。尽管这不可能在所有情况下发生,你仍可以在一些特殊情况下让它们精确地相等(译者:指让h(n)精确地等于实际值)。只要提供完美的信息,A*会运行得很完美,认识这一点很好。
4) h(n) > 真实代价
如果h(n)有时比从n移动到目标的实际代价高,则A*不能保证找到一条最短路径,但它运行得更快。
5) h(n) >> 真实代价
另一种极端情况,如果h(n)比g(n)大很多,则只有h(n)起作用,A*演变成BFS算法。
关于启发函数h、Dijkstra算法、BFS(最佳优先搜索)算法、路径规划情况下启发函数的选择、算法实现时List的数据结构、算法变种等等更多问题,请参考: A*算法
㈣ 制作游戏辅助:用按键精灵如何确定人物朝向
按键学院实战班前段时间沸沸扬扬的讲解着自动寻路教程。今天,咱也来跟大家分享分享,实战班自动寻路思路之——确定人物朝向(箭头的方向角度)。
不少网络游戏已经支持自动寻路,玩家只需要设定终点后,游戏人物即可自动寻路,但是碰到某些未自带自动寻路功能的游戏,就呵呵呵了……
院刊今天跟大家分享两款热门游戏的人物朝向判定~~知道了人物朝向,再知道目标的朝向,不就知道怎么自动寻路了嘛~
按键学院实战班的07老师整理了自动寻路的三要素,给大家分享:
自动寻路一般需要确定三个要素:
确定路线
确定朝向
确定位置
确定了人物位置和物品位置,再确定了人物的朝向,与目标路线。将人物转向目标就可以用脚本实现自动寻路的功能。
剑灵模式的地图的寻路:游戏画面右上角有小地图,地图中灰白色箭头代表人物。
斜率:已知A、B点坐标,求直线AB的斜率。
斜率公式k=(y1-y2)/(x1-x2),即两个坐标纵坐标之差,除以两个坐标横坐标之差。
正切函数:正切函数是直角三角形中,对边与邻边的比值。
在上图中,即tanα=b/a=(y2-y1)/(x2-x1)。在按键精灵中为Tan函数。
通过公式对比,我们可以知道,直线AB的斜率,即角α的正切值
角度:已知角α的正切值,我们可以通过反三角函数公式,来计算这个角度的值。
α=arctan(k)。在按键精灵中为Atn函数。
反三角函数:即相对应的正弦、余弦、正切、余切为x的角。
如何实现箭头角度计算:
从上面的三角函数知识拓展中,我们知道,要计算一个角度,可以通过计算该角度的正切值,再通过反三角函数来求这个角度。
那么,在按键精灵的代码中如何实现呢?
思路:
1.通过找图找色命令,找到箭头顶部A的坐标,以及箭头底部中间B的坐标。
2.构建直角三角形。确定箭头的指向的角度α。
3.通过斜率/正切函数,来计算角度α的正切值。
4.通过反三角函数,来得出角α的角度值。
代码实现:
‘在剑灵右上角的小地图里找色/找图,箭头坐标存储在(x1,y1),箭尾坐标存储在(x2,y2)
FindColor1200,0,1920,300,"箭头颜色",x1,y1
Ifx1>0Andy1>0Then
EndIf
FindColor1200,0,1920,300,"箭尾颜色",x2,y2
Ifx1>0Andy1>0Then
EndIf
'计算斜率/正切值
斜率=(y1-y2)/(x1-x2)
'计算角度
角度=Atn(斜率)
当然,自动寻路并不是单一的方式,不同游戏的地图不同,寻路的方式不同。但是运用到的数学知识和思路是共同的。当然,有些特定的地图有更便捷的方式,例如最终幻想14的地图。下一期的院刊,再跟大家分享另一些不同的地图的寻路方式~~