本例子是用A*方法

先上一个4方向的A*

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html" charset="utf-8"><title>A* javascript</title><style type="text/css">.map{ background-color: #CCCCCC; }.map td{ width : 20px; height: 20px; }.map_close{ background-color: #000000; }.map_open{ background-color: #FFFFFF; }</style>
</head>
<body>
</body>
</html>
<script type="text/javascript">
var map = {gridWidth : 30,girdHeight : 20,roadBlock : 0.1,init : function() {map.costEnergy_S = 10;map.costEnergy_L = 14;map.openArea = [];map.closeArea = {};map._createMapData();},/**  创建网格数据 */_createMapData : function() {var cache = map.cache;map.data = [];for (var y = 0, _arr; y < map.girdHeight; y++) {_arr = [];for (var x = 0, mapNode; x < map.gridWidth; x++) {mapNode = new map.Node(x, y);if (Math.random() < map.roadBlock) {mapNode.isRoadBlock = true;map.closeArea[mapNode.id] = mapNode;};map.cache[mapNode.id] = mapNode;_arr.push(mapNode);};map.data.push(_arr);};},/**  建立地图网格 */getUI : function() {var table = [];var data = map.data;table.push('<table cellpadding="0" cellspacing="1" bgcolor="0" class="map">');table.push('<tbody>');for (var y = 0, yl = data.length; y < yl; y++) {table.push('<tr>');for (var x = 0, xl = data[y].length; x < xl; x++) {table.push('<td id="'+ data[y][x].id +'" class="'+ (data[y][x].isRoadBlock === true ? 'map_close' : 'map_open') +'"></td>')}table.push('</tr>');};table.push('</tbody>');table.push('</table>');map.container = document.createElement('div');map.container.innerHTML = table.join('');return map.container;},Node : function(x, y) {this.x = x;this.y = y;this.id = 'map_'+ x + '_' + y;this.isRoadBlock = false;this.prev = null;this.fObj = null;},getNode : function(x, y) {return map.cache['map_'+ x + '_'+ y];},setStartNode : function(node) {map.startNode = node;},setEndNode : function(node) {map.endNode = node;},/**  检测当前开启列表中是否含有传进来的Node 存在则从开启列表中选中将其返回*/_isOpenAreaExitNode : function(node) {var openArea = map.openArea;for (var i = 0, l = openArea.length; i < l; i++) {if (openArea[i].id === node.id) return openArea[i];};return null;},getPath : function() {map.getAroundNode(map.startNode);if (map.openArea.length == 0) return;map.search(map.endNode);},/**  获取当前点的F G H值 */getF : function(cNode, aNode) {var energyW = Math.abs(map.endNode.x - aNode.x) * map.costEnergy_S;var energyH = Math.abs(map.endNode.y - aNode.y) * map.costEnergy_S;var _H = energyW + energyH;var _G = (Math.abs(aNode.x - cNode.x) === Math.abs(aNode.y - cNode.y) ? map.costEnergy_L : map.costEnergy_S);if (cNode.fObj) _G = cNode.fObj.G + _G;return { F : _H + _G, H : _H, G : _G };},/**  获取当前父节点周围的点  */getAroundNode : function(node) {var maxHeight = map.girdHeight;var maxWidth = map.gridWidth;var nodeX;var nodeY;for (var x = -1; x <= 1; x++) {nodeX = node.x + x;for (var y = -1, mapNode, _fObj, tmpNode; y <= 1; y++) {nodeY = node.y + y;//剔除本身 以及斜角方向if (x === 0 && y === 0 || Math.abs(x) == Math.abs(y)) continue;if (nodeX >= 0 && nodeY >= 0 && nodeX < maxWidth && nodeY < maxHeight) {mapNode = map.getNode(nodeX, nodeY);if (!map.closeArea[mapNode.id]) {_fObj = map.getF(node, mapNode);// 如果周围节点已在开启区域的 根据当前节点 获取新的G值  与当前点的进行比较 如果小于以前的G值 则指定当前节点为其父节点tmpNode =  map._isOpenAreaExitNode(mapNode);if (tmpNode) {if (tmpNode.fObj.G <= _fObj.G) continue;};mapNode.fObj = _fObj;mapNode.prev = node;map.openArea.push(mapNode);};};};};},/**  不断删除查找周围节点,直到找寻到结束点 */search : function(node) {while(!map.closeArea[node.id]) {var _fMinNode = map._getFMin();if (!_fMinNode) break;map.getAroundNode(_fMinNode);map.search(node);};if (map.closeArea[node.id]) {map._drawRoad(node);};},/**  绘制路线 */_drawRoad : function(node) {document.getElementById(node.id).style.background = '#EFA626';if (node.prev !== map.startNode) map._drawRoad(node.prev);},/**  从开启列表从寻找F点最小的点 从开启列表移除 移入关闭列表 */_getFMin : function() {if (map.openArea.length == 0) return null;map._orderOpenArea();map.closeArea[map.openArea[0].id] = map.openArea[0];//document.getElementById(map.openArea[0].id).innerHTML = map.openArea[0].fObj.F + '^' + map.openArea[0].fObj.G + '^' + map.openArea[0].fObj.H;return map.openArea.shift();},/**  排序开启列表 */_orderOpenArea : function() {this.openArea.sort(function(objF, objN) {return objF.fObj.F - objN.fObj.F;});},data : [],openArea : [],closeArea : {},cache : {},startNode : null,endNode : null,container : null
};(function() {map.roadBlock = 0.3;map.init();var mapUI = map.getUI();var startNode = null;var isRun = false;// 计时器var Timer = function (){this.startTime = + new Date;};Timer.prototype.stop = function(){return + new Date - this.startTime;};document.getElementsByTagName('body')[0].appendChild(mapUI);mapUI.onclick = function(event) {event = event || window.event;var target = event.target || event.srcElement;if (isRun) return;if (target.nodeName !== "TD") return;var node = map.cache[target.id];if (node.isRoadBlock) return;if (!node) return;if (startNode) {map.setEndNode(node);var time = new Timer;map.getPath();document.title = '[' + time.stop() + '毫秒] ' + document.title;isRun = true;target.style.backgroundColor = 'red';} else {startNode = node;map.setStartNode(node);target.style.backgroundColor = 'green';};};
})();
</script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html" charset="utf-8"> <title>A* javascript</title> <style type="text/css"> .map{ background-color: #CCCCCC; } .map td{ width : 20px; height: 20px; } .map_close{ background-color: #000000; } .map_open{ background-color: #FFFFFF; } </style> </head> <body> </body> </html> <script type="text/javascript"> var map = { gridWidth : 30, girdHeight : 20, roadBlock : 0.1, init : function() { map.costEnergy_S = 10; map.costEnergy_L = 14; map.openArea = []; map.closeArea = {}; map._createMapData(); }, /** 创建网格数据 */ _createMapData : function() { var cache = map.cache; map.data = []; for (var y = 0, _arr; y < map.girdHeight; y++) { _arr = []; for (var x = 0, mapNode; x < map.gridWidth; x++) { mapNode = new map.Node(x, y); if (Math.random() < map.roadBlock) { mapNode.isRoadBlock = true; map.closeArea[mapNode.id] = mapNode; }; map.cache[mapNode.id] = mapNode; _arr.push(mapNode); }; map.data.push(_arr); }; }, /** 建立地图网格 */ getUI : function() { var table = []; var data = map.data; table.push('<table cellpadding="0" cellspacing="1" bgcolor="0" class="map">'); table.push('<tbody>'); for (var y = 0, yl = data.length; y < yl; y++) { table.push('<tr>'); for (var x = 0, xl = data[y].length; x < xl; x++) { table.push('<td id="'+ data[y][x].id +'" class="'+ (data[y][x].isRoadBlock === true ? 'map_close' : 'map_open') +'"></td>') } table.push('</tr>'); }; table.push('</tbody>'); table.push('</table>'); map.container = document.createElement('div'); map.container.innerHTML = table.join(''); return map.container; }, Node : function(x, y) { this.x = x; this.y = y; this.id = 'map_'+ x + '_' + y; this.isRoadBlock = false; this.prev = null; this.fObj = null; }, getNode : function(x, y) { return map.cache['map_'+ x + '_'+ y]; }, setStartNode : function(node) { map.startNode = node; }, setEndNode : function(node) { map.endNode = node; }, /** 检测当前开启列表中是否含有传进来的Node 存在则从开启列表中选中将其返回*/ _isOpenAreaExitNode : function(node) { var openArea = map.openArea; for (var i = 0, l = openArea.length; i < l; i++) { if (openArea[i].id === node.id) return openArea[i]; }; return null; }, getPath : function() { map.getAroundNode(map.startNode); if (map.openArea.length == 0) return; map.search(map.endNode); }, /** 获取当前点的F G H值 */ getF : function(cNode, aNode) { var energyW = Math.abs(map.endNode.x - aNode.x) * map.costEnergy_S; var energyH = Math.abs(map.endNode.y - aNode.y) * map.costEnergy_S; var _H = energyW + energyH; var _G = (Math.abs(aNode.x - cNode.x) === Math.abs(aNode.y - cNode.y) ? map.costEnergy_L : map.costEnergy_S); if (cNode.fObj) _G = cNode.fObj.G + _G; return { F : _H + _G, H : _H, G : _G }; }, /** 获取当前父节点周围的点 */ getAroundNode : function(node) { var maxHeight = map.girdHeight; var maxWidth = map.gridWidth; var nodeX; var nodeY; for (var x = -1; x <= 1; x++) { nodeX = node.x + x; for (var y = -1, mapNode, _fObj, tmpNode; y <= 1; y++) { nodeY = node.y + y; //剔除本身 以及斜角方向 if (x === 0 && y === 0 || Math.abs(x) == Math.abs(y)) continue; if (nodeX >= 0 && nodeY >= 0 && nodeX < maxWidth && nodeY < maxHeight) { mapNode = map.getNode(nodeX, nodeY); if (!map.closeArea[mapNode.id]) { _fObj = map.getF(node, mapNode); // 如果周围节点已在开启区域的 根据当前节点 获取新的G值 与当前点的进行比较 如果小于以前的G值 则指定当前节点为其父节点 tmpNode = map._isOpenAreaExitNode(mapNode); if (tmpNode) { if (tmpNode.fObj.G <= _fObj.G) continue; }; mapNode.fObj = _fObj; mapNode.prev = node; map.openArea.push(mapNode); }; }; }; }; }, /** 不断删除查找周围节点,直到找寻到结束点 */ search : function(node) { while(!map.closeArea[node.id]) { var _fMinNode = map._getFMin(); if (!_fMinNode) break; map.getAroundNode(_fMinNode); map.search(node); }; if (map.closeArea[node.id]) { map._drawRoad(node); }; }, /** 绘制路线 */ _drawRoad : function(node) { document.getElementById(node.id).style.background = '#EFA626'; if (node.prev !== map.startNode) map._drawRoad(node.prev); }, /** 从开启列表从寻找F点最小的点 从开启列表移除 移入关闭列表 */ _getFMin : function() { if (map.openArea.length == 0) return null; map._orderOpenArea(); map.closeArea[map.openArea[0].id] = map.openArea[0]; //document.getElementById(map.openArea[0].id).innerHTML = map.openArea[0].fObj.F + '^' + map.openArea[0].fObj.G + '^' + map.openArea[0].fObj.H; return map.openArea.shift(); }, /** 排序开启列表 */ _orderOpenArea : function() { this.openArea.sort(function(objF, objN) { return objF.fObj.F - objN.fObj.F; }); }, data : [], openArea : [], closeArea : {}, cache : {}, startNode : null, endNode : null, container : null }; (function() { map.roadBlock = 0.3; map.init(); var mapUI = map.getUI(); var startNode = null; var isRun = false; // 计时器 var Timer = function (){ this.startTime = + new Date; }; Timer.prototype.stop = function(){ return + new Date - this.startTime; }; document.getElementsByTagName('body')[0].appendChild(mapUI); mapUI.onclick = function(event) { event = event || window.event; var target = event.target || event.srcElement; if (isRun) return; if (target.nodeName !== "TD") return; var node = map.cache[target.id]; if (node.isRoadBlock) return; if (!node) return; if (startNode) { map.setEndNode(node); var time = new Timer; map.getPath(); document.title = '[' + time.stop() + '毫秒] ' + document.title; isRun = true; target.style.backgroundColor = 'red'; } else { startNode = node; map.setStartNode(node); target.style.backgroundColor = 'green'; }; }; })(); </script>

鉴于A* 还有8方向的 后来再4方向的基础上实现了下8方向

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html" charset="utf-8"><title>A* javascript</title><style type="text/css">.map{ background-color: #CCCCCC; }.map td{ width : 30px; height: 30px; }.map_close{ background-color: #000000; }.map_open{ background-color: #FFFFFF; }</style>
</head>
<body>
</body>
</html>
<script type="text/javascript">
var map = {gridWidth : 30,girdHeight : 20,roadBlock : 0.1,init : function() {map.costEnergy_S = 10;map.costEnergy_L = 14;map.openArea = [];map.closeArea = {};map._createMapData();},/**  创建网格数据 */_createMapData : function() {var cache = map.cache;map.data = [];for (var y = 0, _arr; y < map.girdHeight; y++) {_arr = [];for (var x = 0, mapNode; x < map.gridWidth; x++) {mapNode = new map.Node(x, y);if (Math.random() < map.roadBlock) {mapNode.isRoadBlock = true;map.closeArea[mapNode.id] = mapNode;};map.cache[mapNode.id] = mapNode;_arr.push(mapNode);};map.data.push(_arr);};},/**  建立地图网格 */getUI : function() {var table = [];var data = map.data;table.push('<table cellpadding="0" cellspacing="1" bgcolor="0" class="map">');table.push('<tbody>');for (var y = 0, yl = data.length; y < yl; y++) {table.push('<tr>');for (var x = 0, xl = data[y].length; x < xl; x++) {table.push('<td id="'+ data[y][x].id +'" class="'+ (data[y][x].isRoadBlock === true ? 'map_close' : 'map_open') +'"></td>')}table.push('</tr>');};table.push('</tbody>');table.push('</table>');map.container = document.createElement('div');map.container.innerHTML = table.join('');return map.container;},Node : function(x, y) {this.x = x;this.y = y;this.id = 'map_'+ x + '_' + y;this.isRoadBlock = false;this.prev = null;this.fObj = null;},getNode : function(x, y) {return map.cache['map_'+ x + '_'+ y];},setStartNode : function(node) {map.startNode = node;},setEndNode : function(node) {map.endNode = node;},/**  检测当前开启列表中是否含有传进来的Node 存在则从开启列表中选中将其返回*/_isOpenAreaExitNode : function(node) {var openArea = map.openArea;for (var i = 0, l = openArea.length; i < l; i++) {if (openArea[i].id === node.id) return openArea[i];};return null;},getPath : function() {map.getAroundNode(map.startNode);if (map.openArea.length == 0) return;map.search(map.endNode);},/**  获取当前点的F G H值 */getF : function(cNode, aNode) {var energyW = Math.abs(map.endNode.x - aNode.x) * map.costEnergy_S;var energyH = Math.abs(map.endNode.y - aNode.y) * map.costEnergy_S;var _H = energyW + energyH;var _G = (Math.abs(aNode.x - cNode.x) === Math.abs(aNode.y - cNode.y) ? map.costEnergy_L : map.costEnergy_S);if (cNode.fObj) _G = cNode.fObj.G + _G;return { F : _H + _G, H : _H, G : _G };},/**  获取当前父节点周围的点  */getAroundNode : function(node) {var maxHeight = map.girdHeight;var maxWidth = map.gridWidth;var nodeX;var nodeY;var corner = [];for (var x = -1; x <= 1; x++) {nodeX = node.x + x;for (var y = -1, mapNode, _fObj, tmpNode; y <= 1; y++) {nodeY = node.y + y;//剔除本身if (x === 0 && y === 0) continue;if (nodeX >= 0 && nodeY >= 0 && nodeX < maxWidth && nodeY < maxHeight) {mapNode = map.getNode(nodeX, nodeY);//查找周围的新节点, 如果新节点处于拐角则跳过if (Math.abs(x) == Math.abs(y) && map._isCorner(mapNode, { x : x, y : y })) continue;if (!map.closeArea[mapNode.id]) {_fObj = map.getF(node, mapNode);// 如果周围节点已在开启区域的 根据当前节点 获取新的G值  与当前点的进行比较 如果小于以前的G值 则指定当前节点为其父节点tmpNode =  map._isOpenAreaExitNode(mapNode);if (tmpNode) {if (tmpNode.fObj.G <= _fObj.G) continue;};mapNode.fObj = _fObj;mapNode.prev = node;map.openArea.push(mapNode);};};};};},/**  监测节点是否为拐角, 如果是 从开启列表中移除穿越拐角到达的点 */_isCorner : function(node, obj) {var closeArea = map.closeArea;var x = obj.x;var y = obj.y;var getNode = map.getNode;if (Math.abs(x) === Math.abs(y)) {if (x > 0 && y < 0) {return closeArea[new getNode(node.x, node.y + 1).id] || closeArea[new getNode(node.x - 1, node.y).id];};if (x < 0 && y > 0) {return closeArea[new getNode(node.x, node.y - 1).id] || closeArea[new getNode(node.x + 1, node.y).id];};if (x === y && x > 0) {return closeArea[new getNode(node.x, node.y - 1).id] || closeArea[new getNode(node.x - 1, node.y).id];};if (x === y && x < 0) {return closeArea[new getNode(node.x, node.y + 1).id] || closeArea[new getNode(node.x + 1, node.y).id];};};},/**  不断删除查找周围节点,直到找寻到结束点 */search : function(node) {while(!map.closeArea[node.id]) {var _fMinNode = map._getFMin();if (!_fMinNode) break;map.getAroundNode(_fMinNode);map.search(node);};if (map.closeArea[node.id]) {map._drawRoad(node);};},/**  绘制路线 */_drawRoad : function(node) {document.getElementById(node.id).style.background = '#EFA626';if (node.prev !== map.startNode) map._drawRoad(node.prev);},/**  从开启列表从寻找F点最小的点 从开启列表移除 移入关闭列表 */_getFMin : function() {if (map.openArea.length == 0) return null;map._orderOpenArea();map.closeArea[map.openArea[0].id] = map.openArea[0];//document.getElementById(map.openArea[0].id).innerHTML = map.openArea[0].fObj.F + '^' + map.openArea[0].fObj.G + '^' + map.openArea[0].fObj.H;return map.openArea.shift();},/**  排序开启列表 */_orderOpenArea : function() {this.openArea.sort(function(objF, objN) {return objF.fObj.F - objN.fObj.F;});},data : [],openArea : [],closeArea : {},cache : {},startNode : null,endNode : null,container : null
};(function() {map.roadBlock = 0.3;map.init();var mapUI = map.getUI();var startNode = null;var isRun = false;// 计时器var Timer = function (){this.startTime = + new Date;};Timer.prototype.stop = function(){return + new Date - this.startTime;};document.getElementsByTagName('body')[0].appendChild(mapUI);mapUI.onclick = function(event) {event = event || window.event;var target = event.target || event.srcElement;if (isRun) return;if (target.nodeName !== "TD") return;var node = map.cache[target.id];if (node.isRoadBlock) return;if (!node) return;if (startNode) {map.setEndNode(node);var time = new Timer;map.getPath();document.title = '[' + time.stop() + '毫秒] ' + document.title;isRun = true;target.style.backgroundColor = 'red';} else {startNode = node;map.setStartNode(node);target.style.backgroundColor = 'green';};};
})();
</script>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html" charset="utf-8"> <title>A* javascript</title> <style type="text/css"> .map{ background-color: #CCCCCC; } .map td{ width : 20px; height: 20px; } .map_close{ background-color: #000000; } .map_open{ background-color: #FFFFFF; } </style> </head> <body> </body> </html> <script type="text/javascript"> var map = { gridWidth : 30, girdHeight : 20, roadBlock : 0.1, init : function() { map.costEnergy_S = 10; map.costEnergy_L = 14; map.openArea = []; map.closeArea = {}; map._createMapData(); }, /** 创建网格数据 */ _createMapData : function() { var cache = map.cache; map.data = []; for (var y = 0, _arr; y < map.girdHeight; y++) { _arr = []; for (var x = 0, mapNode; x < map.gridWidth; x++) { mapNode = new map.Node(x, y); if (Math.random() < map.roadBlock) { mapNode.isRoadBlock = true; map.closeArea[mapNode.id] = mapNode; }; map.cache[mapNode.id] = mapNode; _arr.push(mapNode); }; map.data.push(_arr); }; }, /** 建立地图网格 */ getUI : function() { var table = []; var data = map.data; table.push('<table cellpadding="0" cellspacing="1" bgcolor="0" class="map">'); table.push('<tbody>'); for (var y = 0, yl = data.length; y < yl; y++) { table.push('<tr>'); for (var x = 0, xl = data[y].length; x < xl; x++) { table.push('<td id="'+ data[y][x].id +'" class="'+ (data[y][x].isRoadBlock === true ? 'map_close' : 'map_open') +'"></td>') } table.push('</tr>'); }; table.push('</tbody>'); table.push('</table>'); map.container = document.createElement('div'); map.container.innerHTML = table.join(''); return map.container; }, Node : function(x, y) { this.x = x; this.y = y; this.id = 'map_'+ x + '_' + y; this.isRoadBlock = false; this.prev = null; this.fObj = null; }, getNode : function(x, y) { return map.cache['map_'+ x + '_'+ y]; }, setStartNode : function(node) { map.startNode = node; }, setEndNode : function(node) { map.endNode = node; }, /** 检测当前开启列表中是否含有传进来的Node 存在则从开启列表中选中将其返回*/ _isOpenAreaExitNode : function(node) { var openArea = map.openArea; for (var i = 0, l = openArea.length; i < l; i++) { if (openArea[i].id === node.id) return openArea[i]; }; return null; }, getPath : function() { map.getAroundNode(map.startNode); if (map.openArea.length == 0) return; map.search(map.endNode); }, /** 获取当前点的F G H值 */ getF : function(cNode, aNode) { var energyW = Math.abs(map.endNode.x - aNode.x) * map.costEnergy_S; var energyH = Math.abs(map.endNode.y - aNode.y) * map.costEnergy_S; var _H = energyW + energyH; var _G = (Math.abs(aNode.x - cNode.x) === Math.abs(aNode.y - cNode.y) ? map.costEnergy_L : map.costEnergy_S); if (cNode.fObj) _G = cNode.fObj.G + _G; return { F : _H + _G, H : _H, G : _G }; }, /** 获取当前父节点周围的点 */ getAroundNode : function(node) { var maxHeight = map.girdHeight; var maxWidth = map.gridWidth; var nodeX; var nodeY; var corner = []; for (var x = -1; x <= 1; x++) { nodeX = node.x + x; for (var y = -1, mapNode, _fObj, tmpNode; y <= 1; y++) { nodeY = node.y + y; //剔除本身 if (x === 0 && y === 0) continue; if (nodeX >= 0 && nodeY >= 0 && nodeX < maxWidth && nodeY < maxHeight) { mapNode = map.getNode(nodeX, nodeY); //查找周围的新节点, 如果新节点处于拐角则跳过 if (Math.abs(x) == Math.abs(y) && map._isCorner(mapNode, { x : x, y : y })) continue; if (!map.closeArea[mapNode.id]) { _fObj = map.getF(node, mapNode); // 如果周围节点已在开启区域的 根据当前节点 获取新的G值 与当前点的进行比较 如果小于以前的G值 则指定当前节点为其父节点 tmpNode = map._isOpenAreaExitNode(mapNode); if (tmpNode) { if (tmpNode.fObj.G <= _fObj.G) continue; }; mapNode.fObj = _fObj; mapNode.prev = node; map.openArea.push(mapNode); }; }; }; }; }, /** 监测节点是否为拐角, 如果是 从开启列表中移除穿越拐角到达的点 */ _isCorner : function(node, obj) { var closeArea = map.closeArea; var x = obj.x; var y = obj.y; var getNode = map.getNode; if (Math.abs(x) === Math.abs(y)) { if (x > 0 && y < 0) { return closeArea[new getNode(node.x, node.y + 1).id] || closeArea[new getNode(node.x - 1, node.y).id]; }; if (x < 0 && y > 0) { return closeArea[new getNode(node.x, node.y - 1).id] || closeArea[new getNode(node.x + 1, node.y).id]; }; if (x === y && x > 0) { return closeArea[new getNode(node.x, node.y - 1).id] || closeArea[new getNode(node.x - 1, node.y).id]; }; if (x === y && x < 0) { return closeArea[new getNode(node.x, node.y + 1).id] || closeArea[new getNode(node.x + 1, node.y).id]; }; }; }, /** 不断删除查找周围节点,直到找寻到结束点 */ search : function(node) { while(!map.closeArea[node.id]) { var _fMinNode = map._getFMin(); if (!_fMinNode) break; map.getAroundNode(_fMinNode); map.search(node); }; if (map.closeArea[node.id]) { map._drawRoad(node); }; }, /** 绘制路线 */ _drawRoad : function(node) { document.getElementById(node.id).style.background = '#EFA626'; if (node.prev !== map.startNode) map._drawRoad(node.prev); }, /** 从开启列表从寻找F点最小的点 从开启列表移除 移入关闭列表 */ _getFMin : function() { if (map.openArea.length == 0) return null; map._orderOpenArea(); map.closeArea[map.openArea[0].id] = map.openArea[0]; //document.getElementById(map.openArea[0].id).innerHTML = map.openArea[0].fObj.F + '^' + map.openArea[0].fObj.G + '^' + map.openArea[0].fObj.H; return map.openArea.shift(); }, /** 排序开启列表 */ _orderOpenArea : function() { this.openArea.sort(function(objF, objN) { return objF.fObj.F - objN.fObj.F; }); }, data : [], openArea : [], closeArea : {}, cache : {}, startNode : null, endNode : null, container : null }; (function() { map.roadBlock = 0.3; map.init(); var mapUI = map.getUI(); var startNode = null; var isRun = false; // 计时器 var Timer = function (){ this.startTime = + new Date; }; Timer.prototype.stop = function(){ return + new Date - this.startTime; }; document.getElementsByTagName('body')[0].appendChild(mapUI); mapUI.onclick = function(event) { event = event || window.event; var target = event.target || event.srcElement; if (isRun) return; if (target.nodeName !== "TD") return; var node = map.cache[target.id]; if (node.isRoadBlock) return; if (!node) return; if (startNode) { map.setEndNode(node); var time = new Timer; map.getPath(); document.title = '[' + time.stop() + '毫秒] ' + document.title; isRun = true; target.style.backgroundColor = 'red'; } else { startNode = node; map.setStartNode(node); target.style.backgroundColor = 'green'; }; }; })(); </script>

关于A*算法的原理 参考 http://hi.baidu.com/jklzt/blog/item/cbfc1d3e03ab8e19baa167b4.html

转载于:https://www.cnblogs.com/oneroundseven/archive/2012/02/14/2351130.html

A*算法 javascript模拟相关推荐

  1. 资料分享:送你一本《数据结构与算法JavaScript描述》电子书!

    数据结构 是掌握计算机编程必须具备的技能.通常情况下,我想掌握一门编程语言所用的方法就是利用这门语言把数据结构中线性表.栈.队列.字符串.动态数字.整数集合.树.图.搜索.排序等涉及的算法全部写一遍. ...

  2. 数据结构与算法JavaScript (一) 栈

    序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...

  3. 蝗虫算法java代码_蝗虫搜索算法 蝗虫算法:蝗虫优化算法是模拟自然界蝗虫种群捕食行为而提出的一 联合开发网 - pudn.com...

    蝗虫搜索算法 所属分类:其他 开发工具:matlab 文件大小:347KB 下载次数:5 上传日期:2020-07-26 16:31:25 上 传 者:西柚不加冰 说明:  蝗虫算法:蝗虫优化算法是模 ...

  4. 操作系统课设之虚拟内存页面置换算法的模拟与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  5. Javascript模拟c#中arraylist操作(学习分享)

    最近在看javascript,在<javascript高级编程>中也学到了不少东西.但是在这里要感谢博客园的"汤姆大叔" 的无私奉献,他的关于javascript相关博 ...

  6. 模拟运行php,window_PHP+Javascript模拟Matrix画面, 直接存为*.php文件运行即 - phpStudy...

    PHP+Javascript模拟Matrix画面 直接存为*.php文件运行即可. $color_back="#000000"; $number_w=8; $number_h=6; ...

  7. [小笔记]TypeScript/JavaScript模拟Python中的Range函数

    [小笔记]TypeScript/JavaScript 模拟Python中的Range函数 李俊才/CSDN博客 CSDN用户名:jcLee95 邮箱:291148484@163.com 原创不易,感谢 ...

  8. 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象

    文章目录 一.JavaScript模拟面向对象 1.函数是类 2.函数中各种变量的声明 3.关于函数内的this 小结:JavaScript中函数是什么? 4.练习:面向对象思想编写Complex类 ...

  9. 最坏适应算法的模拟(c++实现)

    实验要求 1)实现一个完整的(可变)动态分区管理器,包括分配,回收,分区碎片整理等.希望同学们实现如下功能: 2)初始化功能:内存状态设置为初始状态. 3)分配功能:采用最佳适应算法进行分配. 4)回 ...

最新文章

  1. C语言的 32个关键之和9个控制语言之关键字
  2. ScrollView 嵌套EditText 滑动冲突解决
  3. 蚂蚁金服移动端可视化解决方案 F2 3.2 正式发布
  4. 使用dbunit和system-rules测试代码
  5. Css基本语法及页面引用
  6. Spring Boot数据持久化之NamedParameterJdbcTemplate
  7. Subsequence Count (线段树)
  8. Hex Editor Crack版,十六进制编辑器使用方案
  9. 世园会开幕式上的机器人_小胖机器人驻扎“2019北京世园会”媒体分会场
  10. matlab mcc-m,【matlab】matlab中 mcc、mbuild和mex命令详解
  11. 采用汇编语言对c语言函数调用的方法求平均数 汇编实验报告,汇编措辞调用C措辞求平均数.doc...
  12. Blend for Visual Studio 概述
  13. zookeeper windows7下集群搭建
  14. 备库ORA-00313 ORA-00312 ORA-27037
  15. github监控平台hawkeye搭建
  16. 一分钟快速将ogg转换成MP3格式
  17. B2117 整理药名
  18. sharemouse切窗口就锁定了什么原因_iPhone 提示“Apple ID 已锁定”是什么原因?
  19. 【web安全】——逻辑漏洞之越权漏洞
  20. 动网论坛dvbbs7.1.0 SP1由Access版升级到SQL版的具体说明(用于全新安装)

热门文章

  1. 如何写好一份渗透测试报告
  2. (九)洞悉linux下的Netfilteramp;iptables:网络地址转换原理之DNAT
  3. BestCoder 2nd Anniversary
  4. 继承CListCtrl,然后重载OnLButtonUP消息,发现变成双击才触发???
  5. .NET中的IO操作之文件流
  6. 【我看Hibernate】Hibernate 介绍及其简单应用
  7. flaash-ACC_LSMOOTH2: Cannot continue with smoothing calculation
  8. CSP:CSP认证考试:202012-1(期末预测之安全指数)满分答案,Java版
  9. 快速学习ggplot2
  10. 适合写python的电脑_这篇写给想选计算机专业的学弟学妹们