package { import flash.display.Sprite; public class AStar extends Sprite { private var _open:Array;//开放列表 private var _closed:Array;//封闭列表 private var _grid:Grid; private var _endNode:Node;//终点 private var _startNode:Node;//起点 private var _path:Array;//最终的路径节点 // private var _heuristic:Function = manhattan; // private var _heuristic:Function = euclidian; private var _heuristic:Function=diagonal; //估计公式 private var _straightCost:Number=1.0; //直线代价 private var _diagCost:Number=Math.SQRT2; //对角线代价 public function AStar() { } //判断节点是否开放列表 private function isOpen(node:Node):Boolean { for (var i:int=0; i < _open.length; i++) { if (_open[i] == node) { return true; } } return false; } //判断节点是否封闭列表 private function isClosed(node:Node):Boolean { for (var i:int=0; i < _closed.length; i++) { if (_closed[i] == node) { return true; } } return false; } //对指定的网络寻找路径 public function findPath(grid:Grid):Boolean { _grid=grid; _open=new Array(); _closed=new Array(); _startNode=_grid.startNode; _endNode=_grid.endNode; _startNode.g=0; _startNode.h=_heuristic(_startNode); _startNode.f=_startNode.g + _startNode.h; return search(); } //计算周围节点代价的关键处理函数 public function search():Boolean { var _t:uint =1; var node:Node=_startNode; //如果当前节点不是终点 while (node != _endNode) { //找出相邻节点的x,y范围 var startX:int=Math.max(0, node.x - 1); var endX:int=Math.min(_grid.numCols - 1, node.x + 1); var startY:int=Math.max(0, node.y - 1); var endY:int=Math.min(_grid.numRows - 1, node.y + 1); //循环处理所有相邻节点 for (var i:int=startX; i <= endX; i++) { for (var j:int=startY; j <= endY; j++) { var test:Node=_grid.getNode(i, j); //如果是当前节点,或者是不可通过的,且排除水平和垂直方向都是障碍物节点时的特例情况 if (test == node || !test.walkable || !_grid.getNode(node.x, test.y).walkable || !_grid.getNode(test.x, node.y).walkable) { continue; } var cost:Number=_straightCost; //如果是对象线,则使用对角代价 if (!((node.x == test.x) || (node.y == test.y))) { cost=_diagCost; } //计算test节点的总代价 var g:Number=node.g + cost * test.costMultiplier; var h:Number=_heuristic(test); var f:Number=g + h; //如果该点在open或close列表中 if (isOpen(test) || isClosed(test)) { //如果本次计算的代价更小,则以本次计算为准 if (f