本文属sunbright原创,小S吧——sunbright博客首发
如转载请注明:sunbright博客

 
引言
终于把A*寻路算法看懂了,虽然还有点小问题,但A*寻路算法我已经略知一二,帮助还不知道的朋友进入A*算法入门阶级,应该不成问题,下面就来看看A*算法的原理(以下讲解不带入任何程序语言,因此只要你看懂了下面所有的话,那么你可以随意用在任意程序语言中)
在下也是初学,写这篇文章的目的只是让新手入门,因此高手看到这就飘过吧,当然愿意给予指点的高手请继续往下看
前言
在文中可能会出现一些专业术语或者是我信口雌黄的话语,未免看官不明白,前面我先加以注解,具体意思可以从文中体会到
该寻路算法是在一个由很多方格组成的图像中,你操纵一个蓝色小方格进行寻路的环境下进行讲解,具体请看文章一开始的flash示例,或者是查看A*寻路算法例子
 
方格:一个一个的小方块
障碍物:挡着去路的东西
目标方格:你想到达的方格
操控方格:你控制的寻路对象
标记:临时为某一个方格做的标记
父标记:除了操控方格所创建的临时标记,每个标记都有个父标记,但父标记不是随便乱定的,请看下文
开启标记列表:当该标记还未进行过遍历,会先加入到开启标记列表中
关闭标记列表:当该标记已经进行过遍历,会加入到关闭标记列表中
路径评分:通过某种算法,计算当前所遍历的标记离目标方格的路径耗费估值(后面会讲一种通用的耗费算法)
  首先描述一个环境,在一望无际的方格中,我身处某某方格,如今我想去某某方格,接下来我开始寻路!
  在脑海中,先创建开启标记列表、关闭标记列表,然后把我的初始位置设置为开始标记进行遍历,同时因为开始标记已经遍历过了,因此把开始标记加入到关闭列表。通过开始标记我们找出了相邻的八个方格,为它们创建相应的标记,加入到开启标记列表中,并把每个标记的父标记设置为开始标记,是因为开始标记才让我们这些方格创建了属于自己的标记,它就是我们的再生父母。但不符合条件的我们就不加入开启标记列表(下面的条件符合任何一条都不要加入到开启标记列表中):
  1、它在我们的搜寻地图范围外,比如你地图的寻路范围是 0*0 - 50*50,那么但这个点在边缘的时候,那它相邻的八个方格,必定有几个是处在外面的!
  2、搜寻的这个方格是否有障碍物、或不可到达,比如河流,石头,山川等
  3、判断它是否已经加入关闭标记列表,若已经加入表示该方格已经遍历过了,在遍历一次也无济于事,还会影响效率
  4、判断它是否已经加入开启标记列表,若已经加入那么咋们就来判断一下该标记是否离开始标记更近一些
  5、判断当斜着走的时候,它的上下或左右是否有障碍,如果有则表示你无法斜着走,需要先横走一下,再竖走一下或者是竖走一下,再横走一下
  如果想象不出来,可以看着这个A*寻路算法例子进行学习和比较。
 
  把相邻的八方向都添加到开启标记列表中后,现在从开启标记列表中取出一个路径评分最低标记,对他开始进行遍历相邻的八个方格,并进行创建标记、添加到开启标记列表、设置父标记为该标记,并且重复判断上面的创建条件,然后把这个标记加入到关闭标记列表
  如此循环的做着上面所说的事,然后每次判断下面条件:
  1、判断开启列表是否已经为空,如果空了则表示从操控方格到目标方格是不可能达到,是死路!
  2、判断当前所遍历的标记的坐标与目标方格的坐标是否相同,如果相同则表示到达了目标方格!
 
  当得到第一个条件,则表示这条路是死路,因此咱们不用遍历了,宣告结果吧。当得到第二个条件,则表示咱们已经找到路了,从最后创建的这个标记开始,一直向上访问它的父标记,直到开始标记的时候没有父标记为止,这就是一条从操控方格到目标方格的路径,但这可能不是捷径。
 
  A*寻路算法,只是保证在低消耗的情况在最短的时间找出路径,但A*寻路算法寻出来的路不一定是最近,但也绝对不会远的离谱,可也不排除你对路径评分算法的优化可以做到最快最短最低消耗,或者对最终路径的优化来达到目的,下面就来讲讲通用的路径评分计算公式:
 
  首先看公式: F = G + H
 
  F值表示路径评分,G值表示当前所判断的标记离开始标记的路径耗费,H值表示当前所判断的标记离目标方格的路径估值耗费
  G值的计算方式是,如果为斜走判断则用父标记的G值加上14表示当前标记的G值,如果为直走判断则用父标记的G值加上10表示当前标记G值
  H值通常的计算方式是一种称作为曼哈顿方法的方式,当前标记离目标方格横着的方格数加上竖着的方格数,然后乘以10,最后得值就是H值。当然若你想通过A*寻出最好的路径,那么改善算法的主要地方就是这个H值的算法(如果你对本计算方式还有更好的办法可以到我博客中去发表自己的意见)
  根据上面讲的A*算法的做法来讲,则表示前面判断哪个标记离开始标记更近一些只需判断一下G值即可;前面所说的取出一个路径评分最低标记,也就是将F值进行升序排序取出第一个,或降序排序取出最后一个。
  
  sunbright总结:本文只是初略的讲解A*寻路算法的入门,相信仔细看过该文用心体会肯定能入门A*算法,但该文不是A*算法的权威,因为我自己也知道这篇文章是按照我自己的想法对A*的理解所写出来的,可能跟A*算法的原理是一样的,但讲解方式可能大不同,毕竟国内大部分A*算法的讲解都是来自于国外的译本。希望还不懂A*寻路算法的朋友通过这篇文章能理解过来!——本文出至sunbright博客
  
