Pathfinding,A*寻路,利用这原理可以制作战棋游戏...地图内黑色块为障碍物,白色块为通道,在非寻路状态时点击可以切换.红色块为主角,点击主角再点目标可进行寻路.
PS:寻路是四方向的,人懒就没写八方向了,FLA文件请用FLASH MX2004以上版本打开
演示:
以下为代码:
//code by 月光 2005.9.22 //地图长宽 var mapx = 40; var mapy = 40; var total = mapx * mapy; //边界距离 var distancex = 30; var distancey = 30; //移动速度 var interval = 75; //初始障碍物比率 var balk = 3; var val; var width = 0; var height = 0; //移动次数 var moves = 0; //是否正在忙碌 var busy = false; //是否正在移动 var moving = false; //是否搜索成功 var finded = false; //路径记录 var open = new Array(); //方向数组 => 右, 下, 左, 上 var ori = new Array([1, 0], [0, 1], [-1, 0], [0, -1]); // ======================================== //重置 var reset = function () { clearInterval(val); for (var i in _root) { if (typeof _root[i] == "movieclip") { _root[i].removeMovieClip(); } } txt.text = ""; init(); }; btn_reset.onPress = reset; // ======================================== //初始化 var init = function () { var i = 1; // 绘制地图 while (i <= total) { var tmp = attachMovie("mc", "m" + i, i, {id:i, visited:false}); tmp._x = (i - 1) % mapx * tmp._width + distancex; tmp._y = Math.floor((i - 1) / mapy) * tmp._height + distancey; if (random(balk) == 0) { tmp.gotoAndStop(2); } i++; } m1.gotoAndStop(1); width = m1._width; height = m1._height; // 主角初始位置 attachMovie("player", "player", total + 10000, {_x:distancex, _y:distancey}); player.onPress = function() { busy = true; txt.text = "请选择目标"; }; moving = false; }; // ======================================== //点击地图后执行 btn.onPress = function() { if (!moving) { var i = 1; while (i <= total) { this._parent["m" + i].visited = false; i++; } var x = Math.ceil((_xmouse - distancex) / width); var y = Math.ceil((_ymouse - distancey) / height); var id = x + (y - 1) * mapy; //当前点击的MC var tmp = this._parent["m" + id]; if (!busy) { if (tmp._currentframe == 1) { txt.text = "目标转换为障碍物"; tmp.gotoAndStop(2); } else { txt.text = "目标转换为通道"; tmp.gotoAndStop(1); } } else { if (tmp._currentframe == 2) { txt.text = "目标为障碍物,无法到达"; busy = false; } else { findit(x, y); } } } }; // ======================================== //寻路 var findit = function (x, y) { finded = false; open = new Array(); var playerx = Math.ceil((player._x - distancex) / width) + 1; var playery = Math.ceil((player._y - distancey) / height) + 1; moves = 1; // 数组内元素为: X坐标, Y坐标, 距离原点长度, 上级位置 open[1] = [x, y, moves, 1]; for (i = 0; i < 4; i++) { // 邻格内移动 if (x + ori[i][0] == playerx && y + ori[i][1] == playery) { movefunc(); return; } } // 非邻格内移动 var z = 1; var t = 1; while (open[z] != null) { for (i = 0; i < 4; i++) { var tmpx = open[z][0] + ori[i][0]; var tmpy = open[z][1] + ori[i][1]; if (tmpx > 0 && tmpy > 0 && tmpx <= 40 && tmpy <= 40) { var id = tmpx + (tmpy - 1) * mapy; var tmp = this["m" + id]; // 当对象存在及非障碍物及未访问过时 if (tmp != null && tmp._currentframe == 1 && !tmp.visited) { tmp.visited = true; open[++t] = [tmpx, tmpy, open[z][2] + 1, z]; if (open[t][0] == playerx && open[t][1] == playery) { finded = true; moves = z; break; } } } } z++; } if (finded) { movefunc(); } else { busy = false; moving = false; //debug trace(open.join(" => ")); txt.text = "无法到达目标"; } }; // ======================================== //角色移动 var movefunc = function () { moving = true; txt.text = "找到目标,正在移动"; val = setInterval(moveFunc, interval); }; var moveFunc = function () { updateAfterEvent(); moves = open[moves][3]; player._x = (open[moves][0] - 1) * width + distancex; player._y = (open[moves][1] - 1) * height + distancey; if (moves == 1) { busy = moving = finded = false; txt.text = "已到达目标"; clearInterval(val); } }; // ======================================== init(); stop();
上一篇:时间轴特效设置
下一篇:学用FlashMX制作简单的情景动画
|