A*寻路算法(JavaScript实现)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
div{
position: absolute;
width: 50px;
height: 50px;
margin: 1px 1px;
background-color: gray;
border: 1px dashed #cccccc;
}
body{
position: relative;
font-family: "微软雅黑"; }
header,
section
{
position: relative;
margin: 0 auto;
width: 998px;
} </style>
</head>
<body>
<header>
<h1>A*寻路demo演示</h1>
<table>
<tr>
<td>输入地图列数(最大15列):</td>
<td><input id="rowInput" type="text"/></td>
</tr>
<tr>
<td>请输入地图行数(最大15行):</td>
<td><input id="colInput" type="text"></td>
</tr>
<tr>
<td></td>
<td><input id="createMapBtn" type="button" value="点击生成地图"/></td>
</tr>
<tr>
<td id="prompt">test...</td>
<td><input id="findPoint" type="button" value="开始寻路" style="display: none"/></td>
</tr> </table> </header> <section id="main"></section> <script>
function Point(){
this.x=0;
this.y=0;
this.G=0;//G值 开始点 到当前点的移动量
this.H=0;//H值 当前点移动目的地的移动量估算值
this.father=null;
};
Point.prototype={
Console:function(){
console.log("x:"+this.x+" and y:"+this.y);
},
Init:function(x,y,father){
this.x=x;
this.y=y;
this.father=father;
}
};
function AStar(){
//地图存放二维数组
this.map=[];
//行数
this.rowCount=0;
//列数
this.colCount=0;
//出发点
this.startPoint=new Point();
//终点
this.endPoint=new Point();
//存放Opint类的open数组
this.openList=[];
//存在Opint类的close数组
this.closeList=[];
};
AStar.prototype={
//是否为障碍物
IsBar:function(x,y){
if(this.map[x][y]==3){
console.log("bar...");
return true;
}
else{
console.log("no bar...")
return false;
}
},
//当前坐标是否在OpenList
IsInOpenList:function(x,y){
for(var i=0;i<this.openList.length;i++){
if(this.openList[i].x==x&&this.openList[i].y==y){
return true;
} }
return false;
},
//当前坐标是否在CloseList
IsInCloseList:function(x,y){
for(var i=0;i<this.closeList.length;i++){
if(this.closeList[i].x==x&&this.closeList[i].y==y){
return true;
} }
return false;
},
//计算G值;(p是Point类)
GetG:function(p){
if(p.father==null){
return 0;
}
return p.father.G+1;
},
//计算H值
GetH:function(p,pb){
return Math.abs(p.x-pb.x)+Math.abs(p.y-pb.y);
},
//添加当前点的上下左右相邻的方格到Open列表中
AddNeiToOpenList:function(curPoint){
for(var x=curPoint.x-1;x<=curPoint.x+1;x++){
for(var y=curPoint.y-1;y<=curPoint.y+1;y++){
//排除自身以及超出下标的点
if((x>=0&&x<this.colCount&&y>=0&&y<this.rowCount)&&!(curPoint.x==x&&curPoint.y==y)){
//排除斜对角
if(Math.abs(x-curPoint.x)+Math.abs(y-curPoint.y)==1){
//不是障碍物且不在关闭列表中
if(this.IsBar(x,y)==false&&this.IsInCloseList(x,y)==false){
//不存在Open列表
if(this.IsInOpenList(x,y)==false){
var point=new Point();
point.x=x;
point.y=y;
point.father=curPoint;
point.G=this.GetG(point);
point.H=this.GetH(point,this.endPoint);
this.openList.push(point);
}
}
}
}
}
}
},
//在openlist集合中获取G+H为最小的Point点
GetMinFFromOpenList:function(){
var minPoint=null;
var index=0;
for(var i=0;i<this.openList.length;i++){
if(minPoint==null||minPoint.G+minPoint.H>=this.openList[i].G+this.openList[i].H){
minPoint=this.openList[i];
index=i;
}
}
return{
minPoint:minPoint,
index:index
}
}, GetPointFromOpenList:function(x,y){
for(var i=0;i<this.openList.length;i++){
if(this.openList[i].x==x&&this.openList[i].y==y){
return this.openList[i];
}
}
return null; },
//开始寻找节点
FindPoint:function(){
console.log(this);
this.openList.push(this.startPoint);
while(this.IsInOpenList(this.endPoint.x,this.endPoint.y)==false||this.openList.length==0){
var curPoint=this.GetMinFFromOpenList().minPoint;
console.log("curPoint:"+curPoint);
var index=this.GetMinFFromOpenList().index;
if(curPoint==null){
console.log("没有路");
return;
}
this.openList.splice(index,1);
this.closeList.push(curPoint);
this.AddNeiToOpenList(curPoint);
}
var p=this.GetPointFromOpenList(this.endPoint.x,this.endPoint.y);
console.log(p+".....");
while(p.father!=null){
p= p.father;
console.log("father..");
this.map[p.x][p.y]=4;
}
//把终结点也设置成4
this.map[this.endPoint.x][this.endPoint.y]=4;
},
PrintMap:function(){ } };
//地图类 map数组保存数字标识 :0 默认 1 开始点 2 结束点 3 障碍物
function Map(id){
this.map=[];
this.container=document.getElementById(id);
this.colCount=0;
this.rowCount=0;
}
Map.prototype={
init:function(colCount,rowCount){
this.colCount=colCount;
this.rowCount=rowCount;
for(var colIndex=0;colIndex<this.colCount;colIndex++){
this.map.push([]);
for(var rowIndex=0;rowIndex<this.rowCount;rowIndex++){
this.map[colIndex].push(0);
}
}
},
drawMap:function(callback){
for(var colIndex=0;colIndex<this.map.length;colIndex++){
for(var rowIndex=0;rowIndex<this.map[colIndex].length;rowIndex++){
var div=document.createElement("div");
div.style.top=colIndex*50+5+"px";
div.style.left=rowIndex*50+5+"px";
div.setAttribute("colIndex",colIndex);
div.setAttribute("rowIndex",rowIndex);
div.onclick=callback;
this.container.appendChild(div);
} } },
drawPoints:function(){
var divs=this.container.children;
console.log(divs.length);
console.log(this.map);
var timer=1000;
for(var i=0;i<divs.length;i++){
var colIndex=divs[i].getAttribute("colIndex");
var rowIndex=divs[i].getAttribute("rowIndex");
if(this.map[colIndex][rowIndex]==4){
divs[i].style.backgroundColor="red";
}
}
},
getPoint:function(colIndex,rowIndex){
return this.map[colIndex][rowIndex];
},
setStartPoint:function(colIndex,rowIndex){
this.map[colIndex][rowIndex]=1;
},
setEndPoint:function(colIndex,rowIndex){
this.map[colIndex][rowIndex]=2;
},
setBarPoint:function(colIndex,rowIndex){
this.map[colIndex][rowIndex]=3;
},
clearMap:function(){
this.map.splice(0,this.map.length);
this.container.innerHTML="";
} } var rowInput=document.querySelector("#rowInput");
var colInput=document.querySelector("#colInput");
var createMapBtn=document.querySelector("#createMapBtn");
var prompt=document.querySelector("#prompt");
var findPoint=document.querySelector("#findPoint");
var curMap=new Map("main");
var state=0;//状态标识 0选择开始节点标识 1选择结束节点标识 2选择障碍物标识
var aStar=new AStar();//寻路类 createMapBtn.onclick=function(){ curMap.clearMap();
curMap.init(colInput.value,rowInput.value);
aStar.map=curMap.map;
aStar.colCount=colInput.value;
aStar.rowCount=rowInput.value;
curMap.drawMap(function(){
var colIndex=this.getAttribute("colIndex");
var rowIndex=this.getAttribute("rowIndex");
if(curMap.getPoint(colIndex,rowIndex)!=0){
return;
}
if(state==0){
this.style.backgroundColor="blue";
curMap.setStartPoint(colIndex,rowIndex);
aStar.startPoint.x=colIndex;
aStar.startPoint.y=rowIndex;
state=1;
prompt.innerHTML="请点击格子,设置终点"; }else if(state==1){
this.style.backgroundColor="yellow";
curMap.setEndPoint(colIndex,rowIndex);
aStar.endPoint.x=colIndex;
aStar.endPoint.y=rowIndex;
prompt.innerHTML="请点击格子,设置障碍物";
console.log(findPoint);
findPoint.style.display="block";
state=2;
}else if(state==2){
curMap.setBarPoint(colIndex,rowIndex);
this.style.backgroundColor="black";
}
});
prompt.innerHTML="请点击格子,设置起始点";
}
findPoint.onclick=function(){
console.log(aStar.map);
aStar.FindPoint();
curMap.drawPoints();
} </script> </body>
</html>
A*寻路算法(JavaScript实现)的更多相关文章
- javascript的Astar版 寻路算法
去年做一个模仿保卫萝卜的塔防游戏的时候,自己写的,游戏框架用的是coco2d-html5 实现原理可以参考 http://www.cnblogs.com/technology/archive/2011 ...
- 读《数据结构与算法 Javascript描述》 | 平淡无奇
“平淡无奇”,一句话总结. 当初买这本书的原因,在意的是有没有什么令人惊喜的东西,特别是针对Javascript代码的奇思妙想,所以就买下了这本书. 在买的几本书里面,最先看的也是这一本,但看起目录就 ...
- 不再依赖A*,利用C++编写全新寻路算法
一,说在前面的话 大概在半年前,看见一到信息竞赛题:在任意方格阵中设置障碍物,确定起始点后,求这两点之间路径.当时觉得蛮有意思的,但是没有时间去做,今天花了两个小时来实现它.据说有一个更高级的寻路算法 ...
- PHP树生成迷宫及A*自己主动寻路算法
PHP树生成迷宫及A*自己主动寻路算法 迷宫算法是採用树的深度遍历原理.这样生成的迷宫相当的细,并且死胡同数量相对较少! 随意两点之间都存在唯一的一条通路. 至于A*寻路算法是最大众化的一全自己主动寻 ...
- A星寻路算法介绍
你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...
- A*寻路算法探究
A*寻路算法探究 A*算法常用在游戏的寻路,是一种静态网路中求解最短路径的搜索方法,也是解决很多搜索问题的算法.相对于Dijkstra,BFS这些算法在复杂的搜索更有效率.本文在U3D中进行代码的测试 ...
- A*寻路算法
对于初学者而言,A*寻路已经是个比较复杂的算法了,为了便于理解,本文降低了A*算法的难度,规定只能横竖(四方向)寻路,而无法直接走对角线,使得整个算法更好理解. 简而言之,A*寻路就是计算从起点经过该 ...
- 数据结构与算法JavaScript (一) 栈
序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...
- 算法:Astar寻路算法改进,双向A*寻路算法
早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢 ...
随机推荐
- easyui datagrid columns field 如何支持一个或多个子属性
//如果只需要一个子属性从value出发 {field:'customer',title:'会员手机',width:100, formatter: function(value,row,index){ ...
- iOS 趣谈设计模式——通知
[前言介绍] iOS的一种设计模式,观察者Observer模式(也叫发布/订阅,即Publich/Subscribe模式). 观察者模式,包含了通知机制(notification)和KVO(Key-v ...
- 所有古诗词的api
服务商:api.getlove.cn 分类:诗词 更新时间:2016-03 如果接口不满足您的要求,您可以联系qq:2265658022购买完整的数据库 免费apikey:56eab527a0facb ...
- CSS VS JS动画,哪个更快[译]
英文原文:https://davidwalsh.name/css-js-animation 原作者Julian Shapiro是Velocity.js的作者,Velocity.js是一个高效易用的js ...
- 整理一下自己用到的SVN几个命令
第一步 svn co 代码分支(http://yyyyyyyyyyyyyyyy) 将开发给的代码分支地址中的代码拉到测试机中 第二步 cd /目录 进入需要拉代码的目录 然后 ll 查看目录下的 ...
- html5设计原理(转)
转自: http://www.cn-cuckoo.com/2010/10/21/the-design-of-html5-2151.html 今天我想跟大家谈一谈HTML5的设计.主要分两个方面:一 ...
- CHARINDEX
实现查询条件多个值的或的关系 Select Id,Name from CustTable where CharIndex( CustTable.Name, 'ACDE,BEX,CCC')>0 C ...
- 1045 access denied for user 'root'@'localhost' using password yes的解决方法
今天把一个项目和项目的数据库都下载到了本地,安装好项目和在本地配置好数据库后,在浏览器登陆项目的后台却出现了以下错误: 后来上百度搜索了好几个答案,都是讲述修改数据库密码的步骤,但是就是没有说明为 ...
- java上传xls文件
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System. ...
- html尖角提示框的实现
<style type="text/css"> .box { background-color: #bebf22; ...