具体用法需要研究的同学看三个public入口就知道了。
- /**
- * @author hirokimo
- * @data 2006-05-03
- * @usage A*path searching
- */
- class Astar {
- private static var cost:Number = 10;
- private static var isSearching:Boolean = false;
- private static var broadcastInit = AsBroadcaster.initialize(Astar.prototype);
- public var addListener:Function;
- public var removeListener:Function;
- private var broadcastMessage:Function;
- private var path:Array;
- private var openList:Array;
- private var closeList:Array;
- private var map:Array;
- private var pointType:Array;
- private var directData:Array;
- //
- public function Astar() {
- path = new Array();
- pointType = new Array();
- openList = new Array();
- closeList = new Array();
- directData = new Array();
- map = new Array();
- initDirectData();
- }
- public function setMap(map_t:Array) {
- map = map_t;
- setPointType(map);
- }
- public function findPath(startX:Number, startY:Number, endX:Number, endY:Number) {
- initData();
- isSearching = true;
- var startPoint:Object = new Object();
- var endPoint:Object = new Object();
- var prePoint:Object = new Object();
- startPoint.X = startX;
- startPoint.Y = startY;
- endPoint.X = endX;
- endPoint.Y = endY;
- startPoint.parent = null;
- startPoint.G = 0;
- startPoint.H = manhattanDis(startPoint, endPoint);
- startPoint.F = startPoint.G+startPoint.H;
- prePoint = startPoint;
- //send2List(startPoint, openList);
- send2List(startPoint, closeList);
- while (isSearching == true) {
- for (var i = 0; i<directData.length; i++) {
- var tempPoint:Object = new Object();
- tempPoint.X = prePoint.X+directData[i][0];
- tempPoint.Y = prePoint.Y+directData[i][1];
- if (isOut(tempPoint) == true) {
- } else {
- if (tempPoint.Y == endPoint.Y && tempPoint.X == endPoint.X) {
- //found
- isSearching = false;
- send2List(tempPoint, closeList);
- tempPoint.parent = prePoint;
- tempPoint.G = prePoint.G+directData[i][2];
- tempPoint.H = manhattanDis(tempPoint, endPoint);
- tempPoint.F = tempPoint.G+tempPoint.H;
- //trace(closeList[closeList.length-1].X+" "+closeList[closeList.length-1].Y);
- //trace("path found!");
- drawPath();
- broadcastMessage("onPathFound");
- return;
- }
- if (getPointType(tempPoint) == "road" && isInList(tempPoint, closeList) == false) {
- //trace("四向之"+i+" tempPoint:"+tempPoint.X+" "+tempPoint.Y);
- //目标格不在关闭列表且是road
- if (isInList(tempPoint, openList) == false) {
- //目标格尚未开启
- send2List(tempPoint, openList);
- //trace("ol:"+openList[0].X+"=="+openList[0].Y);
- tempPoint.parent = prePoint;
- tempPoint.G = prePoint.G+directData[i][2];
- tempPoint.H = manhattanDis(tempPoint, endPoint);
- tempPoint.F = tempPoint.G+tempPoint.H;
- } else {
- //已经在开启列表中
- var tempG:Number = prePoint.G+directData[i][2];
- for (var j = 0; j<openList.length; j++) {
- if (tempPoint.X == openList[j].X && tempPoint.Y == openList[j].Y) {
- if (tempG<openList[j].G) {
- //现在的路径G更好
- openList[j].G = tempG;
- openList[j].F = openList[j].G+openList[j].H;
- openList[j].parent = prePoint;
- }
- break;
- }
- }
- }
- }
- }
- }
- if (openList.length == 0) {
- isSearching = false;
- broadcastMessage("onPathBlock");
- return;
- }
- sortList(openList);
- prePoint = openList.shift();
- send2List(prePoint, closeList);
- //trace(closeList[closeList.length-1].X+" "+closeList[closeList.length-1].Y);
- }
- }
- public function getPath():Array {
- path.reverse();
- trace("==========Path start===========");
- for (var i = 0; i<path.length; i++) {
- trace("path:"+path[i].X+path[i].Y);
- }
- trace("==========Path end ===========");
- return path;
- }
- private function initData():Void {
- openList = [];
- closeList = [];
- path = [];
- }
- private function drawPath() {
- //trace("set path");
- closeList.reverse();
- var currentPathPoint:Object = new Object();
- currentPathPoint = closeList[0];
- send2List(currentPathPoint, path);
- //trace(currentPathPoint.X+" "+currentPathPoint.Y);
- for (var i = 1; i<closeList.length; i++) {
- if (currentPathPoint.parent == null) {
- break;
- }
- //trace(currentPathPoint.parent.X+" "+currentPathPoint.parent.Y);
- send2List(currentPathPoint.parent, path);
- currentPathPoint = currentPathPoint.parent;
- }
- }
- private function getPointType(point_t:Object):String {
- return pointType[point_t.X][point_t.Y];
- }
- private function setPointType(map_t:Array) {
- for (var i = 0; i<map_t.length; i++) {
- pointType[i] = new Array();
- for (var j = 0; j<map_t[0].length; j++) {
- if (map_t[i][j] == 1) {
- pointType[i].push("wall");
- } else if (map_t[i][j] == 0) {
- pointType[i].push("road");
- }
- }
- }
- //trace("第一行:"+pointType[0]);
- }
- private function initDirectData():Void {
- //下,右,上,左
- directData[0] = [1, 0, 10];
- directData[1] = [0, 1, 10];
- directData[2] = [-1, 0, 10];
- directData[3] = [0, -1, 10];
- }
- private function sortList(list_t:Array):Void {
- list_t.sortOn("F", Array.NUMERIC);
- }
- private function isOut(point_t:Object):Boolean {
- if (point_t.X<0 || point_t.Y<0 || point_t.X>16 || point_t.Y>16) {
- return true;
- } else {
- return false;
- }
- }
- private function isInList(point_t:Object, list_t:Array):Boolean {
- if (list_t.length == 0) {
- return false;
- }
- for (var i = 0; i<list_t.length; ) {
- if (list_t[i].X == point_t.X && list_t[i].Y == point_t.Y) {
- return true;
- break;
- }
- i++;
- if (i == list_t.length) {
- return false;
- }
- }
- }
- private function manhattanDis(start_t:Object, end_t:Object):Number {
- var dis:Number;
- dis = Math.abs(start_t.X-end_t.X)+Math.abs(start_t.Y-end_t.Y);
- return dis*cost;
- }
- private function send2List(point_t:Object, list_t:Array):Void {
- list_t.push(point_t);
- }
- }