有时候,影响计算寻路路径的不是时间,而是计算路径所需的上百个单元格所占的空间。寻路是需要内存来运行寻路算法,还需要额外内存来存储寻到的路径。运行寻路算法(A*,开集或闭集)所需的临时空间经常会比存储这些寻到的路径所需的空间更大。通过在同一时间内只进行一条路径计算来限制游戏中的计算量,可以将你需要的临时空间降到最少。另外,对开集闭集的数据结构的选择也会对减少你所需的临时内存产生很大的影响。在本章中将会转而关注通过生成的路径减少使用的空间。

位置vs方向

一条路径可以是一堆位置或者一堆方向,位置需要更多的空间,但是它的优势在于它很容易决定一条路径上的一个任意的位置点或者方向而不用遍历这条路径。当存储方向的时候,只需要这个方向就可以很容易的决定;而位置只能通过遵循某个方向经由整条路径才能决定,在传统的栅格化地图中,位置可能使用两个16位的整数来存储,这样的话,每一步存储都需要32字节。因为它有更少的方向所以需要的空间就更少。如果一个单元格只能在四个方向上移动,每一步只需要2字节;如果单元格可以在六个或者八个方向上移动,每一步就会需要3字节。这些存储在存储位置上的路径点在路径中是非常重要的。Hannu Kankaanpaa建议你可以通过存储绝对的方向(比如”向北”)而不是存储这些相对方向(比如”右转60度”)来进一步的减少存储所需的空间。一些相对方向可能让一些单元格难以理解。比如说如果你的单元格在想北方移动,那它下一步就不大可能向南移动。在一个六方向的游戏中,你只有五个有意义的方向。在一些地图中你可能只有3个方向(直走,左转60度,右转60度)有意义。但是在一些其他的地图中右转120度可能才是一个有效的移动(比如通过Z字形路线爬一座陡峭的山)。

路径压缩

一旦一个路径被找到,它将会通过某种方式被压缩。我们可以使用一个通用的压缩算法,但是我们不会在这篇文章中讨论这个算法。一个针对具体路径的压缩算法可以用来缩短基于位置的路径或者基于方向的路径。在做决定之前,考虑你游戏中的具体的典型路径来决定哪一种压缩算法最适合你所寻到的路径。同时 也要考虑在你游戏中实施(或者调试)的可行性,代码的体积还有这个压缩算法是否真的很重要。如果你有 个300单元格的限制,在同一时间只有50个单元格在移动,并且路径很短(只有100步),那么所需要的内存可能最多只有50k,那么你就不需要再考虑使用路径的压缩算法了。

位置点存储

在一张地图中如果障碍是寻路的主要影响因子而不是地形,那么就可以将路径分成很多条线段,如果是这种情况的话,那么一条路径只需要包括这些线段集合的各个终点位置(有时也被称为路径点)。运动就是由检查这条路径的下一个终点位置并沿着直线向终点移动组成。

方向存储

当方向被存储的时候,它可能是在一排中多次出现的方向,你可以利用那种常见的模式使用较少的空间去存储那条路径。

一种最好的存储路径方式是同时存储这个方向和指明单元格将在这个方向上移动多少次的数字。不同于位置存储的优化,当这个方向在这一排中并没有多次使用的时候这种优化可能会变得很糟。当然,对于很多直线路径的位置存储这种方式很有效,由于线可以不与的行走方向之一对齐,这种情况并不适用方向存储的压缩。当有多种可选方向时,你可以选择清除“一直直走”作为一个可行的方向。Hannu Kankaanpaa指出在一个八方向图中,你可以清除直走,手游账号卖号平台后退还有135度左,右转(假设你的地图允许这样),然后你可以仅仅使用2字节去存储每个方向。

另一种存储路径的方法是使用可变长度的编码。这是指使用一个单字节去存储大部分的一般性步骤比如说:直走。使用数字1去标记转向,在跟上一个数字1使用一些字节去表示转向,在一个4向图中,你只可以左转或者右转,所以你可能需要使用10来表示左转11来表示右转。

可变长度编码更为通用,可能比游程编码工作起来更好,但是对于长直型的路径就不如混合编码了。这个(北向,六步直走,左转,直走三步,右转,直走5步,左转,直走六步)的序列被使用长编码的[(North,6),(WEST,3),(NORTH,5),(WEST,2)]所代替。如果每个方向占用2字节,美短距离占用8字节,这条路径需要40字节去存储。如果使用可变长度编码,你需要使用1个字节去存储各个步骤2个字节去存储每次转向-[NORTH 0 0 0 0 0 0 10 0 0 0 11 0 0 0 0 0 10 0 0]总共需要24字节。如果初始化的方向和每次转向代表一步,你可以每次转向省下一字节,这样你只需要20字节就可以存储这条路径。但是使用可变长度编码在遇到较长的路径可能需要使用更多的空间。如果使用游程编码这个序列(north,直走200步)是[(NORTH,200)]只需要10个字节,同样的序列如果使用可变长度编码就变成[NORTH 0 0...],总共需要202字节。

计算路径点

路径点是指一条路径上的所有点。寻路完成后处理步骤时,可以折叠多个步骤到一个单一的路径点钟,通常存储的是路径改变方向的点,或者像城市的主要位置点,而不是存储一路走来的每一步。然后使用算法在路径点之间沿着路径运动。