对于高手看过本文后,有什么见解可以提出来,在下也是菜鸟,也希望能得到进步;如果新手看过本文后,有什么好的建议或疑问,也可以提出来,我尽量解答!
[最后修改由 sunbright, 于 2008-10-03 22:35:38]
评论Feed 评论Feed: http://www.xiaos8.com/feed.asp?q=comment&id=312
怎么一页才显示这么点文章?点快速检索查看更多的文章: 显示全部 | 评论: 55 | 排序 | 观看的: 20768
YBoy*
[ 2008-11-08 21:27:52 ]
不知博主有没有发现这样的一个问题:
开始时选择终点,蓝色方块寻找最短路径走过去;最后,蓝色方块在终点处。这时,把起点作为第二次寻路的终点,按道理应该是按原路径走回去的(因为第一次寻路已经是最短了),但,结果不是这样。
YBoy*
[ 2008-11-08 21:29:08 ]
可能,最短路径不止一条吧:)
sunbright
[ 2008-11-08 21:38:03 ]
的确如此,了解A*寻路的方式,自然就能想明白为什么会这样
一明*
[ 2009-06-09 17:45:48 ]
不是最短路径
sunbright
[ 2009-06-09 18:54:03 ]
额,为什么都喜欢拿例子说话额
文章已经说过了,现在计算出来的并不是最短路径
因为没有对路径评分的算法进行优化
一般的Flash游戏,做到这样的寻路级别已经够用了
游客*
[ 2009-06-16 14:57:29 ]
谢谢你的分享
游客*
[ 2009-06-18 18:22:38 ]
花了好几天,总算用flash as2实现了,不过还是有一定问题,不知道出在什么地方,有时明明有可行的路径却找不到,我很郁闷,能否给我指点指点
sunbright
[ 2009-06-18 19:26:30 ]
额,肯定是算法细节上有问题啦
nihao*
[ 2009-06-20 10:13:34 ]
如果有多个NPC同时寻路的话,就可能会重叠在一起,请问一下,这个问题如何解决呀^_^
sunbright
[ 2009-06-20 10:17:49 ]
NPC寻路重叠?啥意思?如果目标不一样,或者起始点不一样,怎么会重叠呢?
当起始点和目标点一样,才会重叠啊。
nihao*
[ 2009-06-20 11:36:02 ]
在寻路过程中重叠
游客*
[ 2009-06-20 11:39:24 ]
hehe,谢谢了,的确是算法细节上有问题,在计算H值时,我只是用坐标位置的值来计算而忘了乘以10(方块的长)了!!
sunbright
[ 2009-06-20 12:23:53 ]
看看网络游戏
当一堆怪跟着你的时候,貌似他们就是几乎重叠的
但他们起始点不一样时,看上去就好些
但是你带着怪多兜几圈,慢慢的也就重叠了
nihao*
[ 2009-06-24 11:42:56 ]
博主,劳驾你玩一下Flash版的僵尸危机,那里面的怪物寻路是不是很厉害,成千上万的僵尸向你走来,却不会出现重叠,如果两个怪物下一步的路径相同(由于算法并不能将不确定的因素比如这么多怪物下一步会走到哪儿考虑到地图方格的visitable中)就必然会重叠,我尝试了很久却无法解决这个问题,郁闷得很,而网上关于多怪物的碰撞问题却没有,恳请您帮我点化一下,在下将不甚感激!!!!!!!!
sunbright
[ 2009-06-24 11:52:41 ]
这游戏传到中国原来叫僵尸危机啊,这是一个在国外很出名的游戏,早在国外的游戏平台玩过了
至于他的做法呢,很明显怪与怪之间是有碰撞检测的,那么在有碰撞检测的时候寻路肯定不会重叠拉
所以这个问题不应该是从寻路下手解决,如果加了碰撞检测,那为什么还会重叠呢?
很明显你没好嘛,加了碰撞检测还重叠,只能说你碰撞检测有问题啊
跟寻路没关系的好吧。。。
[最后修改由 sunbright, 于 2009-06-24 11:53:56]
nihao*
[ 2009-06-24 12:10:08 ]
感谢你及时的reply!呵呵,原来博主也爱玩呀,只不过这个碰撞检测和我以前做的不同,因为只是
两个怪物MC实际上并未真正重叠呀,在重叠实再做检测是不是迟了点,所以我的思路是用怪物所得路径集合的下一步的坐标值是否相等来判断,但是......,恕我愚钝,能否给我点思路呀
sunbright
[ 2009-06-24 12:16:28 ]
其实实现这种效果有很多办法额。。。
比如
你把每个怪占据点作为一个障碍物来寻;
每个怪在走路时碰到另外一个怪,就停止走动,重新寻路;
还有很多细节做法的,如果这是你开发的第一个很复杂的游戏
那我只能祈求上天保佑你了,因为这不是一点点点化,就能让你做完这个游戏的
nihao*
[ 2009-06-24 13:11:34 ]
关键是,怪是在不停的移动的呀,还有如果碰到在检测的话不就已经重叠上了吗?
sunbright
[ 2009-06-24 13:38:10 ]
不停地检测啊
另外你这句话也有矛盾好吧
你怎么知道他重叠了呢?你也是一直在检测才知道他重叠的啊。。如果你没检测,那么就算他重叠了你程序也不知道啊。。那也不存在已经重叠才检测的可能啊?
游客*
[ 2009-06-24 14:33:07 ]
我意思使用hitTest()检测
sunbright
[ 2009-06-24 14:34:23 ]
用什么检测都是一样的啊,竟然在检测怎么可能重叠呢?
nihao*
[ 2009-06-24 15:09:34 ]
很抱歉我一直在打扰你,但是能不能给我介绍一下该碰撞检测的具体思路
sunbright
[ 2009-06-24 15:11:13 ]
不停地检测碰撞检测就行了啊?你想要知道什么思路额?
sunbright
[ 2009-06-24 15:12:07 ]
不打扰,没关系的~~能解决你的问题,我也会很开心的
游客*
[ 2009-06-24 15:18:37 ]
你认为好一点的(),谢谢
sunbright
[ 2009-06-24 15:27:13 ]
官方不是提供了碰撞的接口么?都是用它啊?你还想干什么呢?一个这么简单的东西,难道你还想做一个3D碰撞系统出来?没必要吧?官方提供的碰撞接口已经够用了。。
游客*
[ 2009-06-25 15:49:05 ]
我觉得上面那位老兄碰到的问题并不简单。其实,多人寻路没有你说的那么简单,网上基本上都是基于单人的寻路,如果多人同时寻路就要把各NPC的冲突问题考虑进去,你把碰撞检测说得那么简单,如果真那样的话,你在Astar演示上把单人的NPC寻路改为多人的试一试
sunbright
[ 2009-06-25 16:09:28 ]
额,多人寻路一样没问题,公司项目已经做过了
游客*
[ 2009-06-25 16:12:28 ]
不介意地话,发过来,瞅瞅哈
sunbright
[ 2009-06-25 16:42:51 ]
公司项目,且是封闭开发的,我拿不出代码,如果你想玩的话
可以去下载这个软件玩玩:http://www.xiaos8.com/article.asp?id=458
sunbright
[ 2009-06-25 16:43:58 ]
里面有个游戏叫爆爆乐,那个游戏里面的AI就是我做的寻路,可以跟3个AI对打~
游客*
[ 2009-06-25 17:23:33 ]
问一下,A*中你对最小F的取得是怎么办的,使遍历开放列表吗?
sunbright
[ 2009-06-25 17:41:44 ]
游客*
[ 2009-09-10 23:34:21 ]
看了你的A星算法讲解很受启发,我是AS3的新手,最近因为一个小游戏里多个NPC的AI都需要寻路算法!我希望了解一下,在游戏中,多个NPC的目标都是玩家,而玩家是在不断移动的,这种情况下,玩家的每次移动都需要NPC重新寻路吗?如果是这样的话,在多NPC同时反复寻路的情况下,性能影响是否会很大?如果很大,有没有什么更好的思路呢?请不吝赐教~~
sunbright
[ 2009-09-11 09:15:39 ]
这个要看地图的大小,地图不是很大的话,A*寻路足够了~~也就是说用上面的办法是可行的
http://www.xiaos8.com/article.asp?id=371 另外这里也有源代码,你可以参考的!
另外我上面提到的爆爆乐,AI在寻路时就是不断在寻路,每当玩家走动一个格子,或者扔一个雷,或者出现宝物,都会重新寻路,去躲避雷,并计算应该是去杀人,或者抢宝物
在2V2时,双AI的情况下,也不会有问题。
祝你好运~~
游客我*
[ 2009-09-11 10:04:39 ]
http://blog.vckbase.com/images/vckbase_com/panic/image007.jpg

