最近为了开发 王牌特工 这款小游戏,学习了A*寻路算法,来实现避开障碍物并抵达目标地点的功能。
算法具体实现过程可以学习这篇文章,本篇主要记录我使用Js实现寻路算法的过程(算法学习真是头疼- -)。
一、4个功能模块:
A*寻路算法是基于点到点的关系,而在游戏开发场景中,我们常常把地图划分成一个个小方块,通过二维数组记录每个方块的坐标值,从而可以定位到某个点。因此我们需要构建坐标系。我使用的是HTML5中的Canvas绘图,在创建2D上下文环境中以40X40为一方块分割画布。
1 2 3 4 5 6 7 8 9
| var block = { x:……, y:……, G:……, H:……, F:……, parents:…… }
|
存放需要遍历查找的方块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var openList = (function() { var _openArr = []; return { add: function(point){……}, count: function(){……}, minPoint: function(){……}, removeAt: function(index) {……}, exists: function(obj) {……}, foundPoint: function(tempStart, end, point) {……}, notFoundPoint: function(tempStart, end, point) {……}, get: function(end) {……}, init: function() {……} }; })();
|
存放不需要查找的方块
1 2 3 4 5 6 7 8
| var closeList = (function() { var _closeArr = []; return { add: function(point) {……}, init: function() {……} }; })();
|
见下一节
二、A*寻路算法的实现
findPath
为寻路算法函数,该函数接受两个参数start
(开始点)和 end
(终点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| var findPath = function(start, end) { var isArrive = false; openList.add(start); while(!isArrive) { var tempStart = openList.minPoint(); openList.removeAt(0); closeList.add(tempStart); var aroundPoints = sAroundPoints(tempStart); aroundPoints.forEach(function(item, index) { if (openList.exists(item)) { openList.foundPoint(tempStart, end, item); } else { openList.notFoundPoint(tempStart, end, item); } }); openList.get(end); } foundPathRoad(end); };
|
通过终点对象的parents属性值,逐层递归找到上级节点,将每个父节点存入数组。
1 2 3 4 5 6 7
| var foundPathRoad = function(obj) { if ('parents' in obj) { roadArr.unshift(obj); arguments.callee(obj.parents); } return roadArr; };
|