限制路径长度

考虑到地图条件或者指令可能会发生变化,存储一条长路径可能意义并不大,因为余下的路径点可能根本就不会被使用到。每个单元格可以在路径开始的时候存储一些合适的步骤数,然后在路径快要走完时在重新计算心的路径。这种方法可以控制每个单元格的数据量。

总结

路径在游戏中可能占用很多空间,尤其是当路径很长,并且这个路径上有很多游戏单元的时候。路径压缩、路径点还有信标(beacon)都会在一定程度上减少在一小块数据里存储很多行路步骤的空间。在一条直线路径上加入需要存储路径点的话,只需要存储末尾点就可以了,信标是依靠在地图上特意标明的地方之间事先计算好的路径上使用。如果路径仍然需要占用很大的空间,就要限制路径的长度了,在经典的实时路径计算中是这样做的:为了节省空间,消息可以被忽略并且延迟计算。

游戏中常用的寻路算法(5)预先计算好的路径的所用空间相关推荐

  1. 游戏中常用的寻路算法(6):地图表示

    在本系列文档大部分内容中,我都假设A*用于某种网格上,其中的"节点"是一个个网格的位置,"边"是从某个网格位置出发的各个方向.然而,A*可用于任意图形,不仅仅是 ...

  2. 游戏中常用的寻路算法的分享(3):A*算法的实现

    概述 剥除代码,A* 算法非常简单.算法维护两个集合:OPEN 集和 CLOSED 集.OPEN 集包含待检测节点.初始状态,OPEN集仅包含一个元素:开始位置.CLOSED集包含已检测节点.初始状态 ...

  3. 游戏中常用的寻路算法的分享(2):Heuristics 函数

    转自:https://www.gameres.com/485150.html 启发式函数h(n)告诉A*从任何结点n到目标结点的最小代价评估值.因此选择一个好的启发式函数很重要. 启发式函数在A* 中 ...

  4. 游戏中常用的寻路算法的分享(4)处理移动中的障碍物

    一个寻路算法会计算出一条绕过静止障碍物的路径,但如果障碍物会移动呢?当一个单位移动到达某特定点时,原来的障碍物可能不在那点了,或者在那点上出现了新的障碍物.如果路线可以绕过典型的障碍物,那么只要使用单 ...

  5. 即时战略游戏中实用的寻路算法分享

    http://www.gameres.com/340777.html GameRes游资网授权发布,文 / 伍一峰 RTS中的寻路系统一般需要满足有以下几个条件: 1. 效率高,因为rts普遍地图大, ...

  6. 关于寻路算法的一些思考(6):预先计算好的路径的所用空间

    有时候,影响计算寻路路径的不是时间,而是计算路径所需的上百个单元格所占的空间.寻路是需要内存来运行寻路算法,还需要额外内存来存储寻到的路径.运行寻路算法(A*,开集或闭集)所需的临时空间经常会比存储这 ...

  7. 如何在Cocos2D游戏中实现A*寻路算法(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  8. 如何在Cocos2D游戏中实现A*寻路算法(七)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  9. 如何在Cocos2D游戏中实现A*寻路算法(五)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

最新文章

  1. WebAPI增加Area以支持无限层级同名Controller
  2. Paint.Net学习笔记——二、窗体(上)
  3. 启明云端分享 | Sigmastar SSD201\SSD202D核心板在智能料理机方案的应用(4.3寸彩屏应用)
  4. 养蛙游戏刷爆朋友圈,养蛙成功“反杀”传统手游?
  5. 【学习笔记】DAG / 一般有向图的支配树 / 灭绝树
  6. 用R在地图上绘制网络图的三种方法
  7. 把CMD下的color 方案遍历一遍
  8. Nginx 轻松搞定跨域问题!
  9. 如何破解无法炸开的CAD加密图纸
  10. 黑客帝国1-3 1080P 35.9G 下载
  11. 台式电脑硬件维修操作规范
  12. java 龟兔赛跑预测_Java实现 蓝桥杯VIP 基础练习 龟兔赛跑预测
  13. 爬虫 裁判文书网爬取part2
  14. 9、使用容器数据卷部署MySQL
  15. dropout keep_prob参数
  16. 与计算机相关的创意网名,最好的网名昵称大全_好听又有创意的网名
  17. MPQ技术内幕(转载)
  18. 英语信件_如何创建动画的旧信件
  19. 机器人如何改变我们的世界
  20. 个人拥有云服务器能用来干啥好玩的?

热门文章

  1. 批量修改栏目名_必收APP-效率高不含糊,批量管理功能上线了!
  2. c语言用什么能暂存结构指针,c语言中什么是指针
  3. 【C++】运算符重载 Operator Overload
  4. mysql ---- innodb-3-锁、事务
  5. .NET Framework Client Profile/.net framework 客户端配置
  6. [NOI2007]货币兑换
  7. 利用jdbc做一个购买的事务
  8. “GIS讲堂”第二课内容的公布
  9. 《Programming WPF》翻译 第8章 2.Timeline
  10. poj3083 Children of the Candy Corn 深搜+广搜