/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/glIJ
*/
package {
import flash.geom.Rectangle;
import flash.display.BitmapData;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
map = new BitmapData(465,465,false, 0xf0f0f0);
map.fillRect(new Rectangle(64,64, 128,32), 0);
map.fillRect(new Rectangle(64,264, 128,32), 0);
map.fillRect(new Rectangle(64,64, 32,128), 0);
map.fillRect(new Rectangle(264,64, 32,128), 0);
map.fillRect(new Rectangle(264,264, 32,128), 0);
addNode(32,32);
addNode(232,32);
addNode(32,232);
addNode(232,232);
addNode(132,132);
addNode(332,232);
addNode(32,432);
addNode(432,432);
addNode(432,32);
addNode(132,332);
addNode(232,332);
addNode(232,432);
buildNode();
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var map:BitmapData;
public function isWall(ax:Number, ay:Number):Boolean
{ if (ax<0||ax>=465||ay<0||ay>=465){return true;}
if (map.getPixel(ax,ay)<256) { return true;} return false; }
public function getMag(ax:Number,ay:Number):Number
{ return Math.sqrt(ax*ax+ay*ay); }
public function lineTest(ax:Number,ay:Number, bx:Number, by:Number):Boolean
{
var ta:Number; var mag:Number;
var ux:Number; var uy:Number;
var d:Number;
mag = getMag(bx-ax,by-ay);
ta = Math.atan2(by-ay,bx-ax);
ux = Math.cos(ta)*4; uy = Math.sin(ta)*4;
for(d=0;d<mag;d+=4)
{ if (isWall(ax,ay)) {return false;} ax+=ux; ay+=uy; }
return true;
}//linetest
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
graphics.beginBitmapFill(map);
graphics.drawRect(0,0,465,465);
graphics.endFill();
var i:int; var num:int; var a:xNode;
var k:int; var nk:int; var b:xNode;
num = vecNode.length;
for (i=0;i<num;i+=1)
{
a = vecNode[i];
graphics.drawCircle(a.cx,a.cy,8);
nk = a.vecNext.length;
for (k=0;k<nk;k+=1)
{
b = a.vecNext[k];
graphics.moveTo(a.cx,a.cy);
graphics.lineTo(b.cx,b.cy);
}//nextk
}//nexti
var mx:Number; var my:Number;
mx = stage.mouseX; my = stage.mouseY;
a = getClose(mx,my);
if (a!=null)
{
graphics.drawCircle(a.cx,a.cy,12);
graphics.moveTo(a.cx,a.cy);
graphics.lineTo(mx,my);
}//endif
graphics.lineStyle(6,0xFF,1);
findPath(vecNode[0], a);
var vec:Vector.<xNode>;
vec = getPath();
num = vec.length;
for(i=0;i<num;i+=1)
{
a = vec[i];
if (i==0){graphics.moveTo(a.cx,a.cy); }
graphics.lineTo(a.cx,a.cy);
}//nexti
}//onenter
public var vecNode:Vector.<xNode> = new Vector.<xNode>(0,false);
public function addNode(ax:Number, ay:Number):void
{
var a:xNode;
a = new xNode();
a.cx=ax;a.cy=ay;
vecNode.push(a);
}//addnode
public function buildNode():void
{
var k:int; var i:int; var num:int;
var a:xNode; var b:xNode;
num = vecNode.length;
for (i=0;i<num;i+=1)
{
a = vecNode[i];
for (k=i+1;k<num;k+=1)
{
b = vecNode[k];
if (lineTest(a.cx,a.cy, b.cx,b.cy)==false){continue;}
a.vecNext.push(b);
b.vecNext.push(a);
}//nextk
}//nexti
}//buildnode
public function getClose(ax:Number, ay:Number):xNode
{
var d:Number; var mag:Number;
var ret:xNode;
var num:int; var i:int;
var a:xNode;
if (vecNode.length<=0){return null; }
ret = vecNode[0];
mag = getMag(ret.cx-ax, ret.cy-ay);
num = vecNode.length;
for (i=0;i<num;i+=1)
{
a = vecNode[i];
d = getMag(a.cx-ax,a.cy-ay);
if (d>=mag) {continue;}
mag=d;ret=a;
}//nexti
return ret;
}//getclose
public var maxOpen:int = 1024;
public var vecOpen:Vector.<xNode> = new Vector.<xNode>(1024, false);
public var curFrame:int =0;
public var lastNode:xNode = null;
public function findPath(from:xNode, to:xNode):void
{
var i:int; var num:int; var k:int; var nk:int;
var ot:int; var mcost:Number;
var a:xNode; var b:xNode;
lastNode=null;
curFrame+=1;
ot = 1;
vecOpen[0]= from;
from.cost=0;
from.parent=null;
from.frame=curFrame;
for(i=0;i<4096;i+=1)
{
if (ot<=0){ return; }
mcost = 999999999;
a = vecOpen[0];
for (k = 0; k < ot; k+=1)
{
b = vecOpen[k];
if (b.cost < mcost)
{ mcost = b.cost; a = b; nk = k; }
}//nextk
vecOpen[nk] = vecOpen[ot - 1];
ot -= 1;
if (a == to) { lastNode = to; return; }
num=a.vecNext.length;
for(k=0;k<num;k+=1)
{
b = a.vecNext[k];
if (b.frame==curFrame){continue;}
b.frame=curFrame;
b.cost = getMag(a.cx-b.cx, a.cy-b.cy) + a.cost;
b.parent = a;
vecOpen[ot] =b;ot+=1; if (ot>=maxOpen){ot=maxOpen-1;}
}//nextk
}//nexti
}//findpath
public function getPath():Vector.<xNode>
{
var a:xNode; var k:int;
var ret:Vector.<xNode>;
ret = new Vector.<xNode>(0,false);
a = lastNode; k = 0;
while(a != null)
{
graphics.drawCircle(a.cx,a.cy,16);
ret.push(a);
a = a.parent;
k+=1;if (k>=1024){return null;}
} //wend
return ret.reverse();
}//getpath
}//classend
}
internal class xNode
{
public var cx:Number = 0;
public var cy:Number = 0;
public var frame:int = 0;
public var cost:Number = 0;
public var parent:xNode = null;
public var vecNext:Vector.<xNode> = new Vector.<xNode>(0,false);
}//xnode