A星算法JavaScript版本

A星算法

引见

javascript完成A星寻路算法

  1. 在游戏中常有须要主角/仇人去移动到某个物品或许追随仇人的时刻,这个时刻,能够运用寻路算法
  2. 为了完成canvas游戏,须要寻路算法,因而便本身用JS完成了一下

道理思绪

简化搜刮地区:

  1. 为了削减资本斲丧,起首须要我们将舆图分割为区块,如下图

    《A星算法JavaScript版本》

    2.竖立出发点和尽头坐标,用于寻路

保护open和close列表

  1. 我们新建两个列表,一个open表,它记录了一切被斟酌的寻路点;一个close表,它记录了一切不再被斟酌的点
  2. 我们要做的是接下来对两个表的保护

搜刮途径

  1. 怎样寻路呢,起首我们引入3个量

    1. G值,也就是当前点到起始点所需的价值
    2. H值,不斟酌一切停滞等要素,该点到尽头非斜线体式格局的预算量,也就是x+y的值
    3. F值,也就是该点的G+H的值
    4. 如图所示,左上角为F,右上角为H,左下为G:
      《A星算法JavaScript版本》
  2. 接下来是寻路详细完成

    1. 起首最小F值的点到场open,点暂记为curr点
    2. 将curr点移除open,到场close
    3. 关于curr相邻点,都有以下步骤

      1. 在close或许是停滞,不管它
      2. 不在open中,则盘算它的各项值,到场open
      3. 在open中,则盘算我们当前这条途径抵达这个点是不是有更小F值,是则更新它的F值
    4. 检测到当前途径点和尽头一致时刻则完毕寻路;假如open中为空,则代表没有适宜的寻路计划,寻路失利
  3. JS完成的详细计划

    1. 起首竖立一个Sopt的类,它内里包括以下信息

      1. 属性:x,y,f,g,h,isWall,neighbors,parents,
      2. 要领addNeighbors,用于增加四周8个格子能够增加的点
    2. 初始化舆图一切点,运转addNeighbors要领,将neighbors数组初始化
    3. 竖立寻路流程

      1. 初始化所在、尽头,将出发点到场openlist
      2. 竖立一个递归函数用于寻觅途径
    4. 寻路递归函数

      1. 起首推断openlist是不是长度为0,是则寻路失利
      2. 竖立一个curr代表当前点初始为null,和currIndex序列号初始为0

        let currIndex = 0;
                let curr = null;
                
                for(let i = 0; i < openList.length; i++) {
                    if(openList[i].f < openList[currIndex].f) {
                        currIndex = i;
                    }
                }
        
                curr = openList[currIndex];
        
                if(curr === endSopt) {
                    drawPath(curr);
                    return true;
                }
        
                removeFromArray(openList, curr);
                closedList.push(curr);

        3.遍历curr的neighbors,将适宜点的parent设为curr

        for(let i = 0; i < curr.neighbors.length; i++) {
                    
                    let neighbor = curr.neighbors[i];
                    if(!closedList.includes(neighbor) && !neighbor.wall) {
        
                        let tmpF =  curr.g + getG(curr, neighbor) + getH(neighbor);
        
                        let newPath = false; // 是不是是更好的线路
        
                        if(openList.includes(neighbor)) {
                            if(tmpF <= neighbor.f) {
                                neighbor.f = tmpF;
                                newPath = true;
                            }
                        } else {
                            neighbor.g = curr.g + getG(curr, neighbor);
                            neighbor.h = getH(neighbor);
                            neighbor.f = neighbor.g + neighbor.h;
                            newPath = true;
                            openList.push(neighbor);
                        }
        
                        if(newPath) {
                            neighbor.parent = curr;
                        }
                    }
                }
        
        4.递归这个函数,当点和尽头一致时,返回这个点,然后递归它的parent属性,则能找到线路

末了附上案例地点:a星算法

    原文作者:BitCat
    原文地址: https://segmentfault.com/a/1190000018623507
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