陋室铭
永远也不要停下学习的脚步(大道至简至易)

posts - 2169,comments - 570,views - 413万

很多游戏特别是rts,rpg类游戏,都需要用到寻路。寻路算法有深度优先搜索(DFS),广度优先搜索(BFS),A星算法等,而A星算法是一种具备启发性策略的算法,效率是几种算法中最高的,因此也成为游戏中最常用的寻路算法。

直入正题:

在游戏设计中,地图可以划分为若干大小相同的方块区域(方格),这些方格就是寻路的基本单元。

在确定了寻路的开始点,结束点的情况下,假定每个方块都有一个F值,该值代表了在当前路线下选择走该方块的代价。 而A星寻路的思路很简单:从开始点,每走一步都选择代价最小的格子走,直到达到结束点。

A星算法核心公式就是F值的计算: F = G + H

F - 方块的总移动代价 G - 开始点到当前方块的移动代价 H - 当前方块到结束点的预估移动代价

 

以下详细解释这个公式,方便更好地理解它。

G值是怎么计算的? 假设现在我们在某一格子,邻近有8个格子可走,当我们往上、下、左、右这4个格子走时,移动代价为10;当往左上、左下、右上、右下这4个格子走时,移动代价为14;即走斜线的移动代价为走直线的1.4倍。 这就是G值最基本的计算方式,适用于大多数2.5Drpg页游。

基本公式: G = 移动代价

根据游戏需要,G值的计算可以进行拓展。如加上地形因素对寻路的影响。格子地形不同,那么选择通过不同地形格子,移动代价肯定不同。同一段路,平地地形和丘陵地形,虽然都可以走,但平地地形显然更易走。 我们可以给不同地形赋予不同代价因子,来体现出G值的差异。如给平地地形设置代价因子为1,丘陵地形为2,在移动代价相同情况下,平地地形的G值更低,算法就会倾向选择G值更小的平地地形。

拓展公式: G = 移动代价 * 代价因子

 

H值是如何预估出来的? 很显然,在只知道当前点,结束点,不知道这两者的路径情况下,我们无法精确地确定H值大小,所以只能进行预估。 有多种方式可以预估H值,如曼哈顿距离、欧式距离、对角线估价,最常用最简单的方法就是使用曼哈顿距离进行预估: H = 当前方块到结束点的水平距离 + 当前方块到结束点的垂直距离

题外话:A星算法之所以被认为是具有启发策略的算法,在于其可通过预估H值,降低走弯路的可能性,更容易找到一条更短的路径。其他不具有启发策略的算法,没有做预估处理,只是穷举出所有可通行路径,然后从中挑选一条最短的路径。这也是A星算法效率更高的原因。

 

每个方块的G值、H值是怎么确定的呢? G值 = 父节点的G值 + 父节点到当前点的移动代价 H值 = 当前点到结束点的曼哈顿距离

 

最后,A星算法还需要用到两个列表: 开放列表 - 用于记录所有可考虑选择的格子 封闭列表 - 用于记录所有不再考虑的格子

 

以上就是要完成A星算法所需要的东西,而算法的过程并不复杂。

A星算法伪码: a、将开始点记录为当前点P b、将当前点P放入封闭列表 c、搜寻点P所有邻近点,假如某邻近点既没有在开放列表或封闭列表里面,则计算出该邻近点的F值,并设父节点为P,然后将其放入开放列表 d、判断开放列表是否已经空了,如果没有说明在达到结束点前已经找完了所有可能的路径点,寻路失败,算法结束;否则继续。 e、从开放列表拿出一个F值最小的点,作为寻路路径的下一步。 f、判断该点是否为结束点,如果是,则寻路成功,算法结束;否则继续。 g、将该点设为当前点P,跳回步骤c。

 

后续优化

以上就是A星算法最基本的原理,明白了基本原理,用2,3百行代码写出一个可用的A星算法并不难。当然A星算法在实际应用中不仅于此,还可以对细节进行优化:

1、选择排序更快的二叉树来作为开放列表,帮助我们更快地从开放列表中取出F值最小的点;

2、对何种情况下可以走斜线路径加以判断;

3、采用布兰森汉姆算法预先判断两点是否可以直接通行,可通行就直接返回两点的直线路径,不可直接通行再采用A星算法寻路,提高寻路效率;

4、A星算法得出寻路路径后,可采用弗洛伊德算法对路径进行平滑处理,使人物走动更为自然

这里只是用语言讲解A星算法原理,并没有配图讲解整个寻路的过程,希望进一步直观理解整个过程的,推荐参考下面两个网友翻译过来的A星教程

posted on   宏宇  阅读(691)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2012-03-06 DIV+CSS背景一张整图(css sprites)
2009-03-06 微软云计算的思考
2007-03-06 C#接口慨述
2007-03-06 函数指针进化论(下)
2007-03-06 函数指针进化论(上)
2007-03-06 解耦的故事(二)-松耦合时代的来临(转)
2007-03-06 解耦的故事(一)-tmfc的开关(转)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示