这张图片上寻路:当F值相同的时候,优先选择哪一个点作为开启列表的下一格呢.
每次有二个相同的54,后面又有二个相同的74.
是固定方向0-8,还是在开启列表中排序确定的顺序呢?

游客我*
[ 2009-09-11 10:08:50 ]
相同F值时,优先选择哪一个?这个因素,一般有几个条件影响,麻烦老大讲解一下.
另外,当F值相同时,选择的哪个要加入到关闭列表中,另一个没有选择的F值相同的,是否,也在同时一起加放到关闭列表中呢?
sunbright
[ 2009-09-11 10:34:33 ]
如果相同的话,这个就需要更好算法了,比如你要看那条是有利路线,其实一般Flash做的游戏是不需要注意这些的,当然研究一下还是可以的~~
你仔细看看我的例子,会发现同样的路,反过来走,寻出来的路径不一样,有些可能也不是最短路径,但是效率保证了
另外还有几个速度较慢的例子,那寻出来的就真的是最短路径了,但消耗却很高
因此这个要看个人取舍的,我建议使用效率高的~~
游客我*
[ 2009-09-11 11:07:22 ]
极其感谢你的回答,不过我还有问题想问,肯请指教:当有二个F值相同的时,必须选择一个进行下面的操作,二选一的情况下,随便选一个有什么规则吗,是选择先加入开启列表的哪个格子吗?

