A星算法
引见
javascript完成A星寻路算法
- 在游戏中常有须要主角/仇人去移动到某个物品或许追随仇人的时刻,这个时刻,能够运用寻路算法
- 为了完成canvas游戏,须要寻路算法,因而便本身用JS完成了一下
道理思绪
简化搜刮地区:
- 为了削减资本斲丧,起首须要我们将舆图分割为区块,如下图
2.竖立出发点和尽头坐标,用于寻路
保护open和close列表
- 我们新建两个列表,一个open表,它记录了一切被斟酌的寻路点;一个close表,它记录了一切不再被斟酌的点
- 我们要做的是接下来对两个表的保护
搜刮途径
怎样寻路呢,起首我们引入3个量
- G值,也就是当前点到起始点所需的价值
- H值,不斟酌一切停滞等要素,该点到尽头非斜线体式格局的预算量,也就是x+y的值
- F值,也就是该点的G+H的值
- 如图所示,左上角为F,右上角为H,左下为G:
接下来是寻路详细完成
- 起首最小F值的点到场open,点暂记为curr点
- 将curr点移除open,到场close
关于curr相邻点,都有以下步骤
- 在close或许是停滞,不管它
- 不在open中,则盘算它的各项值,到场open
- 在open中,则盘算我们当前这条途径抵达这个点是不是有更小F值,是则更新它的F值
- 检测到当前途径点和尽头一致时刻则完毕寻路;假如open中为空,则代表没有适宜的寻路计划,寻路失利
JS完成的详细计划
起首竖立一个Sopt的类,它内里包括以下信息
- 属性:x,y,f,g,h,isWall,neighbors,parents,
- 要领addNeighbors,用于增加四周8个格子能够增加的点
- 初始化舆图一切点,运转addNeighbors要领,将neighbors数组初始化
竖立寻路流程
- 初始化所在、尽头,将出发点到场openlist
- 竖立一个递归函数用于寻觅途径
寻路递归函数
- 起首推断openlist是不是长度为0,是则寻路失利
竖立一个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星算法