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;
}

  

时间: 2024-08-16 16:06:09

javascript的Astar版 寻路算法的相关文章

【JavaScript】【算法】JavaScript版排序算法

JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) 1 //排序算法 2 window.onload = function(){ 3 var array = [0,1,2,44,4, 4 324,5,65,6,6, 5 34,4,5,6,2, 6 43,5,6,62,43, 7 5,1,4,51,56, 8 76,7,7,2,1, 9 45,4,6,7,8]; 10 //var array = [4,2,5,1,0,3]; 11 array

算法:Astar寻路算法改进,双向A*寻路算法

早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢? 我们知道,A*的时间复杂度是和节点数量以及起始点难度呈幂函数正相关的. 这个http://qiao.github.io/PathFinding.js/visual/该网址很好的演示了双向A*的效果,我们来看一看. 绿色表示起点,红色表示终点,灰色是墙面.稍浅的两种绿色分别代表open节点和close节点:

javascript 回溯寻路算法

最近一直在手游 caveboy escape(安卓上,不知道IOS上有没有,可以下来玩玩). 游戏规则是,在5x5的矩阵,从最下面的起点,每个颜色走三步,到达最上面的重点. 想写个js版本.碰到第一个问题就是,矩阵布局,寻路算法. 网上搜了下只有 PathFinding.js 带有的著名的 A*寻路法(自己百度) 源码: https://github.com/qiao/PathFinding.js DEMO: http://qiao.github.io/PathFinding.js/visual

A*(也叫A star, A星)寻路算法Java版

寻路算法有很多种,A*寻路算法被公认为最好的寻路算法. 首先要理解什么是A*寻路算法,可以参考这三篇文章: http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003(英文) http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html(中文) http://www.cnblog

算法:Astar寻路算法改进

早前写了一篇<RCP:gef智能寻路算法(A star)> 出现了一点问题. 在AStar算法中,默认寻路起点和终点都是N x N的方格,但如果用在路由上,就会出现问题. 如果,需要连线的终点并不在方格的四角上,就产生了斜线.于是我们可以对终点附近的点重新做一点儿处理,源码如下所示: int size = points.size(); if (size < 3) return; points.removePoint(size - 1); Point pointN1 = points.ge

C#实现简单的AStar寻路算法

1.算法实施模型 在我看来,最简单最基础的寻路环境是:在一片二维网格区域中存在一些围墙(Block),在起始点和终点之间保持连通的前提下寻找一条最佳路径. 2.算法原理 详细介绍有很多,可参考网址:http://www.policyalmanac.org/games/aStarTutorial.htm,浅显易懂,重点是理解"启发式搜索"的概念.下面谈谈我自己的理解,如果是第一次接触A*寻路算法,还是先老老实实看完给出的参考网址吧(当然也可以参考相关的中文介绍资料). 在一片二维网格中,

[转] A*寻路算法C++简单实现

参考文章: http://www.policyalmanac.org/games/aStarTutorial.htm   这是英文原文<A*入门>,最经典的讲解,有demo演示 http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html  这是国人翻译后整理的简版,有简单代码demo,不过有些错误,讲得很清晰,本文图片来自这篇 http://blog.csdn.net/b2b160/article/details/4057

PHP树生成迷宫及A*自己主动寻路算法

PHP树生成迷宫及A*自己主动寻路算法 迷宫算法是採用树的深度遍历原理.这样生成的迷宫相当的细,并且死胡同数量相对较少! 随意两点之间都存在唯一的一条通路. 至于A*寻路算法是最大众化的一全自己主动寻路算法 完整代码已上传,http://download.csdn.net/detail/hello_katty/8885779 ,此处做些简单解释,还须要大家自己思考动手.废话不多说,贴上带代码 迷宫生成类: /** 生成迷宫类 * @date 2015-07-10 * @edit http://w

RCP:gef智能寻路算法(A star)

本路由继承自AbstactRouter,参数只有EditPart(编辑器内容控制器),gridLength(寻路用单元格大小),style(FLOYD,FLOYD_FLAT,FOUR_DIR). 字符集编码为GBK,本文只做简单的代码解析,源码戳我 如果源码不全,可以联系本人. 算法实现主要有三: 1.Astar单向寻路 2.地图预读 3.弗洛伊德平滑算法 Astar寻路的实现: ANode minFNode = null; while (true) { minFNode = findMinNo