重叠空间区域的有效数据结构

时间:2010-06-28 19:58:34

标签: language-agnostic data-structures spatial

我正在编写一个游戏,其中大量对象将在平铺2D地图的区域上具有“区域效果”。

必备功能:

  • 其中一些区域效果可能重叠并影响相同的图块
  • 必须能够非常有效地访问任何给定图块的效果列表
  • 区域效果可以具有任意形状,但通常具有“距离导致效果的物体最多X个瓦片”的形式,其中X是一个小整数,通常为1-10
  • 区域效应会经常变化,例如:当对象移动到地图上的不同位置时
  • 地图可能很大(例如1000 * 1000个图块)

哪种数据结构最适用于此?

5 个答案:

答案 0 :(得分:2)

通常取决于地图的密度。

如果您知道每个图块(或图块的主要部分)至少包含一个效果,则应使用常规网格 - 简单的2D图块阵列。

如果你的地图填充不足并且有很多空的瓷砖,那么使用一些spatial indexes像四叉树或R树或BSP树是有意义的。

答案 1 :(得分:2)

假设您确实同时发生了很多区域效果,并且它们将具有任​​意形状,我会这样做:

  • 创建新效果时,它是 存储在全局效果列表中 (不一定是全局变量, 只是适用于的东西 整场比赛或当前的比赛图)
  • 它计算哪些瓷砖 它影响并存储这些瓷砖的列表以防止效果
  • 每个瓷砖都是 通知新效果,和 在a中存储一个引用它的引用 每个瓦片列表(在C ++中我会使用一个 std :: vector for this,with something with 连续存储,而不是链接 列表)
  • 通过迭代处理结束效果 感兴趣的瓷砖,并在销毁之前删除对它的引用
  • 移动它或改变它的形状是通过移除来处理的 如上所述,执行变更计算, 然后重新附加现在受影响的图块中的引用
  • 你还应该有一个只进行调试的不变检查 您的整个地图并验证效果中的切片列表 与引用它的地图中的图块完全匹配。

答案 2 :(得分:1)

通常为BSP-Trees(或quadtreesoctrees)。

答案 3 :(得分:1)

一些不依赖计算机科学的蛮力解决方案:

1000 x 1000不是太大 - 只是一个兆。电脑有演出。你可以有一个2d数组。字节中的每个位可以是“区域类型”。较大的“受影响区域”可能是另一点。如果您有合理数量的不同类型的区域,您仍然可以使用多字节位掩码。如果这变得荒谬,你可以使数组元素指向重叠区域类型对象的列表。但是你失去了效率。

你也可以实现一个稀疏数组 - 使用哈希表键(例如,键= 1000 * x + y) - 但这要慢很多倍。

如果您不介意编写花哨的计算机科学方法,那么它们通常会更好!

答案 4 :(得分:1)

如果您有一个已知的每个区域效果的最大范围,您可以使用您选择的数据结构并仅存储实际的源,这是针对正常的2D碰撞测试进行优化的。

然后,在检查拼贴上的效果时,只需检查(最大化数据结构的碰撞检测样式)所有效果源在最大范围内,然后应用定义的测试功能(例如,如果该区域是圆,检查距离是否小于常数;如果是方形,检查x和y距离是否均为常数。

如果您有一小部分(< 10)效果“字段”形状,您甚至可以在预先计算出的最大范围内为每个效果字段类型执行唯一的碰撞检测。