javascript的Astar版 寻路算法
去年做一个模仿保卫萝卜的塔防游戏的时候,自己写的,游戏框架用的是coco2d-html5
实现原理可以参考 http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
这个算法项目一直放在github中,朋友们需要的可以自己去看下
https://github.com/caoke90/Algorithm/blob/master/Astar.js
//Astar 寻路算法
//Point 类型
var cc=cc||console
var Point=function(x,y){
if(this instanceof Point){
this.init(x,y)
}else{
return new Point(x,y)
} }
Point.prototype={
init:function(x,y){
this.x=x;
this.y=y;
},
ParentPoint:null,
F :0, //F=G+H
G:0,
H:0,
x:0,
y:0,
CalcF:function(){
this.F = this.G + this.H;
}
} //Maze 类型
var Maze=function(maze){
if(this instanceof Maze){
this.init(maze);
}else{
return new Maze(maze)
}
}
Maze.prototype={
init:function(maze){
this.MazeArray=maze
},
OBLIQUE : 14,
STEP:10,
CloseList:[],
OpenList:[],
FindPath:function(start, end, IsIgnoreCorner){
this.OpenList.push(start);
while (this.OpenList.length != 0)
{
//找出F值最小的点
var tempStart = this.MinPoint(this.OpenList);
this.CloseList.push(tempStart);
this.Remove(this.OpenList,tempStart); //找出它相邻的点
var surroundPoints = this.SurrroundPoints(tempStart, IsIgnoreCorner);
for (var i=0;i< surroundPoints.length;i++)
{
var point=surroundPoints[i]
if (this.Exists(this.OpenList,point)){
//计算G值, 如果比原来的大, 就什么都不做, 否则设置它的父节点为当前点,并更新G和F
this.FoundPoint(tempStart, point);
}
else{
//如果它们不在开始列表里, 就加入, 并设置父节点,并计算GHF
this.NotFoundPoint(tempStart, end, point);
}
}
if (this.Get(this.OpenList,end) != null){
return this.Get(this.OpenList,end);
}
}
return this.Get(this.OpenList,end);
},
//在二维数组对应的位置不为障碍物
CanReaches:function(x,y){
return this.MazeArray[this.MazeArray.length-y-1][x] == 0;
},
CanReach:function( start, point, IsIgnoreCorner){
if (!this.CanReaches(point.x, point.y) || this.Exists(this.CloseList,point))
return false;
else
{
if ((Math.abs(point.x - start.x) + Math.abs(point.y - start.y)) == 1){
return true;
}
return false;
}
},
NotFoundPoint:function(tempStart, end, point){
point.ParentPoint = tempStart;
point.G = this.CalcG(tempStart, point);
point.H = this.CalcH(end, point);
point.CalcF();
this.OpenList.push(point); },
FoundPoint:function(tempStart, point){
var G = this.CalcG(tempStart, point);
if (G < point.G)
{
point.ParentPoint = tempStart;
point.G = G;
point.CalcF();
}
},
CalcG:function(start, point)
{
var G = (Math.abs(point.X - start.X) + Math.abs(point.Y - start.Y)) == 2 ? this.OBLIQUE:this.STEP ;
var parentG = point.ParentPoint != null ? point.ParentPoint.G : 0;
return G + parentG;
}, CalcH:function( end, point)
{
var step = Math.abs(point.x - end.x) + Math.abs(point.y - end.y);
return step * this.STEP;
}, //获取某个点周围可以到达的点
SurrroundPoints:function( point, IsIgnoreCorner)
{
var surroundPoints = [];
if (this.CanReach(point,Point(point.x-1,point.y),IsIgnoreCorner)){
surroundPoints.push(Point(point.x-1,point.y));
}
if (this.CanReach(point,Point(point.x,point.y-1),IsIgnoreCorner)){
surroundPoints.push(Point(point.x,point.y-1));
}
if (this.CanReach(point,Point(point.x+1,point.y),IsIgnoreCorner)){
surroundPoints.push(Point(point.x+1,point.y));
}
if (this.CanReach(point,Point(point.x,point.y+1),IsIgnoreCorner)){
surroundPoints.push(Point(point.x,point.y+1));
}
return surroundPoints;
}, //对 List<Point> 的一些扩展方法
//判断是否存在点
Exists:function(points, point)
{
for(k in points){
var p=points[k]
if ((p.x == point.x) && (p.y == point.y)){
return true;
}
}
return false;
},
//获取f最小
MinPoint:function (points)
{
var min=points[0];
for(var i=0;i<points.length-1;i++){
if(points[i].F<points[i+1].F){
min=points[i]
}
}
return min;
},
//获取点
Get:function(points, point)
{
for (var k in points){
var p=points[k]
if ((p.x == point.x) && (p.y == point.y))
return p;
}
return null;
},
//删除点
Remove:function(points,point)
{
for(var i=0;i<points.length;i++){
var p=points[i]
if (point.x === p.x && point.y === p.y){
return points.splice(i,1);
}
} } } var arr= [
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]; var map=Maze(arr)
//起始点 结束点 是否斜角
var parent=map.FindPath(Point(2,3),Point(16,2),false) while (parent != null)
{
cc.log(parent.x + ", " + parent.y);
parent = parent.ParentPoint;
}
javascript的Astar版 寻路算法的更多相关文章
- 算法:Astar寻路算法改进,双向A*寻路算法
早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢 ...
- 算法:Astar寻路算法改进
早前写了一篇<RCP:gef智能寻路算法(A star)> 出现了一点问题. 在AStar算法中,默认寻路起点和终点都是N x N的方格,但如果用在路由上,就会出现问题. 如果,需要连线的 ...
- JavaScript版排序算法
JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) //排序算法 window.onload = function(){ var array = ...
- C#实现AStar寻路算法
AStar寻路算法是一种在一个静态路网中寻找最短路径的算法,也是在游戏开发中最常用到的寻路算法之一:最近刚好需要用到寻路算法,因此把自己的实现过程记录下来. 先直接上可视化之后的效果图,图中黑色方格代 ...
- 一个高效的A-star寻路算法(八方向)(
这种写法比较垃圾,表现在每次搜索一个点要遍历整个地图那么大的数组,如果地图为256*256,每次搜索都要执行65535次,如果遍历多个点就是n*65535,速度上实在是太垃圾了 简单说下思路,以后补充 ...
- A*(也叫A star, A星)寻路算法Java版
寻路算法有非常多种,A*寻路算法被公觉得最好的寻路算法. 首先要理解什么是A*寻路算法,能够參考这三篇文章: http://www.gamedev.net/page/resources/_/techn ...
- [转] A*寻路算法C++简单实现
参考文章: http://www.policyalmanac.org/games/aStarTutorial.htm 这是英文原文<A*入门>,最经典的讲解,有demo演示 http: ...
- 不再依赖A*,利用C++编写全新寻路算法
一,说在前面的话 大概在半年前,看见一到信息竞赛题:在任意方格阵中设置障碍物,确定起始点后,求这两点之间路径.当时觉得蛮有意思的,但是没有时间去做,今天花了两个小时来实现它.据说有一个更高级的寻路算法 ...
- PHP树生成迷宫及A*自己主动寻路算法
PHP树生成迷宫及A*自己主动寻路算法 迷宫算法是採用树的深度遍历原理.这样生成的迷宫相当的细,并且死胡同数量相对较少! 随意两点之间都存在唯一的一条通路. 至于A*寻路算法是最大众化的一全自己主动寻 ...
随机推荐
- Flask解决跨域
Flask解决跨域 问题:网页上(client)有一个ajax请求,Flask sever是直接返回 jsonify. 然后ajax就报错:No 'Access-Control-Allow-Origi ...
- [GO]工程管理
同级目录: 1.分文件编程,多个源文件,必须放在src目录 2.设置GOPATH目录,目录地址不包括src后缀 3.同一个目录,包名必须一样 4.go env查看go相关的环境路径 5.同一个目录,调 ...
- MVC下的cshtml和aspx页面
MVC中的aspx页面是System.Web.Mvc.ViewPage类的实例. 表示将视图呈现为 Web 窗体页所需的属性和方法. 继承层次结构 System.Object System.Web.U ...
- Java 自定义异常类
类1:public class LogicException extends RuntimeException { //业务逻辑异常 /** * * @param mes ...
- 【Android学习】Android编码规范
四种常见的命名法 比较Java和c#的命名规范的不同点 常量用大写 java方法首字母不大写,应该小写 函数行数限制 不要用拼音 参照物,Android源码 看源码工具,SourceInsight 和 ...
- Socket编程(c语言示例)
转自:http://blog.csdn.net/dxpqxb/article/details/8166423 前言 Socket可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序 ...
- C# static 字段初始值设定项无法引用非静态字段、方法或属性
问题:字段或属性的问题字段初始值设定项无法引用非静态字段.方法 下面代码出错的原因,在类中定义的字段为什么不能用? public string text = test(); //提示 字段或属性的问题 ...
- 关于 XML 字段内容查询
找到个总结相当好的知识点的归纳,记在自己的博客里也方便查询 /* sql xml 入门: --by jinjazz --http://blog.csdn.net/jinjazz ...
- C# DataGridView控件动态添加新行
C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...
- Android学习笔记 Gallery图库组件的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...