我已经从http://rocketmandevelopment.com/blog/putting-a-into-code/下载了 A* 包。我对如何使用A*的包有疑问,因为我只有包。
- 我必须创建 main.fla 吗?
- 我必须在 main.fla 类中写什么?Grid.as、Cell.as 还是 AStar.as?
很抱歉我的英语不好。关键是,我不知道如何使用这个包。:D ##
单元格
package com.rocketmandevelopment.grid {
import flash.display.Graphics;
import flash.events.TimerEvent;
import flash.utils.Timer;
import com.rocketmandevelopment.grid.pieces.Piece;
import com.rocketmandevelopment.math.Vector2D;
public class Cell {
public var f:Number = 0;
public var g:Number = 0;
public var h:Number = 0;
public var isClosed:Boolean = false;
public var isOpen:Boolean = false;
public var isWalkable:Boolean = true;
private var _neighbors:Array;
public function get neighbors():Array {
if(!_neighbors) {
_neighbors = [];
_neighbors.push(Grid.cellAt(x - 1, y - 1));
_neighbors.push(Grid.cellAt(x, y - 1));
_neighbors.push(Grid.cellAt(x + 1, y - 1));
_neighbors.push(Grid.cellAt(x + 1, y));
_neighbors.push(Grid.cellAt(x + 1, y + 1));
_neighbors.push(Grid.cellAt(x, y + 1));
_neighbors.push(Grid.cellAt(x - 1, y + 1));
_neighbors.push(Grid.cellAt(x - 1, y));
var len:int = _neighbors.length
for(var i:int = len - 1; i >= 0; i--) {
if(_neighbors[i] == null) {
_neighbors.splice(i, 1);
}
}
}
return _neighbors;
}
public var parent:Cell;
public function get position():Vector2D {
return new Vector2D(_x, _y);
}
public var possibleActions:Array = [];
public var visited:Boolean = false;
private var _x:int;
public function get x():int {
return _x;
}
private var _y:int;
public function get y():int {
return _y;
}
public function Cell(x:int, y:int) {
_x = x;
_y = y;
}
public function clear():void {
f = 0;
g = 0;
h = 0;
isClosed = false;
isOpen = false;
parent = null;
isWalkable = true;
}
public function draw(g:Graphics, w:Number, h:Number):void {
if(!isWalkable) {
g.beginFill(0x000088);
}
g.drawRect(_x * w, _y * h, w, h);
g.endFill();
}
public function reset():void {
f = 0;
g = 0;
h = 0;
isClosed = false;
isOpen = false;
parent = null;
}
public function toString():String {
return "Cell(x: " + _x + " y: " + _y + ")"; // " f: "+ f +" g: "+g+" h: "+h + ")";
}
}
网格.as
package com.rocketmandevelopment.grid {
import flash.display.Graphics;
public class Grid {
private static var theGrid:Grid;
private var _height:int;
private var _width:int;
private var grid:Array;
public function Grid(width:int, height:int) {
_width = width;
_height = height;
grid = [];
for(var x:int = 0; x < _width; x++) {
grid[x] = [];
for(var y:int = 0; y < _height; y++) {
grid[x][y] = new Cell(x, y);
}
}
}
public static function cellAt(x:int, y:int):Cell {
if((x >= 0 && x < theGrid.grid.length) && y >= 0 && y < theGrid.grid[0].length) {
return theGrid.grid[x][y];
}
return null;
}
public static function clear():void {
if(!theGrid.grid) {
return;
}
for(var x:int = 0; x < theGrid._width; x++) {
for(var y:int = 0; y < theGrid._height; y++) {
theGrid.grid[x][y].clear();
}
}
}
public static function createGrid(width:int, height:int):Grid {
if(theGrid) {
return theGrid;
}
var g:Grid = new Grid(o, width, height);
theGrid = g;
return g;
}
public static function draw(graphics:Graphics, width:Number, height:Number):void {
if(!theGrid.grid) {
return;
}
graphics.lineStyle(0, 0x555555);
for(var x:int = 0; x < theGrid._width; x++) {
for(var y:int = 0; y < theGrid._height; y++) {
theGrid.grid[x][y].draw(graphics, width, height);
}
}
}
public static function getGrid():Grid {
if(theGrid) {
return theGrid;
}
return null;
}
public static function reset():void {
if(!theGrid.grid) {
return;
}
for(var x:int = 0; x < theGrid._width; x++) {
for(var y:int = 0; y < theGrid._height; y++) {
theGrid.grid[x][y].reset();
}
}
}
}
星辰
package com.rocketmandevelopment.grid {
import com.rocketmandevelopment.grid.Cell;
import com.rocketmandevelopment.math.Vector2D;
[SWF(width=510, height=550, backgroundColor=0, fps=30)]
public class AStar {
public static var heuristic:Function = manhattan;
public function AStar() {
}
public static function aStar(start:Vector2D, end:Vector2D):Array {
Grid.reset();
var open:Array = [Grid.cellAt(start.x, start.y)];
open[0].isOpen = true;
var closed:Array = [];
var currentCell:Cell;
var path:Array;
while(true) {
if(open.length == 0) {
break;
}
currentCell = getLowestF(open);
if(currentCell.x == end.x && currentCell.y == end.y) {
path = [currentCell];
while(true) {
path.push(currentCell.parent);
currentCell = currentCell.parent;
if(!currentCell.parent) {
path.reverse();
break;
}
}
break;
}
closed.push(currentCell);
currentCell.isClosed = true;
var n:Array = currentCell.neighbors;
for(var i:int = 0; i < n.length; i++) {
if(n[i] == null || !n[i].isWalkable) {
continue;
}
if(!n[i].isOpen && !n[i].isClosed) {
open.push(n[i]);
n[i].isOpen = true;
if(isDiagonal(currentCell, n[i])) {
n[i].g = 1.4;
} else {
n[i].g = 1;
}
n[i].parent = currentCell;
n[i].g += n[i].parent.g;
n[i].h = heuristic(n[i], end);
n[i].f = n[i].g + n[i].h;
} else {
var tg:Number;
if(isDiagonal(currentCell, n[i])) {
tg = 1.4;
} else {
tg = 1
}
tg += currentCell.g;
if(tg < n[i].g) {
n[i].g = tg;
n[i].f = n[i].g + n[i].h;
n[i].parent = currentCell;
}
}
}
}
return path;
}
public static function diagonal(current:Cell, end:Vector2D):Number {
var xDistance:int = Math.abs(current.x - end.x);
var yDistance:int = Math.abs(current.y - end.y);
if(xDistance > yDistance) {
return yDistance + (xDistance - yDistance);
} else {
return xDistance + (yDistance - xDistance);
}
return 0;
}
public static function manhattan(current:Cell, end:Vector2D):Number {
return Math.abs(current.x - end.x) + Math.abs(current.y + end.y);
}
private static function getLowestF(list:Array):Cell {
list.sortOn("f", Array.NUMERIC | Array.DESCENDING);
return list.pop();
}
private static function isDiagonal(center:Cell, other:Cell):Boolean {
if(center.x != other.x && center.y != other.y) {
return true;
}
return false;
}
}