a星算法的原理,网络上基本都有,这里就不在介绍了,网络上的a星和例子结合的过于密切,不利于复用,如果你只需要代码,不需要了解原理,此文会对你有帮助
图片见附件,代码如下:
window.AStar = {};
(function(aStar){
//start:起始节点[i,j] , end:最终节点[i,j] map:地图数据(2d)arr,marker:可以通过的标识(例子用的是1)
aStar.find_path = function(start,end,map,marker){
var open = [];
var close = [];
var s_p = start;
var e_p = end;
var map_arr = map;
var tra_marker = marker;
var G = 0;
var H = 0;
var F = 0;
//加入起始节点 [x, y , G ,F ,father]
open.push([s_p[0],s_p[1],0,(Math.abs(e_p[0]-s_p[0]) + Math.abs(e_p[1]-s_p[1])),null]);
return function(obj){
//重拍,取最小的一个
var count = 0;
for(var i = obj[0]-1,ilen = i+3 ; i < ilen ; i++){
for(var j = obj[1]-1,jlen = j+3 ;j < jlen; j++){
//遍历周围八节点,排除自己
if(i == obj[0] && j == obj[1])
continue;
//排除穿越的情况
if(!((i == obj[0] ) || ( j == obj[1])) && ( map_arr[i] && map_arr[obj[0]] && map_arr[i][obj[1]] != tra_marker && map_arr[obj[0]][j] != tra_marker))
continue;
if(i == e_p[0] && j == e_p[1]){
open.push([i,j,G,F,obj]);
var ways = [];
var ele = obj;
do{
ways.unshift(ele);
ele = ele[4];
}while(ele[4] != null);
return ways;
}
if(map_arr[i] && map_arr[i][j] && map_arr[i][j] == tra_marker && is_exist(open,[i,j]) == -1 && is_exist(close,[i,j]) == -1){
G = ( i == obj[0] ) || ( j == obj[1] ) ? obj[2]+1.0 : obj[2]+1.4 ;
H = Math.sqrt((e_p[0] - i)*(e_p[0] - i) + (e_p[1] - j)*(e_p[1] - j));
F = G + H;
open.push([i,j,G,F,obj]);
count++;
}
}
}
close.push(open.shift());
var o;
if(open[0] && open[0][4] == obj[4]){
o = count == 0 ? get_other(open,obj) : (arr_sort(open),open[0]);
}else{
o = (arr_sort(open),open[0]);
}
if(o){
return arguments.callee(o);
}else{
return [];
}
}(open[0])
}
//获取其他节点
var get_other = function(arr,o){
var a = [];
for(var i = 0 ; i < arr.length ; i++){
if(o && arr[i][4] == o[4]){
return arr[i];
}
}
if(o[4]){
return arguments.callee(o[4]);
}else{
return null;
}
}
//对数组进行重排列
var arr_sort = function(){
function s(a,b){
return a[3] - b[3];
}
return function(arr){
arr.sort(s);
}
}();
//数组中是否存在此元素
var is_exist = function(arr,p){
for(var i = 0 ; i < arr.length ; i++){
if(arr[i][0] == p[0] && arr[i][1] == p[1]){
return i;
}
}
return -1;
}
})(window.AStar)
测试代码
<script src="a_star.js"></script>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script>
var state = 1;
var w = 20;
var h = 10;
var map_arr = [];
var start,end;
window.onload = function(){
var map = document.getElementById("map");
var arr = [];
arr.push("<table border=\"1\">");
for(var i = 0 ; i < h ; i++){
arr.push("<tr>");
if(!map_arr[i]) map_arr[i] = [];
for(var j = 0 ; j < w ;j++){
arr.push("<td id=\""+i+"-"+j+"\" style=\"width:50px;height:50px;border:1px solid #000\" onclick=\"td(" + i + "," + j + ")\"></td>");
map_arr[i][j] = 1;
}
arr.push("</tr>");
}
arr.push("</table>");
map.innerHTML = arr.join("");
}
function td(x,y){
var e = document.getElementById( x + "-" + y);
switch(state){
case 1:
start = [x,y];
e.style.backgroundColor = "#0f0";
break;
case 2:
end = [x,y];
e.style.backgroundColor = "#f00";
break;
case 3:
e.style.backgroundColor = "#000";
map_arr[x][y] = 0;
break;
}
}
function changeS(value){
state = value;
}
function find_path(){
var ways = AStar.find_path(start,end,map_arr,1);
if(ways.length == 0 ){
alert("no ways!~~~");
return ;
}
for(var i = 0;i < ways.length; i++){
var e = document.getElementById(ways[i][0]+"-"+ways[i][1]);
e.style.backgroundColor = "#00f";
}
}
</script>
<body>
<div id="map"></div>
<input type="button" onclick="changeS(1);" value="添加起始"/>
<input type="button" onclick="changeS(2);" value="添加终点" />
<input type="button" onclick="changeS(3);" value="添加障碍物" />
<input type="button" onclick="find_path();" value="生成路径" />
</body>