obsidian/笔记文件/2.笔记/A星寻路算法_第二章.md
2025-03-26 00:02:56 +08:00

5.0 KiB
Raw Permalink Blame History

逻辑类中,有一个静态接口,是用来计算,两个方块之间距离的,通过Mathf.Abs计算距离的绝对值,再通过Mathf.MaxMathf.Min拿到最大/小数值,换算得到,两者之间的距离

!Pasted image 20240404132948.png

重写Tostring字符显示函数还有对应上IComparable接口的CompareTo比较函数是以priority进行比较排序即可

!Pasted image 20240404154322.png

抽象类BasePathFinder是基础的寻路逻辑其中包含两个方块逻辑BlockLogic分别是开始和结束逻辑点 再弄几个队列容器,分别存储,不同阶段的方块逻辑集合;

!Pasted image 20240404155924.png

GetPathBlockLst函数接口是先拿到结束的方块逻辑点m_endBlock然后一个while死循环把节点插到队列0索引 再拿到m_endBlock的前一个检测方块preBlock然后设为当前block方块再进入下一个while死循环等于是倒着拿到整条链路 最后返回这个队列容器lst即可

!Pasted image 20240404160212.png

检测邻近方块这个DetectNeighborBlock抽象函数有四次重写分别对应四种寻路逻辑A星寻路是其中一种

!Pasted image 20240404160610.png

计算路径逻辑,是一个Task任务设置初始方块逻辑点,再清空各个队列容器; 死循环while判断如果等待检测的队列m_detectQue包含结束节点就通过GetPathBlockLst函数倒着拿到整个链路然后基于break跳出 上述这个是寻路找到结束点跳出的逻辑在跳出之前是m_detectQue出队元素调用DetectNeighborBlock函数使用寻路算法完成不同的寻路逻辑

!Pasted image 20240404160728.png

方块地图BlockMap统一管理方块逻辑BlockLogic其中的xyCount是纵横的最大数目m_blockArr作为一个二维数组也是用来存储创建出来的所有方块逻辑 初始化函数InitMap赋值最大xy数目实例化二维数组然后遍历对其中的单个方块逻辑调用InitBlockLogic完成初始化

!Pasted image 20240404161805.png

还可以统一消选所有节点

!Pasted image 20240404174358.png

俩函数接口分别是将逻辑节点的Walkable存到对应的布尔二维数组stateArr还有从stateArr这个二维数组遍历重新设置对应的布尔值到对应索引的逻辑节点Walkable

!Pasted image 20240404165923.png

readonly只读的二维数组allDirs通过几个Vector2元素完成各个方向的定义

!Pasted image 20240404170059.png

边界内判断确认xy没有越界

!Pasted image 20240404170224.png

调用上述的边界判断接口,还有各个方向,完成节点周边,对应逻辑节点集合的添加整理

!Pasted image 20240404170248.png

UpdateMapData函数接口遍历统一更新节点的周边邻近逻辑节点数据集合

!Pasted image 20240404174423.png

因为寻路排序是需要引入优先级的概念也弄一个PEQue排序类继承自IComparable接口,具体的逻辑解析,参考基于堆实现优先级队列即可

!Pasted image 20240404170626.png

寻路相关逻辑一共有四个分别是这几个实现都是继承自基础寻路逻辑BasePathFinder他们的逻辑大致相同区别在于priority优先级的判断不同

!Pasted image 20240404171511.png

首先是广度优先搜索算法breadth First Search, BFS)对应的是BreadFirstPathFinder脚本 判断已完成队列等待检测队列中都没包含这个neighborBlock就会进入寻路的逻辑判断 调用GetLogicBlockDistanc接口拿到俩逻辑节点之间的neighborDistance距离 sumDistance等于检测总节点原本的距离加上新的这个节点距离neighborDistance 它的优先级priority是已完成队列m_finishLst的总数

!Pasted image 20240404171608.png

然后是Dijkstras迪杰斯特拉最短路径算法对应的是DijkstrasPathFinder逻辑进入逻辑的前提布尔判断还有总距离的计算逻辑跟之前的都一样 在总距离是否无穷大的IsPositiveInfinity判断后确保节点的sumDistance总距离是遍历周边最小的 而且priority优先级是sumDistance总距离

!Pasted image 20240404172045.png

然后是贪心算法对应的是GreedyPathFinder逻辑其他逻辑大致一致它的优先级priority判断是节点和最终结束节点m_endBlock之间的距离

!Pasted image 20240404172405.png

然后这是A星算法对应的是AStarPathFinder逻辑其他逻辑大致一致它有使用Dijkstras迪杰斯特拉的最短路径逻辑确保是拿到周边最短的路径sumDistance 同时,它又拿到节点,和最终结束节点,之间的距离,这是贪心算法的相关逻辑; A星算法的优先级是最短路径加上节点到最终节点距离

!Pasted image 20240404172541.png