摘要: 五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑。本系列文章以TypeScript为介绍语言。

这一篇介绍A*寻路算法。在RPG、SLG、模拟经营类游戏,有需要给角色寻路的需求,一般寻路我们采用A*寻路算法,A*寻路算法是一种广度优先启发性算法。

先说说什么叫广度优先。搜索分为广度优先和深度优先,主要体现在对节点的展开上。深度优先一直往一个方向查找,如果没办法查找下去,在当前节点改变方向继续查找,直到找到终点。如果无法继续查找,就回退上一格重复操作。广度优先把当前节点放入待探索列表,循环从待探索列表里取出节点进行展开,直到找到终点。如果待探索列表为空,说明没有路可走。

启发性指算法在待探索列表里取节点时,先预测哪个节点的路径可能会最短,优先对该节点展开,A*算法基于对未探索路径的假设和预测,假设所有路都能通行前提下总路径最短值。在图论里,介绍过有一种寻找最短路径的算法叫Dijkstra算法,该算法基于贪心算法,即当前选择探索的节点,为尚未确定最短路径,当前源点能到达且路径最短的节点。Dijkstra算法基于已知距离源点最短。为了便于理解这两种算法的区别,先介绍下Dijkstra算法。

Dijkstra算法知道所有可能的节点,如下图,知道总共有ABCDE5个节点,寻找从A点出发到各点的最短路径。

1)算法有两个数组,一个维护当前已知最终最短路径的节点数组S,找到为路径字符串和长度,否则为空字符串,初始只有起点A点标记为“A”。另一个数组V,维护各个节点“目前所知”从源点出发最短的路径长度(不一定是最终的最短路径,初始B标记为6,D为7),已经找到最终最短路径的标记为0(初始时起点A标记为0),目前无法到达的标记为无穷大。

2)循环从数组V中获取标记非0,非无穷大,路径最短的节点,在数组S中标记为1,修正V中其他节点的最短路径。直到数组S中所有节点都标记为1

如上图,寻路的过程为:

V:(A,0),(B:6),(C:无穷大),(D:7),(E:无穷大),S:(A,“A”),(B:“”),(C:“”),(D:“”),(E:“”)

V:(A,0),(B:0),(C:11),(D:7),(E:18),S:(A,“A”),(B:“AB”),(C:“”),(D:“”),(E:“”)

V:(A,0),(B:0),(C:10),(D:0),(E:18),S:(A,“A”),(B:“AB”),(C:“”),(D:“AD”),(E:“”)

V:(A,0),(B:0),(C:0),(D:0),(E:18),S:(A,“A”),(B:“AB”),(C:“ADC”),(D:“AD”),(E:“”)

V:(A,0),(B:0),(C:0),(D:0),(E:0),S:(A,“A”),(B:“AB”),(C:“ADC”),(D:“AD”),(E:“ABE”)

这里,Dijkstra算法基于知道所有可能的节点,目标节点也有多个,每个节点可以直接到达的节点数没有限制。

游戏里的寻路是目标节点只有一个,中间节点可能有多个,每个节点可以直接到达的节点数最多4个(如果是8个方向是8)

将数组改成列表会更灵活,现在将数组V改成open队列,将数组S改成close队列。如上图,要找到A到E的路径,仍然按照Dijkstra算法思路,

1)先将A放入open队列,路径长度为0

2)循环从open列表里拿出路径长度最短的节点,将其放入close队列并记录上一节点,对其4个方向进行展开,如果已经在open、close队列,修正其最短路径长度;如果不可走,忽略;否则放入open队列并计算其路径长度。

3)如果找到E点,通过E点的上一节点,上一节点的上一节点...一直反推到A点,形成反推路径,从而找到A到E的最短路径。

4)如果还没找到E点,open 队列为空,A到E路不通。

如上图,从Dijkstra算法修改过来的寻路算法,按照红色、绿色、蓝色、黄色节点,逐步展开寻找才找到A到E的最短路径,很多没用的分支,效率低。

A*的优化思路主要在挑选节点展开时,假设找到一个中间节点B后,中间节点B到E的路都是可走的。这时候最短路径长度是计算经过B点A到E的最短路径(AB)+(BE)。在RPG游戏中,最简单的情况是,A到B的路径长度等于从A走到B经过的格子数,B到E的路径长度等于假设B到E的路都相通情况下B走到E经过的格子数。A*算法每次展开节点时都尽可能的往可能最短的路径去展开寻找,减少没必要的分支,提高寻路效率。

下面是A*寻路算法过程

1)先将A放入open队列,记录其上一节点为空

2)循环从open列表里拿出节点N,N为经过该点N,A到E路径预测长度最短的节点,将其放入close队列;对其4个方向进行展开,如果已经在open、close队列,修正其上一节点;如果不可走,忽略;否则放入open队列并记录其上一节点为N。

3)如果找到E点,通过E点的上一节点,上一节点的上一节点...一直反推到A点,形成反推路径,从而找到A到E的最短路径。

