论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Flash AS编程教程
Tag:2.0,3.0菜鸟,游戏,,cs,技巧,源码,,文本,文字,函数,音乐,随机,拖拽,asp,access,xml,mc,视频教程

FLASH AS 游戏:A*寻路(初级)

文章类别:Flash AS编程 | 发表日期:2008-10-6 17:35:44


经过我的优化后,速度比原来快了很多,但比起版主的还是慢.还要继续努力.不过终于是入AS3的门了.

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);
   }
  }
}
}


A星as3.swf:
 
源文件: A星as3.rar
视频教程列表
文章教程搜索
 
Flash AS推荐教程
Flash AS热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058