《AdvancED ActionScript 3.0 Animation》读书笔记(3) —— A星寻路

public class Grid

{

private var _startNode:Node;

private var _endNode:Node;

private var _nodes:Array;

private var _numCols:int;

private var _numRows:int;


/**

* Constructor.

*/

public function Grid(numCols:int, numRows:int)

{

_numCols = numCols;

_numRows = numRows;

_nodes = new Array();

for(var i:int = 0; i < _numCols; i++)

{

_nodes[i] = new Array();

for(var j:int = 0; j < _numRows; j++)

{

_nodes[i][j] = new Node(i, j);

}

}

}

////////////////////////////////////////

// public methods

////////////////////////////////////////

/**

* Returns the node at the given coords.


* @param x The x coord.

* @param y The y coord.

*/

public function getNode(x:int, y:int):Node

{

return _nodes[x][y] as Node;

}

/**

* Sets the node at the given coords as the end node.

* @param x The x coord.

* @param y The y coord.

*/

public function setEndNode(x:int, y:int):void

{

_endNode = _nodes[x][y] as Node;

}

/**

* Sets the node at the given coords as the start node.

* @param x The x coord.

* @param y The y coord.

*/

public function setStartNode(x:int, y:int):void

{

_startNode = _nodes[x][y] as Node;

}

/**

* Sets the node at the given coords as walkable or not.

* @param x The x coord.

* @param y The y coord.

*/

public function setWalkable(x:int, y:int, value:Boolean):void

{

_nodes[x][y].walkable = value;

}

////////////////////////////////////////

// getters / setters

////////////////////////////////////////

/**

* Returns the end node.

11

*/

public function get endNode():Node

{

return _endNode;

}

/**

* Returns the number of columns in the grid.

*/

public function get numCols():int

{

return _numCols;

}

/**

* Returns the number of rows in the grid.

*/

public function get numRows():int

{

return _numRows;

}

/**

* Returns the start node.

*/

public function get startNode():Node

{

return _startNode;

}

}



===============================


public class Node

{

public var x:int;


public var y:int;

public var f:Number;

public var g:Number;

public var h:Number;

public var walkable:Boolean = true;

public var parent:Node;

public var costMultiplier:Number = 1.0;

public function Node(x:int, y:int)

{

this.x = x;

this.y = y;

}

}



===================================


public class AStar

{

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()

{

}


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 node:Node = _startNode;

while(node != _endNode)

{

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;

}

var g:Number = node.g + cost * test.costMultiplier;

var h:Number = _heuristic(test);

var f:Number = g + h;

14

if(isOpen(test) || isClosed(test))

{

if(test.f > f)

{

test.f = f;

test.g = g;

test.h = h;

test.parent = node;

}

}

else

{

test.f = f;

test.g = g;

test.h = h;

test.parent = node;

_open.push(test);

}

}

}

for(var o:int = 0; o < _open.length; o++)

{

}

_closed.push(node);

if(_open.length == 0)

{

trace("no path found");

return false

}

_open.sortOn("f", Array.NUMERIC);

node = _open.shift() as Node;

}

buildPath();

return true;

}


==================================


private function euclidian(node:Node):Number

{

var dx:Number = node.x - _endNode.x;

var dy:Number = node.y - _endNode.y;

return Math.sqrt(dx * dx + dy * dy) * _straightCost;

}


原文地址:https://www.cnblogs.com/cly84920/p/4426488.html