4)如果还没找到E点,open 队列为空,A到E路不通。

A*寻路算法先说到这里,下一篇我们将介绍有限状态机和行为树。

cocos creator主程入门教程(十)—— A*寻路的更多相关文章

  1. cocos creator主程入门教程(七)—— MVC架构

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇将介绍在游戏客户端常用的架构MVC架构.一个游戏的MVC如下划分: M:1)单例全局的数据中心Wo ...

  2. cocos creator主程入门教程(一)—— 初识creator

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们在cocos creator新建一个Hello TypeScript项目,都会有一个assets/S ...

  3. cocos creator主程入门教程(二)—— 弹窗管理

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们已经知道怎样制作.加载.显示界面.但cocos没有提供一个弹窗管理模块,对于一个多人合作的项目,没有 ...

  4. cocos creator主程入门教程(五)—— 日志系统

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍日志系统的设计.一般我们开发一个demo,只会简单的用cocos提供的cc.log打印下日志, ...

  5. cocos creator主程入门教程(三)—— 资源管理

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 在初识篇,我介绍过怎样加载prefab.cocos提供了一系列的加载接口,包括cc.loader.loa ...

  6. cocos creator主程入门教程(四)—— 网络通信

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 前面已经介绍怎样加载资源.管理弹窗.开发一个网络游戏,难免要处理网络通信.有几点问题需要注意: 1.服务 ...

  7. cocos creator主程入门教程(十一)—— 有限状态机和行为树

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 本篇介绍有限状态机和行为树.有限状态机用于有限的状态下的AI,由于同时只能处于一个状态,多个状态需要多个 ...

  8. cocos creator主程入门教程(九)—— 瓦片地图

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍瓦片地图,在开发模拟经营类游戏.SLG类游戏.RPG游戏,都会使用到瓦片地图.瓦片地图地面是通 ...

  9. cocos creator主程入门教程(八)—— 代码结构

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇简单介绍下代码结构,清晰的代码结构更有利于团队对项目的理解和维护. 1.前面我们介绍了一系列基础功 ...

随机推荐

  1. CAN总线的显性电平与隐性电平

    读CAN总线的书时,都会涉及到总线电平的问题,CAN总线的电平分为显性电平与隐性电平,这是CAN总线物理层的核心部分,也是总线仲裁的基础.那何为显性,何为隐性呢? 根据孔丙火(微信公众号:孔丙火)的理 ...

  2. python接口自动化(二十五)--unittest断言——下(详解)

    简介 本篇还是回归到我们最初始的话题,想必大家都忘记了,没关系看这里:传送门  没错最初的话题就是登录,由于博客园的登录机制改变了,本篇以我找到的开源免费的登录API为案例,结合 unittest 框 ...

  3. MySQL 上手教程

    安装 通过官网选择版本下载安装.Mac 上可通过 Homebrew 方便地安装: $ brew install mysql 检查安装是否成功: $ mysql --version mysql Ver ...

  4. TensorFlow从1到2(四)时尚单品识别和保存、恢复训练数据

    Fashion Mnist --- 一个图片识别的延伸案例 在TensorFlow官方新的教程中,第一个例子使用了由MNIST延伸而来的新程序. 这个程序使用一组时尚单品的图片对模型进行训练,比如T恤 ...

  5. c#批量抓取免费代理并验证有效性

    之前看到某公司的官网的文章的浏览量刷新一次网页就会增加一次,给人的感觉不太好,一个公司的官网给人如此直白的漏洞,我批量发起请求的时候发现页面打开都报错,100多人的公司的官网文章刷新一次你给我看这个, ...

  6. 第2章 授权端点(Authorize Endpoint) - IdentityModel 中文文档(v1.0.0)

    对于大多数情况,OAuth 2.0和OpenID Connect授权端点的GET请求需要具有许多查询字符串参数. 虽然您可以使用任何方法创建带参数的URL来创建正确的字符串,但RequestUrl类是 ...

  7. C#处理json实战

    昨天看到技术群中发了一个查询天气的api,http://www.sojson.com/open/api/weather/json.shtml?city=南昌 点进去看,发现服务器传回来一个天气信息的j ...

  8. 如何通过get,set方法访问到父类的私有属性

    刚学习继承的时候,总是会有这样的疑问. 子类继承父类时,会继承所有的非私有的属性和方法.那么在用set方法修改父类的私有属性时,怎么没有报空指针异常呢? 后来仔细想过这个问题,既然没有报空指针,那么在 ...

  9. ES6数组扩展运算符

    1 扩展运算符的运用 (1)复制数组 数组是复合的数据类型,直接复制的话,只是复制了指向底层数据机构的指针,而不是克隆一个全新的数组; const a1=[1,2]; const a2= a1; a2 ...

  10. Dynamics 365 CE在Pre Delete插件中应用Image

    微软动态CRM专家罗勇 ,回复327或者20190428可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 在插件中限制记录的删除是常见的场景,比如根据statuscode ...