1. 程式人生 > >js實現A*尋路演算法

js實現A*尋路演算法

js使用canvas繪製介面。


定義兩個類:Node儲存點及A*演算法中的F=G+H值;Point。

/**
 * 節點
 * p	: 節點對應的座標
 * pn	: 節點的父節點
 * g	: A*-g
 * h	: A*-h
 */
function Node(p, pn, g, h) {
	if ( !(p instanceof Point) || isNaN(g) || isNaN(h)) {
		throw new Error("非法引數");
	}
	this.g = g;
	this.h = h;
	this.f = g + h;
	this.p = p;
	this.pn = pn;
	
	this.equals = function(obj){
		if(!(obj instanceof Node)){
			return false;
		}
		return this.p.equals(obj.p);
	}
}

/**
 * 點
 */
function Point(x, y) {
	if (isNaN(x) || isNaN(y)) {
		throw new Error("非法引數");
	}
	this.x = x;
	this.y = y;
	
	this.equals = function(obj){
		if(!(obj instanceof Point)){
			return false;
		}
		return this.x == obj.x && this.y == obj.y;
	}
}


演算法實現:探索新節點->是否被訪問 ?跳過:(是否已被記錄?(是否需要更新?更新:""):加入開放列表):“”,直到尋找到終點或地圖說有點被訪問 結束迴圈。

//尋路
while(true){
	if(openList.length == 0){
		break;
	}
	var node = openList.shift();
	if(node.p.equals(constants.END_POINT)){
		rsNode = node;
		break;
	}
	
	var nodeArr = utils.explore(node, constants.MAP_ARRAY, constants.END_POINT);
	closeList.push(node);
	//判斷探索到的節點是否已被訪問  若未訪問過則加入到 開放列表
	for(var i in nodeArr){
		var n = nodeArr[i];
		//判斷開放列表是否已存在節點 是否需要更新
		if(utils.inArray(n, closeList) == -1){
			var off = utils.inArray(n, openList);
			if(off == -1){
				openList.push(n);
			}else{
				var u = openList[off];
				//已探索過此節點,且現在有更優路徑
				if(u.f > n.f){
					openList.splice(off, 0);
					openList.push(n);
				}
			}
		}
	}
	
	openList.sort(utils.sortNode);
}
原始碼:http://download.csdn.net/detail/lj745280746/7007935

參考:http://wenku.baidu.com/link?url=0qHr1lg5ngTQasT6e4J12ZEnVc4A5wiybpD3MRfkzNVP7Z7NUkLJaGeGNPdUmy-Il7dedpJjwbEhkJmJIOgdE5EMRUlBYhyCfd7rW0UbPSC