Lockstep 之寻路算法
最近在学习Unity,在github上发现了一个很好的开源网游架构。也解决了之前的很多困惑,在此和大家分享一下。github地址在文章末尾贡献。
A*寻路算法
1.简易描述
1.在A*寻路中,我们首先需要将地图分割成一个一个的格子。
2.然后选择一个格子作为起点,一个格子作为终点。如上图所示,A选择作为起点,B选择作为终点。
3.然后我们通过A*寻路算法找到从A到B所需要经历的最快捷的格子。
4.从图中我们可以看出,A所能到达的格子,只能是在它的8个邻居。而上下左右4个邻居是最短距离的,而4个角上的邻居则距离要长一些。同时每一个格子到达B的距离又是不一样的。所以我们需要给每一个格子设定权值F,并更新。
5.权值F由两部分组成,即F=G+H。G表示A节点移动到指定方块的消耗,H表示指定节点移动到B节点的消耗。我们设定横向和纵向移动一个格子的消耗为100,而斜着移动一个格子的消耗为140.
6.我们需要找到一条路径,F值是最小的。
2.寻路步骤
- 准备好数据结构,一个“开启列表”,一个“关闭标志”CloseFalgT=0,并执行++CloseFalgT。开启列表中放置待检查的节点。节点结构:
class Grid
{
int x = 0;
int y = 0;
Grid parent = null;
int F = 0;
int G = 0;
int H = 0;
int CloseFlag = 0;
bool walkable = true;
}
- 从起点A开始,把它作为待处理的节点存入“开启列表”中,并更新好它的权值F=G+H,G为0。
- 不断做当前操作,直到找到目标或者“开启列表”为空。
- 对“开启列表”根据F值进行排序。
- CurNode = F值最小的那个,并移除,设置成关闭标志(CloseFalg = CloseFalgT)。
- 找出CurNode的邻居Neighbor,把walkable为false或者CloseFlag等于CloseFlagT的丢弃,不处理。
- 计算CurNode的G值,对于纵横的Neighbor节点,G = CurNode.G + 100, 而斜方向的Neighbor节点 G = CurNode.G + 140.
- 如果改Neighbor不在开启列表中,则加入开启列表中,并设置parent=CurNode,如果在开启列表中,并且新的G值比之前的小,则更新G值,并且更新parent为CurNode。并且计算Neighbor节点的H值。
- 当到达B点之后,那么最后所有选择过的节点,组成的结构则是树形结构。最终路径就是该节点的parent合集。最终的parent就是A点。