还有上左,上,上右,左,右,左下,下,右下这8个方向的格子,依次加入开启列表的顺序是根据程序员的习惯,随便定的吧。这样不同人写的寻路,路径也会因为这个顺序而不一样吧?

sunbright
[ 2009-09-11 14:34:33 ]
其实不会的,后面算出来的值,会统一排序的,其实结果会是一样的
游客*
[ 2009-10-14 09:29:53 ]
ke yi ge iwo ni de chengxu ma ?
frank*
[ 2009-10-14 09:32:36 ]
would you give me your program (Matlab) for A* flash. E-mail: huangwei521521@hotmail.com.
thanks
sunbright
[ 2009-10-14 20:25:21 ]
http://www.xiaos8.com/article.asp?id=371
This is what I write A* the source code.
null*
[ 2009-12-17 14:21:21 ]
[表情03] [表情02] [表情02] [表情02] [表情02] [表情02] [表情01] [表情04]
null*
[ 2009-12-17 14:21:49 ]
[表情02] [表情02] [表情02] [表情02] [表情04] [表情03] [表情02] [表情02] [表情02] [表情04] [表情03]
sunbright
[ 2009-12-17 14:33:56 ]
感谢你的回帖测试,让我发现了一个bug,在用户第一次进入网站时,记录的用户名是不存在的,因此昵称会显示null,现在已经修复~~默认为游客
游客*
[ 2010-01-04 21:40:21 ]
不错,学习中,谢谢楼主分享
游客*
[ 2010-01-05 00:46:00 ]
G值的计算方式是,如果为斜走判断则用父标记的G值加上14表示当前标记的G值,如果为直走判断则用父标记的G值加上10表示当前标记G值
  H值通常的计算方式是一种称作为曼哈顿方法的方式,当前标记离目标方格横着的方格数加上竖着的方格数,然后乘以10,最后得值就是H值。当然若你想通过A*寻出最好的路径,那么改善算法的主要地方就是这个H值的算法(如果你对本计算方式还有更好的办法可以到我博客中去发表自己的意见)
