A*(Astar)寻路算法实现疑问:闭合列表出现空洞问题
A*寻路闭合列表出现空洞的问题分析
你的代码里有几个关键错误,直接导致了闭合列表出现空洞,逐个拆解:
方向数组定义错误
你写的东北方向(directions[6])坐标和西南方向完全重复了:// 错误的东北方向定义 directions[6] = createVector(currentNode.pos.x - 1, currentNode.pos.y + 1); // 正确写法应该是x+1,y-1 directions[6] = createVector(currentNode.pos.x + 1, currentNode.pos.y - 1);这个错误直接让算法永远无法探索东北方向的邻居节点,缺失了四分之一的探索范围,必然会造成闭合列表的空洞。
G值计算不符合对角线移动的实际代价
横向/纵向移动的代价设为1没问题,但对角线移动的代价应该是√2(约1.414),因为对角线的实际距离比直边长。你现在所有方向的G值都加1:const g = currentNode.g + 1;这会让算法认为走对角线和直走成本一样,打乱了A*的路径优先级逻辑,导致探索范围出现混乱的空洞。
Open列表节点更新条件完全写反
你当前的判断逻辑是:如果open列表里已有节点的f值比新节点小,就替换成新节点——这完全搞反了!正确逻辑应该是新节点的f值更小(路径更优)时,才替换旧节点:// 错误条件 } else if(index && openList[index].f < newNode.f) { // 修正后 } else if(index && newNode.f < openList[index].f) {这个错误会让更优的路径节点无法被纳入探索,反而保留了更差的节点,导致算法遗漏大量应该加入闭合列表的节点。
Open列表存在性判断的逻辑bug
如果openListContainsNode返回的索引是0(即节点在open列表的第一个位置),!index会被JS判定为true(因为0是假值),这会错误地重复添加该节点,同时跳过了正常的更新逻辑,干扰了节点探索的正常流程。
内容的提问来源于stack exchange,提问作者Ricardinho
相关产品推荐
相关产品推荐

