Flash Actionscript2.0 Astar 寻路类

利用A*寻路算法写的一个类,希望对研究tile和astar的flash朋友有所帮助。

  1
/*
*
  2
* @author rison
  3
* @data 2006-05-03
  4
* @version 1.1
  5
* @usage A*path searching
  6 */

  7 class Astar {
  8     //init var

  9     private static var cost:Number = 10;
10     private static var isSearching:Boolean = false
;
11     private static var broadcastInit =
AsBroadcaster.initialize(Astar.prototype);
12     public var
addListener:Function;
13     public var
removeListener:Function;
14     private var
broadcastMessage:Function;
15     private var
path:Array;
16     private var
openList:Array;
17     private var
closeList:Array;
18     private var
map:Array;
19     private var
pointType:Array;
20     private var
directData:Array;
21    
//
22     public function
Astar() {
23         path = new
Array();
24         pointType = new
Array();
25         openList = new
Array();
26         closeList = new
Array();
27         directData = new
Array();
28         map = new
Array();
29
        initDirectData();
30
    }
31     public function
setMap(map_t:Array) {
32         map =
map_t;
33
        setPointType(map);
34
    }
35     public function
findPath(startX:Number, startY:Number, endX:Number, endY:Number) {
36
        initData();
37         isSearching = true
;
38         var startPoint:Object = new
Object();
39         var endPoint:Object = new
Object();
40         var prePoint:Object = new
Object();
41         startPoint.X =
startX;
42         startPoint.Y =
startY;
43         endPoint.X =
endX;
44         endPoint.Y =
endY;
45         startPoint.parent = null
;
46         startPoint.G = 0
;
47         startPoint.H =
manhattanDis(startPoint, endPoint);
48         startPoint.F = startPoint.G+
startPoint.H;
49         prePoint =
startPoint;
50         //send2List(startPoint, openList);

51         send2List(startPoint, closeList);
52         while (isSearching == true
) {
53             for (var i = 0; i<directData.length; i++
) {
54                 var tempPoint:Object = new
Object();
55                 tempPoint.X = prePoint.X+directData[i][0
];
56                 tempPoint.Y = prePoint.Y+directData[i][1
];
57                 if (isOut(tempPoint) == true
) {
58                 } else
{
59                     if (tempPoint.Y == endPoint.Y && tempPoint.X ==
endPoint.X) {
60                         //found

61                         isSearching = false;
62
                        send2List(tempPoint, closeList);
63                         tempPoint.parent =
prePoint;
64                         tempPoint.G = prePoint.G+directData[i][2
];
65                         tempPoint.H =
manhattanDis(tempPoint, endPoint);
66                         tempPoint.F = tempPoint.G+
tempPoint.H;
67                         //trace(closeList[closeList.length-1].X+" "+closeList[closeList.length-1].Y);

68                         //trace("path found!");
69                         drawPath();
70                         broadcastMessage("onPathFound"
);
71                         return
;
72
                    }
73                     if (getPointType(tempPoint) == "road" && isInList(tempPoint, closeList) == false
) {
74                         //trace("四向之"+i+" tempPoint:"+tempPoint.X+" "+tempPoint.Y);

75                         //目标格不在关闭列表且是road
76                         if (isInList(tempPoint, openList) == false) {
77                             //目标格尚未开启

78                             send2List(tempPoint, openList);
79                             //trace("ol:"+openList[0].X+"=="+openList[0].Y);

80                             tempPoint.parent = prePoint;
81                             tempPoint.G = prePoint.G+directData[i][2
];
82                             tempPoint.H =
manhattanDis(tempPoint, endPoint);
83                             tempPoint.F = tempPoint.G+
tempPoint.H;
84                         } else
{
85                             //已经在开启列表中

86                             var tempG:Number = prePoint.G+directData[i][2];
87                             for (var j = 0; j<openList.length; j++
) {
88                                 if (tempPoint.X == openList[j].X && tempPoint.Y ==
openList[j].Y) {
89                                     if (tempG<
openList[j].G) {
90                                         //现在的路径G更好

91                                         openList[j].G = tempG;
92                                         openList[j].F = openList[j].G+
openList[j].H;
93                                         openList[j].parent =
prePoint;
94
                                    }
95                                     break
;
96
                                }
97
                            }
98
                        }
99
                    }
100
                }
101
            }
102             if (openList.length == 0
) {
103                 isSearching = false
;
104                 broadcastMessage("onPathBlock"
);
105                 return
;
106
            }
107
            sortList(openList);
108             prePoint =
openList.shift();
109
            send2List(prePoint, closeList);
110             //trace(closeList[closeList.length-1].X+" "+closeList[closeList.length-1].Y);

111         }
112
    }
113     public function
getPath():Array {
114
        path.reverse();
115         trace("==========Path start==========="
);
116         for (var i = 0; i<path.length; i++
) {
117             trace("path:"+path[i].X+
path[i].Y);
118
        }
119         trace("==========Path  end ==========="
);
120         return
path;
121
    }
122     private function
initData():Void {
123         openList =
[];
124         closeList =
[];
125         path =
[];
126
    }
127     private function
drawPath() {
128         //trace("set path");

129         closeList.reverse();
130         var currentPathPoint:Object = new
Object();
131         currentPathPoint = closeList[0
];
132
        send2List(currentPathPoint, path);
133         //trace(currentPathPoint.X+" "+currentPathPoint.Y);

134         for (var i = 1; i<closeList.length; i++) {
135             if (currentPathPoint.parent == null
) {
136                 break
;
137
            }
138             //trace(currentPathPoint.parent.X+" "+currentPathPoint.parent.Y);                                                           

139             send2List(currentPathPoint.parent, path);
140             currentPathPoint =
currentPathPoint.parent;
141
        }
142
    }
143     private function
getPointType(point_t:Object):String {
144         return
pointType[point_t.X][point_t.Y];
145
    }
146     private function
setPointType(map_t:Array) {
147         for (var i = 0; i<map_t.length; i++
) {
148             pointType[i] = new
Array();
149             for (var j = 0; j<map_t[0].length; j++
) {
150                 if (map_t[i][j] == 1
) {
151                     pointType[i].push("wall"
);
152                 } else if (map_t[i][j] == 0
) {
153                     pointType[i].push("road"
);
154
                }
155
            }
156
        }
157         //trace("第一行:"+pointType[0]);

158     }
159     private function
initDirectData():Void {
160         //下,右,上,左

161         directData[0] = [1, 0, 10];
162         directData[1] = [0, 1, 10
];
163         directData[2] = [-1, 0, 10
];
164         directData[3] = [0, -1, 10
];
165
    }
166     private function
sortList(list_t:Array):Void {
167         list_t.sortOn("F"
, Array.NUMERIC);
168
    }
169     private function
isOut(point_t:Object):Boolean {
170         if (point_t.X<0 || point_t.Y<0 || point_t.X>16 || point_t.Y>16
) {
171             return true
;
172         } else
{
173             return false
;
174
        }
175
    }
176     private function
isInList(point_t:Object, list_t:Array):Boolean {
177         if (list_t.length == 0
) {
178             return false
;
179
        }
180         for (var i = 0; i<
list_t.length; ) {
181             if (list_t[i].X == point_t.X && list_t[i].Y ==
point_t.Y) {
182                 return true
;
183                 break
;
184
            }
185             i++
;
186             if (i ==
list_t.length) {
187                 return false
;
188
            }
189
        }
190
    }
191     private function
manhattanDis(start_t:Object, end_t:Object):Number {
192         var
dis:Number;
193         dis = Math.abs(start_t.X-end_t.X)+Math.abs(start_t.Y-
end_t.Y);
194         return dis*
cost;
195
    }
196     private function
send2List(point_t:Object, list_t:Array):Void {
197
        list_t.push(point_t);
198
    }
199
}
200

参考文档:http://blog.vckbase.com/panic/archive/2005/03/20/3778.html

posted on 2007-03-26 13:59  rison  阅读(1065)  评论(4编辑  收藏  举报

导航