- 浏览: 87169 次
- 性别:
- 来自: 龙城
最新评论
-
Fis:
阿呆jinsss 写道 楼主说的简单易懂,最适合我这些理解能力 ...
[原创]AS3.0的自定义事件 -
阿呆jinsss:
楼主说的简单易懂,最适合我这些理解能力差点的人,谢谢了~
[原创]AS3.0的自定义事件 -
Fis:
mengxiaolongcz 写道外层循环 i<arr. ...
去除数组中相同的元素 -
Fis:
mengxiaolongcz 写道外层循环 i<arr. ...
去除数组中相同的元素 -
mengxiaolongcz:
外层循环 i<arr.length-1
里层循环 var ...
去除数组中相同的元素
原创首发www.eb163.com,转载请保留出处 作者:iiacm (着火骷髅)
A*算法的思想很丰富,游戏中用来解决人物角色、敌人的寻路问题是相当不错的方法。以前玩帝国时代的时候,看到里面的士兵跑路的路径都是择优而行,感到很奇妙,后来才知道,那是A*算法的功劳。随着逐渐的学习,对这个算法更是无比的倾慕,一度听到这个名词,心中一股钦佩之情油然而生…… 于是一直都在寻找学习的方法,不断的看帖、搜索,终于,在jr高手发布的帖子(http://www.eb163.com/club/viewthread.php?tid=2458&highlight=%D1%B0%C2%B7)和超哥的启发下,写出了自己的A*例子,感谢他们给予的帮助,拿出来和大家一起分享一下。
演示地址:http://www.eb163.com/club/thread-11209-1-1.html
一、demo的结构
demo分为三个部分:MainClass文档类——构建一个二维地图,并调用A*寻路类寻路;AStar A*寻路算法类——提供了所有寻路时用到的方法函数;AStarGrid 节点数据类——为寻路过程提供中间的数据结构,引入这个类的对象可以剥离地图单元,寻路时操作节点数据对象替代直接操作地图单元,方便管理。具体代码:
二、A*寻路的步骤
起初看些关于A*寻路的文章的时候,都很混乱,因为对它的原理并不了解,甚至于越看越乱…… 不过,当搞清楚了它的原理及他的寻路步骤后,就会很好理解了。正如jr在帖子中提到的那样,寻路的流程分别为:
1、寻路的过程就是检验地图单元(或称为节点)的过程,算法是通过对周围地形的评价得到路径的。寻路前要准备一些东西,为寻路存放数据作准备,他们分别是:
1)一个开放列表:存放以检验过和待检验的节点
2)一个封闭列表:存放操作过的节点,只有被检验过并且具是最优评估值(后面会介绍)的节点才是操作过的节点,路径将通过遍历他们的父节点产生
3)当前操作节点:经检验,计算出的评估值最优的节点
4)评估值:也就是jr高手帖子中提到的 f=h+g,评估值 f 的函数等于—— h(水平和垂直方向距离的和)加上g(直线方向或45度方向的移动消耗)。h、g的值可以自己约定,只要都是一个数量级的就可以了,而且 g 值在直线方向上的消耗值一定要大于 45 度方向上的移动消耗,demo中沿用 h=10,g=10(直线),g=14(45度方向)
2、从起点开始,把起点首先放入封闭列表,将它的父节点设置为null,获取起点周围的节点,将这些周围节点也加开放列表,把他们的父节点设为起点,对开放列表中的节点进行检验,同时计算他们的 f、h、g 值,选择其中 f 值最小的为下一个操作节点,这样我们就有了下一个要操作的对象,把这个节点加入到封闭列表中去
3、获取当前操作节点周围的节点,将这些节点放到开放列表,这里以为开放列表中已经有元素了,得给这些要加入开放列表的“周围节点”作个判断:如果该“周围节点”已存在列表中的话就取消添加入列表的操作,然后看这个节点在经过当前操作节点的情况下的 g 值是否小于它原来的 g 值,如果小于,就把这个更小的 g 值更新到这个“周围节点”中,且把这个“周围节点”的父节点设置为当前操作节点;如果大于,则不作改动,继续检验下一个“周围节点”,检验完后再从这些“周围节点”中挑出 f 值最小的作下一个操作节点……如此反复作递归调用
4、重复步骤 3 中的内容,直到发现封闭列表中出现有终点,说明我们已经到达了终点,终止递归调用,开始路径回溯,即由终点开始,追寻他们的父节点,这些父节点都是在寻路的过程中以评估值最优为条件设置的,当找到父节点为null的节点,就说明已回到了起点,完成了整个寻路的过程
三、小结
好了,demo做完了,学习过程是痛苦的,但是得到成果的时候是喜悦的……在做的过程中,只要理解了寻路的步骤,把每步要用的功能封装好,各个环节就会清晰的暴露在视野中。 这个demo只展现了A*寻路中的一些原理,还没有加入障碍策略和绕路策略等机制,这在今后会不断的做出完善。顺带提提我的体会,寻路过程中允许穿越地图单元行走,所以会看到斜线的路径,这和检验的周围节点有关,如果不希望斜线行走,则在检验周围节点的时候不添加斜线方向的节点就成;若要做类似蜂窝型的不规则地图寻路,同样在检验周围节点上作修改就可以了。由于有了中间操作对象 AStarGrid 类,寻路类只关心传入的地图数据是什么样的,而不用关心实际地图的形状,这提高了寻路类的适应性。
A*算法的思想很丰富,游戏中用来解决人物角色、敌人的寻路问题是相当不错的方法。以前玩帝国时代的时候,看到里面的士兵跑路的路径都是择优而行,感到很奇妙,后来才知道,那是A*算法的功劳。随着逐渐的学习,对这个算法更是无比的倾慕,一度听到这个名词,心中一股钦佩之情油然而生…… 于是一直都在寻找学习的方法,不断的看帖、搜索,终于,在jr高手发布的帖子(http://www.eb163.com/club/viewthread.php?tid=2458&highlight=%D1%B0%C2%B7)和超哥的启发下,写出了自己的A*例子,感谢他们给予的帮助,拿出来和大家一起分享一下。
演示地址:http://www.eb163.com/club/thread-11209-1-1.html
一、demo的结构
demo分为三个部分:MainClass文档类——构建一个二维地图,并调用A*寻路类寻路;AStar A*寻路算法类——提供了所有寻路时用到的方法函数;AStarGrid 节点数据类——为寻路过程提供中间的数据结构,引入这个类的对象可以剥离地图单元,寻路时操作节点数据对象替代直接操作地图单元,方便管理。具体代码:
package{ /* iiacm(着火骷髅),网页游戏开发网 www.eb163.com 网页游戏互动社区 A*寻路算法启发性搜索 demo 文档类 */ import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; public class MainClass extends Sprite{ //设定地图单元行数 protected var rowNum:uint=22; //设定地图单元列数 protected var columnNum:uint=20; //设定地图单元宽度 protected var mcWidth:uint=25; //设定地图单元高度 protected var mcHeight:uint=20; //存储地图单元数据的数组 protected var mcArr:Array=new Array(); //声明一个A*寻路类的实例对象,把地图单元数据作为参数传入类的构造函数 protected var aStar:AStar=new AStar(mcArr); //当前起点 protected var nowPoint:Point=new Point(5,5); //当前终点 protected var endPoint:Point; public function MainClass(){ init(); } //初始化,创建地图 protected function init(){ createMcs(); } //根据行数列数创建地图,同时填充地图数据 protected function createMcs(){ for(var i:int=0; i<columnNum; i++){ mcArr[i]=new Array(); for(var j:int=0; j<rowNum; j++){ var sprite:Sprite=drawRect(); sprite.x=j*mcWidth; sprite.y=i*mcHeight; sprite.name="mc_"+i+"_"+j; mcArr[i].push(sprite); addChild(sprite); sprite.addEventListener(MouseEvent.CLICK, onClickSpriteHandler); } } } //为地图单元添加的鼠标点击事件处理函数,由起点到被点击地图单元的位置进行寻路,改变alpha属性对找到的路径标记 protected function onClickSpriteHandler(e:MouseEvent){ for(var i=0;i<mcArr.length;i++){ for(var j=0;j<mcArr[i].length;j++){ mcArr[i][j].alpha=1; } } endPoint=checkMapPos(e.currentTarget as Sprite); aStar.findPath(nowPoint, endPoint); nowPoint=endPoint; } //查找当前点击的地图单元,返回单元所在坐标 protected function checkMapPos(mapGrid:Sprite):Point{ var point:Point; for(var i=0;i<mcArr.length;i++){ for(var j=0;j<mcArr[i].length;j++){ if(mapGrid.name==mcArr[i][j].name){ point=new Point(i,j); break; } } } return point; } //绘制地图单元 protected function drawRect():Sprite{ var sprite:Sprite=new Sprite(); sprite.graphics.lineStyle(.25, 0x232323, 1); sprite.graphics.beginFill(0xffffff, 0.5); sprite.graphics.drawRect(0, 0, mcWidth, mcHeight); sprite.graphics.endFill(); return sprite; } } }
package{ /* iiacm(着火骷髅),网页游戏开发网 www.eb163.com 网页游戏互动社区 A*寻路类 使用A*算法实现自动寻找最佳路径功能 */ import flash.geom.Point; import flash.display.DisplayObject; public class AStar{ //封闭列表 protected var _closeList:Array=new Array(); //开放列表 protected var _openList:Array=new Array(); //地图节点数据 protected var _mapData:Array; //存储寻路结果的数组 protected var way:Array=new Array(); //起点节点 protected var _startNode:AStarGrid; //目标节点 protected var _targetNode:AStarGrid; //当前操作节点 protected var _nowNode:AStarGrid; //是否找到路径,起始值false,完成寻路后为true protected var _isFind:Boolean=false; //从起点起点沿着已生成的路径到给定节点的移动开销,直线方向为g=10,斜线方向为obliqueG=14 public var g:Number=10; public var obliqueG:Number=14; //从给定节点到目标节点的估计移动开销 public var h:Number=10; //允许寻找的方向,值为8时表示可以从8个方向寻找路线,即允许斜线行走 //public var direct:int=8; //构造函数,需要一个存储有地图节点数据的数组做参数 public function AStar(mapData:Array){ _mapData=mapData; } //启动寻路 public function findPath(startPos:Point, targetPos:Point):Array{ //设置起点、终点 _startNode=new AStarGrid(startPos.x, startPos.y, _mapData[startPos.x][startPos.y]); _targetNode=new AStarGrid(targetPos.x, targetPos.y, _mapData[targetPos.x][targetPos.y]); //在地图上标记出起点和终点 _startNode.mc.alpha=0; _targetNode.mc.alpha=0; //标记,设置起点为当前操作节点 _nowNode=_startNode; //设置起始节点的父节点为null setFather(_startNode, null); //重置寻路结果 way=new Array(); //计算起始节点的g, h, f值 countHG(_startNode); //将起始节点加入开放列表及封闭列表 addToOpen(_startNode); addToClose(_startNode); //获取起始节点周围节点 way=getAround(_startNode); //----------------------- return way; } //获取当前操作节点周围的节点,通过递归调用执行寻路过程 protected function getAround(centreNode:AStarGrid):Array{ //声明两个数组,分别存放当前操作节点周围的节点数据及对应的地图单元 var aroundArr:Array=new Array(); var aroundNodeArr:Array=new Array(); //将当前操作节点周围的非空节点、地图单元分别加入aroundNodeArr和aroundArr数组, if(centreNode.dC+1<_mapData[0].length){ aroundArr.push(_mapData[centreNode.dR][centreNode.dC+1]); aroundNodeArr.push(dataToGrid(centreNode.dR, centreNode.dC+1, aroundArr[0])); } if(centreNode.dC-1>=0){ aroundArr.push(_mapData[centreNode.dR][centreNode.dC-1]); aroundNodeArr.push(dataToGrid(centreNode.dR, centreNode.dC-1, aroundArr[1])); } if(centreNode.dR+1<_mapData.length){ aroundArr.push(_mapData[centreNode.dR+1][centreNode.dC]); aroundNodeArr.push(dataToGrid(centreNode.dR+1, centreNode.dC, aroundArr[2])); } if(centreNode.dR-1>=0){ aroundArr.push(_mapData[centreNode.dR-1][centreNode.dC]); aroundNodeArr.push(dataToGrid(centreNode.dR-1, centreNode.dC, aroundArr[3])); } if(centreNode.dR-1>=0 && centreNode.dC-1>=0){ aroundArr.push(_mapData[centreNode.dR-1][centreNode.dC-1]); aroundNodeArr.push(dataToGrid(centreNode.dR-1, centreNode.dC-1, aroundArr[4])); } if(centreNode.dR+1<_mapData.length && centreNode.dC+1<_mapData[0].length){ aroundArr.push(_mapData[centreNode.dR+1][centreNode.dC+1]); aroundNodeArr.push(dataToGrid(centreNode.dR+1, centreNode.dC+1, aroundArr[5])); } if(centreNode.dR-1>=0 && centreNode.dC+1<_mapData[0].length){ aroundArr.push(_mapData[centreNode.dR-1][centreNode.dC+1]); aroundNodeArr.push(dataToGrid(centreNode.dR-1, centreNode.dC+1, aroundArr[6])); } if(centreNode.dR+1<_mapData.length && centreNode.dC-1>=0){ aroundArr.push(_mapData[centreNode.dR+1][centreNode.dC-1]); aroundNodeArr.push(dataToGrid(centreNode.dR+1, centreNode.dC-1, aroundArr[7])); } //声明一个AStarGrid对象,存储在 aroundNodeArr 数组中具有f值最大的节点 var fMaxGrid:AStarGrid; //遍历 aroundNodeArr 数组,把数组中所有节点的父节点设为当前操作节点,计算他们的g, h, f值,并全部执行加入开放列表操作 for(var n:int=0; n<aroundArr.length; n++){ setFather(aroundNodeArr[n], centreNode); countHG(aroundNodeArr[n]); addToOpen(aroundNodeArr[n]); } //找出 aroundNodeArr 数组中具有f值最大的节点,存入 fMaxGrid 变量 for(var i:int=1; i<aroundNodeArr.length; i++){ for(var m:int=aroundNodeArr.length-1; m>=i; m--){ if(aroundNodeArr[m].f<aroundNodeArr[m-1].f){ var sNode:AStarGrid=aroundNodeArr[m-1]; aroundNodeArr[m-1]=aroundNodeArr[m]; aroundNodeArr[m]=sNode; } } } //设置当前操作节点为 f 值最大的节点,并将其加入封闭列表 _nowNode=aroundNodeArr[0]; addToClose(aroundNodeArr[0]); //判断 _isFind 的值确认是否完成寻路 var finishArr:Array=new Array(); if(!_isFind){ //否,则继续搜索当前节点的周围节点; getAround(_nowNode); }else{ //是,则输出路径 finishArr=getPath(); } return finishArr; } //由目标节点开始,回溯父节点,知道父节点为null,即完成路径的查找 protected function getPath():Array{ var pathArr:Array=new Array(); //判断如果起点与终点一致,则立刻返回路径,不一致就正常寻路 if(_targetNode.dR==_startNode.dR && _targetNode.dC==_startNode.dC){ pathArr.push(_targetNode); }else{ //完成寻路后,清空开放、封闭列表,为下次寻路做准备 var node:AStarGrid=_targetNode; pathArr.push(node); while(node.father!=null){ var f:AStarGrid=node.father; pathArr.push(f); _mapData[node.dR][node.dC].alpha=.4; node=node.father; } } pathArr[0].mc.alpha=0; _isFind=false; _closeList=new Array(); _openList=new Array(); _startNode=null; _targetNode=null; return pathArr; } //设置父节点 protected function setFather(sonNode:AStarGrid, fatherNode:AStarGrid){ sonNode.father=fatherNode; } //计算节点的 g, h, f值 protected function countHG(node:AStarGrid){ countH(node); countG(node); node.f=node.h+node.g; } //计算节点的 h 值 protected function countH(node:AStarGrid):uint{ var xH:uint=Math.abs(_targetNode.dR-node.dR)*h; var yH:uint=Math.abs(_targetNode.dC-node.dC)*h; var hValue:uint=xH+yH; node.h=hValue; return hValue; } //计算节点的 g 值 protected function countG(node:AStarGrid):uint{ var n:AStarGrid=node; var gValue:uint=0; if(n.father!=null){ while(n.father!=null){ var f:AStarGrid=n.father; if(f.dR==n.dR || f.dC==n.dC){ gValue+=g; }else{ gValue+=obliqueG; } n=n.father; } }else{ gValue=0; } node.g=gValue; return gValue; } //将节点加入开放列表 protected function addToOpen(addedNode:AStarGrid){ /*for(var i:int=0; i<_openList.length;i++){ if(_openList[i].dR==_targetNode.dR && _openList[i].dC==_targetNode.dC){ _isFind=true; setFather(_targetNode, addedNode); break; } } */ //判断加入开放列表的节点是否重复,重复则重新计算节点经由当前操作节点的 g 值,如果小于原来的 g 值,则将节点的父节点置为当前操作节点,否则取消加入开放列表 if(!_isFind){ for(var n:int=0; n<_openList.length; n++){ if(_openList[n].dR==addedNode.dR && _openList[n].dC==addedNode.dC){ var oldG:uint=addedNode.g; var newG:uint; if(_nowNode.dR==addedNode.dR || _nowNode.dC==addedNode.dC){ newG=_nowNode.g+g; }else{ newG=_nowNode.g+obliqueG; } if(newG<oldG){ setFather(addedNode, _nowNode); countHG(addedNode); }else{ } }else{ _openList.push(addedNode); } } }else{ } } //将节点加入封闭列表 protected function addToClose(addedNode:AStarGrid){ _closeList.push(addedNode); //判断目标节点是否在封闭列表中,在则将目标节点的父节点设为当前操作节点,寻路结束 for(var i:int=0; i<_closeList.length;i++){ if(_closeList[i].dR==_targetNode.dR && _closeList[i].dC==_targetNode.dC){ _isFind=true; setFather(_targetNode, addedNode); break; } } } //把节点转化为相应的地图单元 protected function gridToData(starGrid:AStarGrid):*{ return _mapData[starGrid.dR][starGrid.dC]; } //把地图单元转化为相应的节点 protected function dataToGrid(r:uint, c:uint, mc:DisplayObject):*{ return new AStarGrid(r, c, mc, null); } } }
package{ /* iiacm(着火骷髅),网页游戏开发网 www.eb163.com 网页游戏互动社区 A*寻路运算节点类 为寻路提供数据节点对象 */ import flash.display.DisplayObject; public class AStarGrid{ //节点的父节点 public var father:AStarGrid; //节点所在的行号 public var dR:uint; //节点所在的列号 public var dC:uint; //节点对应的地图单元 public var mc:DisplayObject; //从此节点到目标节点的估计移动开销 public var h:uint=0; //从起点起点沿着已生成的路径到此节点的移动开销 public var g:uint=0; //节点的移动开销,用来衡量此节点的路径优先度 public var f:uint=0; //构造函数,初始化节点的值 public function AStarGrid(dataR:uint=0, dataC:uint=0, displayObj:DisplayObject=null, father=null){ father=father; dR=dataR; dC=dataC; mc=displayObj; } } }
二、A*寻路的步骤
起初看些关于A*寻路的文章的时候,都很混乱,因为对它的原理并不了解,甚至于越看越乱…… 不过,当搞清楚了它的原理及他的寻路步骤后,就会很好理解了。正如jr在帖子中提到的那样,寻路的流程分别为:
1、寻路的过程就是检验地图单元(或称为节点)的过程,算法是通过对周围地形的评价得到路径的。寻路前要准备一些东西,为寻路存放数据作准备,他们分别是:
1)一个开放列表:存放以检验过和待检验的节点
2)一个封闭列表:存放操作过的节点,只有被检验过并且具是最优评估值(后面会介绍)的节点才是操作过的节点,路径将通过遍历他们的父节点产生
3)当前操作节点:经检验,计算出的评估值最优的节点
4)评估值:也就是jr高手帖子中提到的 f=h+g,评估值 f 的函数等于—— h(水平和垂直方向距离的和)加上g(直线方向或45度方向的移动消耗)。h、g的值可以自己约定,只要都是一个数量级的就可以了,而且 g 值在直线方向上的消耗值一定要大于 45 度方向上的移动消耗,demo中沿用 h=10,g=10(直线),g=14(45度方向)
2、从起点开始,把起点首先放入封闭列表,将它的父节点设置为null,获取起点周围的节点,将这些周围节点也加开放列表,把他们的父节点设为起点,对开放列表中的节点进行检验,同时计算他们的 f、h、g 值,选择其中 f 值最小的为下一个操作节点,这样我们就有了下一个要操作的对象,把这个节点加入到封闭列表中去
3、获取当前操作节点周围的节点,将这些节点放到开放列表,这里以为开放列表中已经有元素了,得给这些要加入开放列表的“周围节点”作个判断:如果该“周围节点”已存在列表中的话就取消添加入列表的操作,然后看这个节点在经过当前操作节点的情况下的 g 值是否小于它原来的 g 值,如果小于,就把这个更小的 g 值更新到这个“周围节点”中,且把这个“周围节点”的父节点设置为当前操作节点;如果大于,则不作改动,继续检验下一个“周围节点”,检验完后再从这些“周围节点”中挑出 f 值最小的作下一个操作节点……如此反复作递归调用
4、重复步骤 3 中的内容,直到发现封闭列表中出现有终点,说明我们已经到达了终点,终止递归调用,开始路径回溯,即由终点开始,追寻他们的父节点,这些父节点都是在寻路的过程中以评估值最优为条件设置的,当找到父节点为null的节点,就说明已回到了起点,完成了整个寻路的过程
三、小结
好了,demo做完了,学习过程是痛苦的,但是得到成果的时候是喜悦的……在做的过程中,只要理解了寻路的步骤,把每步要用的功能封装好,各个环节就会清晰的暴露在视野中。 这个demo只展现了A*寻路中的一些原理,还没有加入障碍策略和绕路策略等机制,这在今后会不断的做出完善。顺带提提我的体会,寻路过程中允许穿越地图单元行走,所以会看到斜线的路径,这和检验的周围节点有关,如果不希望斜线行走,则在检验周围节点的时候不添加斜线方向的节点就成;若要做类似蜂窝型的不规则地图寻路,同样在检验周围节点上作修改就可以了。由于有了中间操作对象 AStarGrid 类,寻路类只关心传入的地图数据是什么样的,而不用关心实际地图的形状,这提高了寻路类的适应性。
发表评论
-
LayaBox flash 转换项目心得
2015-08-28 13:50 4437一、熟悉从as3项目转到js的API和特性差异 1、Simpl ... -
Starling中AssetManager加载文件的流程整理
2015-06-16 20:15 1359Starling做移动开发,会用到大量的纹理和图片素材、X ... -
LayaBox flash 转换项目心得
2015-08-28 13:46 0一、熟悉从as3项目转到j ... -
air遍历目录里的文件
2015-02-12 15:52 926air开发移动应用时,用于遍历一个目录里的所有文件: var ... -
MovieClip 帧里面子对象为null 问题的解决
2014-10-11 17:19 818原因是进入其中一帧后,MovieClip对象不会立刻被创建出来 ... -
as3打包手机引用
2013-10-18 17:48 7661、新建手机项目 去掉其他平台选项 创建项目。 ... -
as3 ANE的打包小结
2013-10-18 15:15 2692工作关系要用到as3手游ANE的打包,之前因为用不到,也没 ... -
SWFLoader不响应Event.COMPLETE事件
2012-06-25 16:16 1212工作中遇到了一个问题,flex控件SWFLoader解决了 ... -
PHP中的生成XML文件的4种方法
2012-05-02 14:07 1037原文:http://www.oschina.net/code/ ... -
AS3 位运算
2012-04-17 13:04 916原文转至http://www.tangpei.net/2011 ... -
支持参数的事件处理函数
2012-04-11 14:44 3通常情况下,我们使用事件机制时,编写的事件处理函数只需要一 ... -
关于as3运动效果的总结
2012-03-22 18:18 1041看了《ActionScript3.0高级动画教程》一书,用 ... -
ActionScript3高级动画教程笔记
2012-03-14 17:09 7982012.3.14 基本三角函数的计算: 角的正弦值 = ... -
移除匿名函数定义的事件处理函数
2012-01-17 14:12 2772如果一个监听事件是匿名函数,那当要移除的时候就会有困扰,既 ... -
传参之事件代理
2012-01-17 14:04 710通常情况下,我们使用事件机制时,编写的事件处理函数只需要一 ... -
Flex Application初始化顺序
2012-01-14 17:54 1113preloader->systemManager-> ... -
换页显示代码
2011-12-20 15:55 910var maxPage:int = Math.ceil(t ... -
全数段取值显示
2011-12-16 22:19 751这个叫法是自己取的,工作中用到了,这里记录一下。 p ... -
as3开发社交游戏的一些总结
2011-07-13 17:57 1220加入社交游戏开发 ... -
抛物线运动公式总结
2011-05-24 20:53 8126竖直上抛运动: 初始化 t = 0; a = ...
相关推荐
A*寻路算法(A* Pathfinding Algorithm)是游戏开发、地图导航、机器人路径规划等领域广泛应用的一种高效路径搜索算法。它结合了Dijkstra算法的全局最优性和BFS(广度优先搜索)的效率,通过引入启发式函数来指导搜索,...
在这个"as3 A*寻路源码"中,我们可以深入理解A*算法的工作原理及其在ActionScript 3(AS3)中的实现。 A*算法的核心思想是结合了Dijkstra算法的全局最优性和最佳优先搜索的效率。它通过一个评估函数f(n)来指导搜索...
六边形A*寻路算法源码(As3版本)在六边形战棋类游戏中可以使用
A*(A-Star)寻路算法是路径规划领域中一种广泛应用的算法,它结合了Dijkstra算法的最短路径特性与优先级队列的效率优势。在Cocos Creator中,利用JavaScript实现A*寻路算法可以为游戏或交互式应用提供高效、智能的...
在AS3(ActionScript 3)这种面向对象的编程语言中实现A*寻路算法,可以为游戏开发、地图导航等场景提供强大的路径计算支持。 首先,我们来看A*算法的基本原理。A*算法通过评估每个节点的F值来决定搜索方向,F值由G...
A*(A-star)寻路算法是一种广泛应用在游戏开发、地图导航、机器人路径规划等领域的高效路径搜索算法。它结合了Dijkstra算法的全局最优性和Greedy最佳优先搜索的效率,通过引入启发式函数来估计从当前节点到目标节点...
3. **多目标寻路**:除了单个目标,PAStar可能还支持同时寻找多个目标的路径。 4. **可定制性**:算法可能允许用户自定义启发式函数,以适应不同场景的需求。 5. **优化的搜索算法**:PAStar可能采用了特定的优化...
标题 "A*寻路的AS实现例子" 指的是使用ActionScript(一种基于ECMAScript的脚本语言,常用于Adobe Flash开发)实现A*(A-star)寻路算法的一个示例项目。A*算法是一种广泛应用在路径规划中的启发式搜索算法,尤其在...
### A*寻路算法详解 #### 一、引言 A*寻路算法是一种广泛应用于游戏开发、机器人路径规划等领域的重要算法。它结合了最佳优先搜索策略与启发式搜索技术,能够有效地找到从起点到终点的最短路径。尽管A*算法在初次...
3. `AStar`类:核心算法实现,包括寻路函数和启发式函数。 4. `Path`类:表示从起点到终点的路径,可以是节点列表或者坐标序列。 源码分析时,我们需要关注以下几个关键点: - 如何建立节点间的连接,即邻接表的...
A*算法是自动寻路的理想解决办法 像自动寻找NPC 自动寻找地图出口 我写的这个只是简单的实现了功能 在运算效率上没有做优化 在接下来的版本中我会增加二*堆算法 来提高A*算法的效率 请大家多多关注 包中还有一个我用...
3. **AStar.cs**:这是A*寻路算法的具体实现。在这个文件中,你可以找到核心的搜索算法,包括节点的开放列表和关闭列表管理、F值(总成本)、G值(实际代价)和H值(启发式估计)的计算,以及最佳路径的回溯。 4. *...
下载本程序仅可演示A*自动寻路算法实现(java),该程序是基于我写的网络版贪吃蛇基础上编写的(网络版贪吃蛇...wasd键控制太阳的方向,鼠标左击目的地,会根据A*自动寻路算法计算出一条最优路线,太阳按最优路线移动。
《C# A*寻路算法在游戏中的应用与可视化演示》 在计算机科学尤其是游戏开发领域,路径规划是一项至关重要的技术。A*(A-Star)算法作为一种高效的寻路算法,被广泛应用于各种需要智能体寻找最短路径的问题中。本文...
A*(A-star)算法是一种广泛应用的路径搜索算法,它在自动寻路系统中起着核心作用。易语言是一种中国本土开发的、面向对象的编程语言,它以其简单易学的特点受到很多程序员的喜爱。这个“A*走路 自动寻路A*算法 ...
《CocosCreator A*自动寻路技术解析与实践》 在游戏开发中,角色的智能移动是至关重要的一环,这通常涉及到自动寻路系统。CocosCreator作为一个强大的2D游戏开发引擎,为开发者提供了丰富的工具和技术支持。本篇将...
A*寻路算法,提供顶点信息矩阵和移动消耗矩阵,返回最短路径顶点列表
**a*寻路算法**是一种广泛应用的路径搜索算法,它结合了Dijkstra算法的最短路径特性与启发式搜索的效率。在C++中实现a*寻路算法,通常会用到数据结构如二叉堆(优先队列)来优化性能。在此项目中,八方向的移动模型...