Astar算法详解文档格式.docx
- 文档编号:20873373
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:17
- 大小:20.90KB
Astar算法详解文档格式.docx
《Astar算法详解文档格式.docx》由会员分享,可在线阅读,更多相关《Astar算法详解文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
return14+Father_int;
//返回父节点的带价值和当前节点到开始节点值等于一路走过来的带价值
}else{
returnMath.abs(h-Start_node.h)*10+Math.abs(l-Start_node.l)*10+Father_int;
//同上
//返回从开始节点到当前节点的移动代价
//G函数比H函数多了一点,就是计算斜角的代价,但是,记住,这个斜角只是当前节点的左上,左下,右上,右下的那一格,那么如何来计算是否是斜角呢?
其实只要计算当前行减去父节点和列减去父节点的列是否都等于1,这里也一样需要取绝对值,如果都为1则说明不在同一行也不在同一列,Father_int是什么呢?
是父节点的代价,G函数计算的是当前的代价还要加上父节点的代价,才能算出开始节点到当前节点的总代价,到了这里A*逻辑部分已经完成一大半了,最后我们还需要将找到的路径保存进一个数组里,看下面代码:
publicfunctiongetPath():
Array{
if(Father_node==this){
varccc:
Array=newArray();
ccc=[[h,l]];
returnccc;
varaa:
Array=Father_node.getPath();
varanswer:
Array=aa.slice(0,aa.length);
answer[aa.length]=[h,l];
returnanswer;
太少了,对,就是这么简单啦,首先我们检测目标节点的父节点是否等于自己,等于自己说明达到了起点,因为起点是没有父节点的,所以我们就设为是自己,好,先就此打住,看看下面的else,这里我们用了递归来寻找节点,首先我们新建立一个数组等于父节点返回的节点,然后在把它拷贝一份进新的输入,因为FLASH的数组是动态的,所以我们直接在尾部answer[aa.length]添加进当前节点的行和列,最后返回,直到返回到父节点也把自己的坐标返回了,整个递归调用结束,最后我们需要知道我们是否已经找到目标了,其实我们就可以直接判断当前的节点是否是目标节点:
publicfunctionequals(me:
Object):
Boolean{
if(meisnode){
if(me.h==h&
me.l==l){
returntrue;
returnfalse;
对啊,就是判断行和列就OK啦,这个方法如果返回真了就是找到了,如果返回假就说明没找到,
自此整个节点核心算法完毕,
下面是整个节点类:
package{
publicclassnode{
publicvarh:
int;
publicvarl:
publicvarFather_node:
node;
publicvarGoal_node:
publicvarStart_node:
publicvarFather_int:
publicfunctionnode(h:
int,l:
int,Father_node:
node,Goal_node:
node,Start_node:
node){
this.h=h;
//接受行
this.l=l;
//接受列
this.Father_node=Father_node;
//接受父类节点
this.Goal_node=Goal_node;
//接受目标节点
this.Start_node=this.Father_node;
//接受开启节点
if(Father_node==null){
this.Father_node=this;
if(Goal_node==null){
this.Goal_node=this;
if(Start_node==null){
this.Start_node=this;
//如果没有,则等于自己(用于起点和重点)
if(Start_node!
=null){
Father_int=Start_node.getG();
//获得父类节点的代价
publicfunctiongetH():
publicfunctiongetG():
publicfunctiongetF():
returngetH()+getG();
publicfunctionequals(me:
publicfunctiongetPath():
好了,节点我们搞定了,剩下的就是探路器的问题了(Find),那么我们的探路器的工作主要是负责,摆放节点到各个节点,那么这里我们需要知道什么位置需要放什么位置不需要,比如放过节点的位置当然就不需要了,呵呵,然后探路器会分析哪个节点返回的代价最少,最后当探路器找到目标之后会把整个路径返回出去,那么说到这里了,我们不得不说下列表问题,探路器是通过列表来选择是否放置节点,一共有2个,开启列表和关闭列表,首先,我们得知道,被放置的节点是否在某个列表里,如下函数:
publicfunctiondetection_listing(h:
int,vec:
Array):
node{
for(vari:
int=0;
i<
vec.length;
i++){
varmc:
node=vec[i];
if(h==mc.h&
l==mc.l){
returnmc;
returnnull;
//检测是否在列表里(检测当前行当前列是否与开启列表里的元素一样)
现在我们只要把列表(数组)丢进去再丢行和列就好了,再下来,我们需要知道斜角的地方是否有障碍物,如下函数:
publicfunctionbianyuan(h:
int,hh:
int,ll:
int,map:
if(hh-1==h&
ll-1==l){
if(map[h][l+1]==1||map[h+1][l]==1){
//trace("
左上"
)
}elseif(hh-1==h&
ll+1==l){
if(map[h][l-1]==1||map[h+1][l]==1){
右上"
}elseif(hh+1==h&
if(map[h-1][l]==1||map[h][l+1]==1){
左下"
if(map[h][l-1]==1||map[h-1][l]==1){
右下"
}
returntrue
//判断当前节点的斜角上周围是否有障碍物
我们需要丢一个行和列进去,然后再丢另一组行和列进去,然后是地图,判断第一组的行和列在第二组的行和列的什么位置,最后再判断是否有障碍物.if(map[h][l-1]==1||map[h-1][l]==1),这里我设置障碍物是1,再后来,我们需要知道是否找不到路:
if(Start_listing.length==0&
Current_node.equals(Goal_node)==false){
trace("
没有路了"
kaishi=false
嗯,开启列表已经没有东西了,但是路径返回返回假,就说明寻路失败,我这里设置了一个布尔值为假:
好了,辅助函数都写好了,关键时刻到了,现在我们需要使用探路,探测身边周围的8个点,方法如下:
for(varj:
int=-1;
j<
2;
j++){
for(vark:
k<
k++){
对,2个for循环,看看,当前节点的行加上J,和当前节点的列加上K,是否就是当前节点周围的8个点,好了,下面是上面的函数的完整应用:
publicfunctionaido(map:
Array){
if(shanchu.length!
=0){
for(vart:
t<
shanchu.length;
t++){
shanchu[t]=null;
删除了"
//如果删除列表不为空,则删除里面所有元素,等待系统回收
shanchu=newArray();
//初始化删除列表
Start_listing=newArray;
//开启列表
Stop_listing=newArray;
//关闭列表
Start_listing.push(Start_node);
//把当前节点放入开启列表
shanchu.push(Start_node);
//把当前节点放入删除列表
do{
Current_node=Start_listing[0];
//获取开启列表的第一个元素
int=1;
i<
Start_listing.length;
if(Start_listing[i].getF()<
Current_node.getF()){
Current_node=Start_listing[i];
//比较数组里的元素,如果数组里的元素的F值比当前的小,则把当前的替换成数组里的
if(Current_node.equals(Goal_node)){
找到路了"
);
fruit=Current_node.getPath();
kaishi=true
break
//是否找到路径
Stop_listing.push(Current_node);
//添加当前节点到关闭列表
Start_listing.splice(Start_listing.indexOf(Current_node),1);
//删除开始列表把当前节点从
for(varj:
//遍历当前节点周围的位置
if(Current_node.h+j==0&
Current_node.l+k==0){
continue;
if(Current_node.h+j>
=map.length||Current_node.h-j<
0){
if(Current_node.l+k>
=map[0].length||Current_node.l-k<
//判断是否遍历到了自己,是否超出了边界,如果是,则返回出去,重新遍历
if(bianyuan(Current_node.h+j,Current_node.l+k,Current_node.h,Current_node.l,map)&
detection_fraise(Current_node.h+j,Current_node.l+k,map)&
detection_border(Current_node.h+j,Current_node.l+k,map)&
detection_listing(Current_node.h+j,Current_node.l+k,Stop_listing)==null){
//如果周边的节点不在关闭列表里,是不是障碍物,斜角的周边是否有障碍物
About_node=detection_listing(Current_node.h+j,Current_node.l+k,Start_listing);
//判断周边的节点,传递行,列,开启列表
//如果当前对象在开启列表里,则函数会返回空,如果不在,则会创建新的节点
if(About_node==null){
//如果为空则不用多说了,像病毒一样扩散开来
About_node=newnode(Current_node.h+j,Current_node.l+k,Current_node,Goal_node,Current_node);
//初始化节点,传递行,列,父节点(当前的节点),目标节点(上面当鼠标点击时6了一个),开始节点(游戏运行时6了一个)
Start_listing.push(About_node);
shanchu.push(About_node);
//如果周边的节点为空,则在周边扩散节点,将扩散的节点放入开启列表,以备下次检测需要,也放入删除列表,待找到路径后删除删除列表里所有的节点,等待系统回收
varoldG:
int=About_node.getG();
//保存零时变量为开启列表里的G值
varFather:
node=About_node.Father_node;
//保存开启列表里的父节点
About_node.Father_node=Current_node;
//替换开启列表里的父节点为当前节点
if(About_node.getG()>
=oldG){
被替换了"
//比较被替换父节点的开启列表里的节点的值是否大于最开始的G值
About_node.Father_node=Father;
//如果大于则,被替换的开启列表里的节点的父节点又被送了回来给与了开启列表里的节点
//如果周边节点移动的代价比当前节点移动的代价要少的话,就替换当前节点的父节点,递归路径时遍会递归到最短路径的父类
}while(Start_listing.length!
=0);
//如果开启列表为空,停止寻路
if(Start_listing.length==0&
首先,我们定义了一个寻路函数,只接收地图,然后我们初始化了开启列表和关闭列表,最后将当前节点放入开启列表和关闭列表,其实我们就是把起点放进去,仔细看,这个动作是在for循环外面,既然是寻路,所以我们要有个开头,对吧,最后我们用do...while()
循环来执行核心部分,在开始部分,我们先来了一次冒泡排序,就是找出开启列表里代价最小的节点,然后让零时节点等于这个节点,然后再比较,这个节点是否是目标节点,如果是,则找到路径,返回路径,如果不是,继续,只要是检测过的节点,都不需要再检测,所以我们把当前节点放入关闭列表,同时也在开启列表里删除当前节点,最后,我们通过for循环,检测当前节点周围的8个点,判断如果超出了边界则放弃掉,进行下一次循环,然后再判断当前节点是否不在关闭列表里,旁边是否有障碍物,自己本上是否是障碍物,如果都没有,则检测是否在开启列表里,如果也不在开启列表里,则放置节点到当前的点上,把当前的点放入开启列表,等待下一次的循环检测,如果在开启列表里,则检测开启列表里的G指是否小于当前的G值,如果小于,则替换父节点,因为递归寻路是通过父节点的坐标,我们需要保证我们找到的路径是最短的,如果开启列表不为空,则继续循环,好,至此整个探路器核心介绍完毕,下面是完整代码:
publicclassFind{
privatevarh:
privatevarl:
privatevarfruit:
Array;
//路径数组
privatevarStart_listing:
privatevarStop_listing:
//目标节点
//开始节点
publicvarCurrent_node:
//当前节点
publicvarFairly_node:
//比较节点
publicvarAbout_node:
//零时节点
privatevarshanchu:
staticpublicvarkaishi:
Boolean
publicfunctionAIdo(h:
Goal_node=newnode(hh,ll,null,null,null);
Start_node=newnode(h,l,null,Goal_node,null);
aido(map);
//开始寻路
returnfruit;
//返回寻路后的结果数组
publicfunctionaido(map:
Curr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Astar 算法 详解
![提示](https://static.bdocx.com/images/bang_tan.gif)