什么样的容器适合 "The Powder Toy" 风格的沙箱?

What kind of container is appropriate for a "The Powder Toy" style sandbox?

基本上我正在制作一款类似于 The Powder Toy 的游戏。在一个给定的帧中,世界最多可以有 256,000 个粒子。在我旧的 Javascript 实现中,我遍历了每个像素,这导致了严重的滞后,因为即使只有大约 20,000 个粒子处于活动状态,256,000 个像素也需要经过很多。我决定改用一个装满所有当前活动粒子的容器,但随后 运行 遇到了一个问题,即在特定坐标处查询容器中的粒子也是处理器密集型的。因此我想到了一个简单的解决方案,我应该将所有粒子保存在查找 table (二维数组)中并且还有一个堆(活性粒子数组),并在使用查找时迭代堆 table作为参考。对堆所做的任何事情都会对查找 table 进行,反之亦然。这在 Javascript 中运行良好,但现在因为我需要将我的程序移植到 C++,所以我很难找到一个好的容器来容纳堆。矢量的添加和删除速度非常慢,我无法通过引用从矢量中轻松删除对象。

我应该使用哪个容器,如果有更好的方法来处理粉末玩具中的颗粒,那是什么?提前致谢,对于那些不熟悉 The Powder Toy 的人,这里有一张图片。

注意每个像素如何有一个粒子,类似的构建 运行 在我的计算机上非常快。我想知道他们是怎么做到的...

向量可以解决这类问题。它们提供连续存储,因此可以更好地使用缓存。

尝试通过构造函数或使用 std::vector::reserve() 预先分配适当的向量容量。如果没有这个,每次向量的大小超过当前容量时都会触发已分配存储空间的自动重新分配space。

您还可以尝试使用 std::swap() 然后 std::vector::pop_back() 从向量中删除元素,如下所示:

std::swap(vect.back(), vect[1]);
vect.pop_back();

而不是:

std::vector::erase()

std::vector::pop_back()std::swap()的复杂度都是常量,std::vector::erase()的复杂度是线性的。

但是如果你需要保留元素的顺序,swap - pop 方法是没有用的。