这种情况的双向数据结构

Bidirectional data structure for this situation

本文关键字:数据结构 情况      更新时间:2023-10-16

我正在研究游戏引擎的一小部分,想知道如何优化某些部分。

情况很简单,如下:

  • 我有一张Tile的地图(存储在二维数组中)(~260k个图块,但假设更多)
  • 我有一个Item列表,这些列表总是至少在瓷砖中,最多是一个瓷砖
  • 一个Tile在逻辑上可以包含无限数量的Item
  • 在游戏执行过程中,会不断创建许多Item,它们从自己的Tile开始
  • 每个Item都会不断将其Tile更改为一个邻居(向上,向右,向下,向左)

到目前为止,每个Item都有一个对其实际Tile的引用,我只保留一个项目列表。每次Item移动到相邻的磁贴时,我都会更新item->tile = ..,我就没事了。这工作正常,但它是单向的。

在扩展引擎时,我意识到我必须多次查找图块中包含的所有项目,这实际上降低了性能(特别是在某些情况下,我必须逐个查找一系列图块的所有项目)。

这意味着我想找到一种比 O(n) 更好的数据结构来查找特定Tile的所有项目,但我想避免在"从一个磁贴移动到另一个"阶段产生太多开销(现在它只是分配一个指针,我想避免在那里做很多操作, 因为它很频繁)。

我正在考虑一种自定义数据结构来利用项目总是移动到相邻单元格的事实,但我目前正在黑暗中摸索!任何建议将不胜感激,即使是棘手或神秘的方法。不幸的是,我不能只是浪费内存,所以需要一个很好的权衡。

我正在使用 STL C++开发它,但没有 Boost。(是的,我确实知道multimap,它不能让我满意,但如果我找不到更好的东西,我会尝试)

struct Coordinate { int x, y; };
map<Coordinate, set<Item*>> tile_items;
这会将磁贴

地图上的坐标映射到指示该磁贴上哪些项的项指针集。 您不需要为每个坐标输入一个条目,只需要那些实际上有项目的坐标。 现在,我知道你说过:

但我想避免在"从一个瓷砖移动"中产生太多开销 到另一个"阶段

这种方法将涉及在该阶段增加更多开销。 但是你真的尝试过这样的事情并确定这是一个问题吗?

对我来说,

我会将std::vector包装成矩阵类型(IE 在 1d 数组上强加 2d 访问),这使您可以快速随机访问任何瓷砖(实现矩阵是微不足道的)。

 vector_index=y_pos*y_size+x_pos;

为大小的向量编制索引

 vector_size=y_size*x_size;

然后每个项目都可以有一个 std::vector 的项目(如果一个磁贴的项目数量非常动态,也许是一个 deque),同样,这些是随机访问包含的开销非常小。

对于您的用例,我会远离间接容器。

PS:如果你愿意,你可以有我的矩阵模板。

如果您真的认为拥有每个瓷砖存储它的物品会花费您太多空间,请考虑使用四叉树来存储物品。这使您可以有效地获取磁贴上的所有项目,但将磁贴网格保留在原位以供项目移动。