基于哈希表数据源的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.IAstartSourceMode
import astart.interfaces.IAstart

public 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:Point
private var endPoint:Point

private var colsePath:Array;
private var colseArray:Array;
private var openPath:Array;
private var openArray:Array;
private var pathArray:Array
private 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=startPoint
this.endPoint=endPoint
this.source=source
this.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+G
var 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]=data
this.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+G
var 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]=data
this.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.x
var y:int=data.keyPoint.y

var 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 Array

var 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=0
this.nonce=null
this.canTL=true
this.canTR=true
this.canBL=true
this.canBR=true
this.isFinish=true
}
}
}





/**
*A星寻路的数据存储单位
* by 吾系衰人/wxsr
*@2008
*/
package astart.AstarData
{
import astar.interfaces.IAstarData;

public class AstarData implements IAstarData
{
private var _key:String
private var _keyPoint:Point
private var _G:int=0;
private var _F:int=0;
private var _parent:AstarData
private var _type:int
public 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:Point
private var _key:String
private var _type:int
public function AstartSourceMode(keyPoint:Point,type:int)
{
this._keyPoint=keyPoint
this._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;
}

}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值