__________
LZ~你好

我是一名新手~
我想问问~
文章中的
G值中的14 和10是怎么算出来的
H值 为什么要乘 10
麻烦了~

sunbright
[ 2010-01-05 09:14:40 ]
G值:4个正方向记作10,4个斜方向记作14
H值:这是一种叫曼哈顿方法的计算方式,当然这也是比较简单的计算方式
游客*
[ 2010-01-05 18:36:44 ]
谢谢lz~~~
dongyi05*
[ 2010-05-07 14:57:29 ]
关于多个NPC在移动中重叠的问题,我想这样可以解决:将每个NPC占的位置都当作障碍物来算,寻完路后,走路时也要判断下一格是否有其它NPC占着,有的话就停顿一次移动,再判断是否被还被占着,不被占着就可以继续走路了,如果判断N次都被占着就要重新寻路。
sunbright
[ 2010-05-07 16:46:54 ]
是个好办法~
游客*
[ 2010-07-01 11:48:35 ]
[表情01] [表情02] [表情03] [表情04] [表情05] [表情06] [表情07] [表情08] [表情09] [表情10] [表情11] [表情12] [表情13] [表情14] [表情15] [表情16] [表情17] [表情18] [表情19] [表情20] [表情21] [表情22] [表情23] [表情24]
回复nihao以及博主*
[ 2010-08-08 14:53:19 ]
多人寻路没有那么简单的,高效率的寻路,并不是简单的碰撞检测,然后重新寻找可以办到的,尽管通常可以这样用。这样的话,即使重新寻路,由于其他人位置也变了,很可能再次碰撞,而且随人数增多,会变得非常可能,造成队伍行走缓慢。再者就是形成死锁,几个人下一步的行动会将对方的路封死,造成明明有路,谁也出不去的情况。目前大部分情况会规定人数上限,能自己编辑地图的游戏(比如暴雪的即时战略的那2个),相信玩过很多编辑出来的有大量兵海场景的rpg地图大都见过这种情况吧。
这个问题至尽仍旧没有被彻底解决。
sunbright
[ 2010-08-08 19:08:58 ]
这个要看具体情况的,如果涉及量很大,当然要做优化啦,像我现在用了寻路的项目,或多或少做了些优化,不过看具体需求来做就行了。上面文章讲解的寻路算法,不过是入门罢了,要想到一定程度还有很多路要走啊。

发表
表情图标
[表情01] [表情02] [表情03] [表情04] [表情05] [表情06] [表情07] [表情08] [表情09] [表情10] [表情11] [表情12] [表情13] [表情14] [表情15] [表情16] [表情17] [表情18] [表情19] [表情20] [表情21] [表情22] [表情23] [表情24]
UBB代码
转换链接
表情图标
悄悄话
昵称:   验证码: *
 
快速浏览
类别
标题
评论/流量
日期