var w:uint = 60;//地图横节点个数
var h:uint = 35;//地图纵节点个数 var r:uint = 10;//节点的长宽 var isEight:Boolean = true;//是否为八方向寻路 var time:uint;//记录时间 var field:MovieClip=new MovieClip();//地图 addChild(field); var allNode:Array = new Array();//所有节点 var start_Piont:MovieClip;//寻路出发点 var end_Piont:MovieClip;//寻路目的地 var open_arr:Array;//开放列表 var block_arr:Array;//关闭列表 var path_arr:Array;//路径 var fail:Boolean = false;//是否找到路径 var isRun:Boolean = false;//是否正在寻路 init(field); type_mc.addEventListener(MouseEvent.CLICK, typeHandler); reset_mc.addEventListener(MouseEvent.CLICK, resetHandler); //初始化地图 function init(field:MovieClip) { for (var y:uint=0; y<h; y++) { if (allNode[y]==undefined) { allNode[y] = new Array(); } for (var x:uint=0; x<w; x++) { var everynode:MovieClip=new node(); allNode[y].push(field.addChildAt(everynode, field.numChildren)); allNode[y][x].px = x; allNode[y][x].py = y; allNode[y][x].x=x*r; allNode[y][x].y=y*r; //25%概率是不可通过,左上角一定为可通过 allNode[y][x].gotoAndStop(Math.random()>.25||(x==0&&y==0)?1:2); //如果可以通过就添加点击事件 if (allNode[y][x].currentFrame == 1) { allNode[y][x].addEventListener(MouseEvent.CLICK, setEndPiont); } } } field.x = 30;//Math.floor((stage.stageWidth-field.width)/2); field.y = 10;//Math.floor((stage.stageHeight-field.height)/2)-10; } //节点被点击时之事件 function setEndPiont(e:MouseEvent):void { if (!isRun) { isRun = true; //清除之前计算的节点 for (var y:uint=0; y<h; y++) { for (var x:uint=0; x<w; x++) { if (allNode[y][x].currentFrame>2) { allNode[y][x].gotoAndStop(1); } } } //开始计时 time = getTimer(); open_arr = new Array(); block_arr = new Array(); path_arr = new Array(); //如果是第一次寻路,出发点是左上角,否则是上一次寻路的终点 start_Piont = end_Piont == null ? allNode[0][0] : end_Piont; end_Piont = e.currentTarget; //开始寻找 checkNeighbor(start_Piont); } } //检测周围的节点 function checkNeighbor(node:MovieClip):void { var thisNode:MovieClip = node;//当前正在检测的节点 var getEnd:Boolean = false;//是否找到目的地 //循环直到找到目的地 while (!getEnd) { //将当前正在检测的节点存入关闭列表 block_arr.push(thisNode); var checkList:Array = new Array();//当前节点的周围 //如果是八方向寻路,就加入四个角 if (isEight) { if (thisNode.py>0 && thisNode.px>0) { checkList.push(allNode[(thisNode.py-1)][(thisNode.px-1)]); } if (thisNode.py<h-1 && thisNode.px>0) { checkList.push(allNode[(thisNode.py+1)][(thisNode.px-1)]); } if (thisNode.py>0 && thisNode.px<w-1) { checkList.push(allNode[(thisNode.py-1)][(thisNode.px+1)]); } if (thisNode.py<h-1 && thisNode.px<w-1) { checkList.push(allNode[(thisNode.py+1)][(thisNode.px+1)]); } } if (thisNode.py>0) { checkList.push(allNode[(thisNode.py-1)][(thisNode.px)]); } if (thisNode.px>0) { checkList.push(allNode[(thisNode.py)][(thisNode.px-1)]); } if (thisNode.px<w-1) { checkList.push(allNode[(thisNode.py)][(thisNode.px+1)]); } if (thisNode.py<h-1) { checkList.push(allNode[(thisNode.py+1)][(thisNode.px)]); } //开始检测当前节点周围 var len:uint = checkList.length; for (var i:uint = 0; i<len; i++) { //周围的每一个节点 var neighboringNode:MovieClip = checkList[i]; //判断是否是目的地 if (neighboringNode == end_Piont) { if (isEight) { //如果是八方向寻路 if (neighboringNode.px != thisNode.px && neighboringNode.py != thisNode.py) { //如果是角上的节点,需要再判断是否可以通行 if (allNode[(neighboringNode.py)][thisNode.px].currentFrame != 2 && allNode [(thisNode.py)][neighboringNode.px].currentFrame != 2) { neighboringNode.nodeparent = thisNode; getEnd = true; break; } } else { //如果不是角上的节点 neighboringNode.nodeparent = thisNode; getEnd = true; break; } } else { //如果是四方向寻路,就直接得到目的地 neighboringNode.nodeparent = thisNode; getEnd = true; break; } } //是否可通行 if (neighboringNode.currentFrame != 2) { if (isEight) { //八方向寻路,需要判断是否为角上的节点 if (neighboringNode.px != thisNode.px && neighboringNode.py != thisNode.py) { //角上的节点需要判断是否可通过 if (allNode[(neighboringNode.py)][thisNode.px].currentFrame != 2 && all Node[(thisNode.py)][neighboringNode.px].currentFrame != 2) { count(neighboringNode, thisNode);//计算该节点 } } else { count(neighboringNode, thisNode);//计算该节点 } } else { count(neighboringNode, thisNode);//计算该节点 } } } if (!getEnd) { //如果未找到目的地 if (open_arr.length>0) { //开发列表不为空,找出F值最小的做为下一个循环的当前节点 thisNode = open_arr.splice(getMin(),1)[0]; } else { //开发列表为空,寻路失败 fail = true; break; } } } if (!fail) { //如果寻路成功,开始画路径 drawPath(end_Piont); //trace_mc.text = "可以到达!"; } else { end_Piont = null; trace_mc.text = "无法到达!"; fail = false; isRun = false; } } //计算邻节点 function count(neighboringNode:MovieClip, thisNode:MovieClip) { //是否在关闭列表里 if (!isInArr(neighboringNode, block_arr)) { //不在关闭列表里才开始判断 var newG:Number; //判断是四方向还是八方向寻路,减化四方向寻路的计算 if (isEight) { newG = neighboringNode.px == thisNode.px || neighboringNode.py == thisNode.py ? thisNode.G+10 : thisNode.G+14; } else { newG = thisNode.G+10; } if (isInArr(neighboringNode, open_arr)) { //如果该节点已经在开放列表里 if (neighboringNode.G>=(newG)) { //如果新G值小于或者等于旧值,则表明该路更优,更新其值 neighboringNode.G = newG; getGHF(neighboringNode); neighboringNode.nodeparent = thisNode; } } else { //如果该节点未在开放列表里 //添加至列表 open_arr.push(neighboringNode); neighboringNode.gotoAndStop(4); //计算GHF值 neighboringNode.G = newG; getGHF(neighboringNode); neighboringNode.nodeparent = thisNode; } } } //判断某值是否存在于数组中 function isInArr(obj, arr:Array):Boolean { var len:uint = arr.length; for (var i:Number = 0; i<len; i++) { if (obj == arr[i]) { return true; } } return false; } //生成GHF值 function getGHF(obj:MovieClip):void { if (!obj.G) { obj.G = 0; } obj.H = 10*(Math.abs(obj.px-end_Piont.px)+Math.abs(obj.py-end_Piont.py)); obj.F = obj.G+obj.H; } //得到开放列表里拥有最小F值的节点在列表里的位置 function getMin():uint { var len:uint = open_arr.length; var min:Object = new Object(); min.F = 100000; min.i = 0; for (var i:uint = 0; i<len; i++) { if (min.F>open_arr[i].F) { min.F = open_arr[i].F; min.i = i; } } return min.i; } //画路径 function drawPath(node:MovieClip):void { var pathNode:MovieClip = node; //倒过来得到路径 while (pathNode != start_Piont) { path_arr.push(pathNode); pathNode = pathNode.nodeparent; } path_arr.push(pathNode); //开始画 var len:uint = path_arr.length; for (var i:Number = 0; i<len; i++) { path_arr[i].gotoAndStop(3); } //显示计算时间 trace_mc.text = "耗时:"+(getTimer()-time)+" 毫秒,路长:"+path_arr.length+" ."; isRun = false; } //四方向八方向节换按钮的点击事件 function typeHandler(e:Event):void { isEight = !isEight; if (isEight) { e.currentTarget.label = "改为四方向"; } else { e.currentTarget.label = "改为八方向"; } } //重置按钮的点击事件 function resetHandler(e:Event):void { start_Piont = allNode[0][0]; end_Piont = null; for (var y:uint=0; y<h; y++) { for (var x:uint=0; x<w; x++) { allNode[y][x].gotoAndStop(Math.random()>.25||(x==0&&y==0)?1:2); if (allNode[y][x].currentFrame == 1) { allNode[y][x].addEventListener(MouseEvent.CLICK, setEndPiont); } else { allNode[y][x].removeEventListener(MouseEvent.CLICK, setEndPiont); } } } } |
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |