A*寻路算法初探及Js实现寻路过程
最近为了开发 王牌特工 这款小游戏,学习了A*寻路算法,来实现避开障碍物并抵达目标地点的功能。
算法具体实现过程可以学习这篇文章,本篇主要记录我使用Js实现寻路算法的过程(算法学习真是头疼- -)。
一、4个功能模块:
- 二维方块地图
A*寻路算法是基于点到点的关系,而在游戏开发场景中,我们常常把地图划分成一个个小方块,通过二维数组记录每个方块的坐标值,从而可以定位到某个点。因此我们需要构建坐标系。我使用的是HTML5中的Canvas绘图,在创建2D上下文环境中以40X40为一方块分割画布。
// 每个方块对象具有的属性
var block = {
x:……, // 横坐标
y:……, // 纵坐标
G:……, // 到该点的消耗
H:……, // 到终点的消耗
F:……, // G + H
parents:…… // 父节点
}
- 开启队列
存放需要遍历查找的方块
// 开启队列
var openList = (function() {
// 存放开启队列
var _openArr = [];
return {
// 添加到队列
add: function(point){……},
// 计算队列长度
count: function(){……},
// 得到开放队列中f值最小的点
minPoint: function(){……},
// 删除某个点
removeAt: function(index) {……},
// 是否可以加入开启队列
exists: function(obj) {……},
// 点已经在开启队列中
foundPoint: function(tempStart, end, point) {……},
// 点不在开启队列中,计算G、H、F值
notFoundPoint: function(tempStart, end, point) {……},
// 是否到达目标点
get: function(end) {……},
// 队列初始化
init: function() {……}
};
})();
- 关闭队列
存放不需要查找的方块
// 闭合队列
var closeList = (function() {
var _closeArr = [];
return {
add: function(point) {……},
init: function() {……}
};
})();
- A*寻路算法函数
见下一节
二、A*寻路算法的实现
- A*寻路算法函数
findPath为寻路算法函数,该函数接受两个参数start(开始点)和 end(终点)
var findPath = function(start, end) {
// 是否抵达标志位
var isArrive = false;
openList.add(start);
// 循环
while(!isArrive)
{
// 找出F值最小的点
var tempStart = openList.minPoint();
openList.removeAt(0);
closeList.add(tempStart);
// 找出它相邻的点
var aroundPoints = sAroundPoints(tempStart);
// 遍历所有相邻的点
aroundPoints.forEach(function(item, index) {
// 是否已经在开启队列中
if (openList.exists(item)) {
//计算G值, 如果比原来的大, 就什么都不做, 否则设置它的父节点为当前点,并更新G和F
openList.foundPoint(tempStart, end, item);
} else {
//如果它们不在开始列表里, 就加入, 并设置父节点,并计算GHF
openList.notFoundPoint(tempStart, end, item);
}
});
// 是否抵达终点
openList.get(end);
}
// 找回路径
foundPathRoad(end);
};
- 如何找回路径
通过终点对象的parents属性值,逐层递归找到上级节点,将每个父节点存入数组。
var foundPathRoad = function(obj) {
if ('parents' in obj) {
roadArr.unshift(obj);
arguments.callee(obj.parents);
}
return roadArr;
};
Comments