游戏教程吧 关注:159贴子:113
  • 0回复贴,共1

基于哈希表数据源的A星寻路算法 - [as 3.0]

取消只看楼主收藏回复

在这贴的代码是为了有需要的人学习而不是 提供源码给别人用的所以大家见谅。这个算法没有跟传统的2维数组作为存储容器,而用哈希表,这样做的好处在于查询跟修改的速度要比2维数组的快而且方便。
package astart.interfaces{ public interface IAstartSourceMode { /** *对应数据源的方格的id * @return * */ function get keyPoint():Point /** *对应数据源的方格的id 的字符串形式(如 var keyPoint=new Point(x,y),则key应为 "x,y" ) * @return * */ function get key():String /** * 对应数据源的方格的类型 0为非可走区域 * @return * */ function get type():int }}
//////////////////////////////////////////////////////
package astart.interfaces{ import flash.geom.Point; public interface IAstarData { function get key():String function get keyPoint():Point function get G():int; function get F():int; function get parent():IAstarData function get type():int function set key(val:String):void function set keyPoint(val:Point):void function set G(val:int):void; function set F(val:int):void; function set parent(val:IAstarData):void function set type(val:int):void }}
////////////////////////////////////////////////////////////////////////
package astart.interfaces{ import flash.geom.Point; public interface IAstar { /** * 返回结果路径 * @param source 以IAstartSourceMode接口所实现的vo类的实例为键值的数组对象 查询key必须为 *IAstartSourceMode接口所实现的vo类的key属性对应 * @param startPoint 开始点,如:new Point (1,2)队形数据源 * @param endPoint 结束点 如:new Point(4,5)对应数据源 * @return * */ function getPath(source:Array,startPoint:Point,endPoint:Point):Array }}
///////////////// /////以上是接口文件////////////////////////////////
//////////////////////////////下边是具体实现///////////////////////////////////////////***实现数据源以对象形式的A星寻路* by 吾系衰人/wxsr*@2008*/package astart.actualize{import flash.geom.Point;import astart.interfaces.IAstartSourceModeimport astart.interfaces.IAstartpublic class Astar implements IAstar{private static const COST_STRAIGHT :int=10;private static const COST_DIAGONAL :int=14;private static const DIR_TC:String=*tc*;private static const DIR_CT:String=*ct*;private static const DIR_CR:String=*cr*;private static const DIR_BC:String=*bc*;private var nonce:AstarData;private var isFinish:Boolean;private var G:int;private var source:Array;private var startPoint:Pointprivate var endPoint:Pointprivate var colsePath:Array;private var colseArray:Array;private var openPath:Array;private var openArray:Array;private var pathArray:Arrayprivate var canTL:Boolean;private var canTR:Boolean;private var canBL:Boolean;private var canBR:Boolean;public function Astar(){}/***寻路
* @param source 数据源* @param startPoint 当前开始
* @param endPoint* @param cell* @return**/ public function getPath(source:Array,startPoint:Point,endPoint:Point):Array{reSet()this.startPoint=startPointthis.endPoint=endPointthis.source=sourcethis.nonce==null?
this.nonce=new AstarData(0,0,this.startPoint):**;this.nonce.parent=this.nonce;this.colseArray.push({F:this.nonce.F,data:this.nonce})this.colsePath[this.nonce.key]=this.colseArray[0]while(this.isFinish)
{getScale9Grid(source,this.nonce,this.endPoint)}return cleanArray()}//评分
private function getDis(point:Point,endPoint:Point):int{var dix:int=Math.abs(endPoint.x-point.x)var diy:int=Math.abs(endPoint.y-point.y)return Math.abs(dix+diy)}//获取当前评分最优对象垂直线对象private function stratght(tar:IAstartSourceMode,endPoint:Point,type:String):void{if(tar!=null){if(tar.type>0){var costH:int=getDis(tar.keyPoint,endPoint)*10;var costG:int=COST_STRAIGHT+Gvar data:AstarData=new AstarData(costG,(costG+costH),tar.keyPoint);data.parent==null?
data.parent=this.nonce:**if(openPath[tar.key]==null&&this.colsePath[tar.key]==null)
{openPath[tar.key]=datathis.openArray.push({F:data.F,data:data})}else if(openPath[tar.key]!=null){var old:AstarData=openPath[tar.key]data.F<old.F?openPath[tar.key]=data:**}}else {if(type==DIR_TC)
{this.canTL=false;this.canTR=false;}else if(type==DIR_CT)
{this.canTL=false;this.canBL=false;}else if(type==DIR_CR)
{this.canTR=false;this.canBR=false;}else if(type==DIR_BC){this.canBL=false;this.canBR=false;}}}}//获取当前评分最优对象对角线对象
private function diagonal(tar:IAstartSourceMode,endPoint:Point,can:Boolean):void{if(can&&tar!=null){if(tar.type>0)
{var costH:int=getDis(tar.keyPoint,endPoint)*10;var costG:int=COST_DIAGONAL+Gvar data:AstarData=new AstarData(costG,costG+costH,tar.keyPoint);data.parent==null?
data.parent=this.nonce:**if(openPath[tar.key]==null&&colsePath[tar.key]==null)
{openPath[tar.key]=datathis.openArray.push({F:data.F,data:data})}else if(openPath[tar.key]!=null)
{var old:AstarData=openPath[tar.key]data.F<old.F?openPath[tar.key]=data:**}}}}//获取当前评分最佳对象
private function getScale9Grid(source:Array,data:AstarData,endPoint:Point):void{this.canBL=true;this.canBR=true;this.canTL=true;this.canTR=true;var x:int=data.keyPoint.xvar y:int=data.keyPoint.yvar tc:IAstartSourceMode=source[x+*,*+(y-1)];var ct:IAstartSourceMode=source[(x-
1)+*,*+y]var cr:IAstartSourceMode=source[(x+1)+*,*+y]var bc:IAstartSourceMode=source[x+*,*+(y+1)]var tl:IAstartSourceMode=source[(x-1)+*,*+(y-1)];var tr:IAstartSourceMode=source[(x+1)+*,*+(y-1)];var bl:IAstartSourceMode=source[(x-1)+*,*+(y+1)]var br:IAstartSourceMode=source[(x+1)+*,*+(y+1)]stratght(tc,endPoint,DIR_TC)stratght(ct,endPoint,DIR_CT)stratght(cr,endPoint,DIR_CR)stratght(bc,endPoint,DIR_BC)diagonal(tl,endPoint,canTL)diagonal(tr,endPoint,canTR)diagonal(bl,endPoint,canBL)diagonal(br,endPoint,canBR)openArray.sortOn(*F*,Array.NUMERIC);if(this.openArray[0]==null){this.isFinish=false ;return}else {this.nonce=this.openArray[0].data;delete this.openPath[this.openArray[0].key];this.openArray.shift()if(this.colsePath[this.nonce.key]==null){this.colseArray.unshift({F:this.nonce.F,data:this.nonce})this.colsePath[this.nonce.key]=this.colseArray[0]}this.G=this.nonce.G}if(this.nonce.keyPoint.x==endPoint.x&&this.nonce.keyPoint.y==endPoint.y){this.isFinish=false;}return}//返回最后路径private function cleanArray():Array{this.pathArray=new Arrayvar key:String=String(this.endPoint.x+*,*+this.endPoint.y);if(this.colsePath[key]!=null){this.pathArray.push(this.colsePath[key].data.parent.keyPoint);this.pathArray.push(this.colsePath[key].data.keyPoint);while(true){key=String(this.colsePath[key].data.parent.key);if(key==String(this.startPoint.x+*,*+this.startPoint.y))break; var item:IAstartSourceMode=this.source[key]this.pathArray.unshift(this.colsePath[key].data.parent.keyPoint)}}return this.pathArray}// 初始化数组 private function reSet() : void{this.pathArray=[]this.source = [];this.colsePath = [];this.colseArray=[]this.openPath = [];this.openArray=[]this.G=0this.nonce=nullthis.canTL=truethis.canTR=truethis.canBL=truethis.canBR=truethis.isFinish=true}}}/////////////////////////////////////////////////////////////////////////////////////////////***A星寻路的数据存储单位* by 吾系衰人/wxsr*@2008*/package astart.AstarData{import astar.interfaces.IAstarData;public class AstarData implements IAstarData{private var _key:Stringprivate var _keyPoint:Pointprivate var _G:int=0;private var _F:int=0;private var _parent:AstarDataprivate var _type:intpublic function AstarData(g:int,f:int,keyPoint:Point){this._G=g;this.F=f;this.keyPoint=keyPoint}public function get key():String{return this._key;}public function get keyPoint():Point{return this._keyPoint;}public function get G():int{return this._G;}public function get F():int{return this._F;}public function get parent():IAstarData{return this._parent;}public function get type():int{return this._type;}public function set key(val:String):void{this._key=val}public function set keyPoint(val:Point):void{this.keyPoint=val}public function set G(val:int):void{this._G=val}public function set F(val:int):void{this._F=val}public function set parent(val:IAstarData):void{this._parent=val}public function set type(val:int):void{this._type=val}}}//////////////////////////////////////////////////////////////////////////***A星寻路的哈希表数据源的查询key为该类属性的key值,键值为该对象实例*如:source:Array=[]*source["1,2"]=new AstartSourceMode (new keyPoint(1,2),1);*source["-1,-2"]=new AstartSourceMode (new keyPoint(-1,-2),1)*source["2,-3"]=new AstartSourceMode (new keyPoint(2,-3),0)*然后以此source为参数 传递给Astart* by 吾系衰人/wxsr*@2008*/package astar.actualize{import flash.geom.Point;import astar.interfaces.IAstartSourceMode;public class AstartSourceMode implements IAstartSourceMode{private var _keyPoint:Pointprivate var _key:Stringprivate var _type:intpublic function AstartSourceMode(keyPoint:Point,type:int){this._keyPoint=keyPointthis._key=String(this._keyPoint.x+*,*+this._keyPoint.y)this._type=type}public function get keyPoint():Point{return _keyPoint;}public function get key():String{return this._key;}public function get type():int{return this._type;}}}


1楼2014-08-13 15:24回复