目录
空间分区 · Optimization Patterns · 游戏设计模式
一、意图
将对象根据它们的位置存储在数据结构中,来高效地定位对象。
二、动机
在实施战略游戏中。双方有成百上千的单位在战场上撞在一起。战士自动向离他最近的敌人挥刀。最简单的处理就是遍历所有敌人。
如果使用最简单的循环,时间复杂度为单位数量的平方级。
这里想到最直接的优化就是使用时间复杂度更小的循环。但这样我们可能需要提前处理一下数据。比如:将二维坐标视为一维的战线。
这样就可以根据单位在战线上的位置排序数组元素来简化。并使用二分查找之类来降低时间复杂度。
三、空间分区
对于一系列对象,每个对象都有空间上的位置。将他们存储在根据位置组织对象的空间数据结构中,让你有效查询在某处或者某处附近的对象。当对象的位置改变时,更新空间数据结构。
1.适用场景:
这是存储活跃的、移动的游戏对象的常用模式。也可用于静态美术和世界地理。
基本要求是:有很多有位置的对象,并且做了太多通过位置查找对象造成性能下降。
同时,这是以空间换时间,并需要在对象位置改变时花费时间去维护这个新的列表。所以一定是在基数足够多,且时间比内存更短缺才能使用。
2.实例代码
空间分区的应用很灵活,这里介绍最简单的空间分区:固定网格
比如:将战场分割成一个个格子,每个士兵都处于某个格子中。
基础类:
这里的grid指针就是指向每个单位所在的格子的。
网格类:
将对象组织为双向链表,一个格子中的对象就有了相互关系
双向链表的具体管理
注意看这个add函数,总是保存了最后进这个格子的单位,新单位进来后就与这个单位互相链上。
于是,战场找人就优化到了每个格子找人。这里是以位置相同的逻辑在找。如果是需要按距离最近找,就需要对比周围的8个格子一起。
四、注意
空间划分通常为了配合四叉树和二分空间查找之类的。熟悉他们的工作原理,能更利于使用这个模式。
1.划分是层次的还是平面的?
i.平面
更简单,内存使用量确定,在对象改变位置时更新更快。
ii.层次性
能更有效率地处理空的区域。它处理密集空间更有效率。
2.划分依赖于对象数量吗?
i.与对象无关
在上面的示例中,如果所有的战士都挤在一个格子里,那性能就回到了优化前了。
ii.与对象数量有关
比如BSPs和K-D树,需要让每部分都接近相同数目对象。
iii.如果划分与对象无关,但层次与对象有关
比如四叉树,四叉树开始时将整个空间视为单一的划分。 如果空间中对象数目超 过了临界值,它将其切为四小块。