我正在编写一个游戏,其中大量对象将在平铺 2D 地图的区域上产生“区域效果”。
所需功能:
- 其中一些区域效果可能会重叠并影响同一个图块
- 必须可以非常有效地访问任何给定图块的效果列表
- 区域效果可以具有任意形状,但通常采用“距导致效果的对象最多 X 瓦片距离”的形式,其中 X 是一个小整数,通常为 1-10
- 区域效果会经常变化,例如当对象移动到地图上的不同位置时
- 地图可能很大(例如 1000*1000 瓦片)
什么数据结构最适合这个?
我正在编写一个游戏,其中大量对象将在平铺 2D 地图的区域上产生“区域效果”。
所需功能:
什么数据结构最适合这个?
通常这取决于地图的密度。
如果您知道每个图块(或图块的主要部分)至少包含一种效果,您应该使用常规网格——简单的二维图块数组。
如果您的地图填充得很少并且有很多空图块,那么使用一些空间索引(如四叉树或 R-tree 或 BSP-trees)是有意义的。
如果您确实确实同时发生了很多区域效果,并且它们将具有任意形状,我会这样做:
一些不依赖花哨的计算机科学的蛮力解决方案:
1000 x 1000 不是太大 - 只是一个兆。电脑有演出。你可以有一个二维数组。字节中的每一位都可以是一种“区域类型”。更大的“受影响区域”可能是另一个。如果您有合理数量的不同类型的区域,您仍然可以使用多字节位掩码。如果这变得荒谬,您可以使数组元素指针指向重叠区域类型对象的列表。但是你会失去效率。
您还可以实现一个稀疏数组 - 使用一个哈希表键(例如,键 = 1000*x+y) - 但这要慢很多倍。
当然,如果您不介意编写花哨的计算机科学方法,它们通常会更好地工作!
如果您知道每个区域效果的最大范围,则可以使用您选择的数据结构并仅存储实际源,该源已针对正常的 2D 碰撞测试进行了优化。
然后,在检查图块上的效果时,只需检查最大范围内的所有效果源(碰撞检测样式,针对您的数据结构进行了优化),然后应用定义的测试函数(例如,如果区域是圆形,检查如果距离小于一个常数;如果它是一个正方形,检查 x 和 y 距离是否都在一个常数内)。
如果您有少量 (<10) 的效果“场”形状,您甚至可以在其预先计算的最大范围内对每种效果场类型进行独特的碰撞检测。