我有一个2d数组的向量指向游戏中的实体。该阵列代表游戏世界的网格,以在检测到碰撞时提高性能。当一个实体移动时,我检查它是否移动到另一个网格块(当然),但这就是一切都变成地狱的地方。如果我在更改时移动数组中的对象,则CPU将变为100%而不是8%,游戏物理不再适用。
这是更新功能,它停止工作:
for (int i = 0; i < xGridCount; i++)
{
for (int j = 0; j < yGridCount; j++)
{
for (auto it : grid[i][j])
{
it->update();
//update gridpos
if ((int) it->x/gridSize != i || (int) it->y/gridSize != j)
{
grid[it->x/gridSize][it->y/gridSize].emplace_back(std::move(it));
}
}
}
}
网格数组声明:
std::array<std::array<std::vector<std::shared_ptr<Entity>>, yGridCount>, xGridCount> grid;
&#34;更新gridpos&#34;是崩溃的地方。如果我发表评论,一切都会正常运作。
当然,我已经想到了我能做些什么来修复它,并且我已经想过在碰撞检测中只使用 数组。但关于这一点的是,我必须保留每个对象的两个指针,一个用于命中检测,一个用于更新/渲染,这听起来不是一个好的解决方案。
为什么CPU太重了? 我怎么能这样做呢?
答案 0 :(得分:2)
for (auto it : grid[i][j])
it
是shared_ptr
,这会产生副本。制作shared_ptr
的副本是一种性能损失。 (通常it
代表&#34; iterator&#34;,所以我不确定你为什么称它为it
。)
grid[it->x/gridSize][it->y/gridSize].emplace_back(std::move(it));
这会将shared_ptr
it
移动到新图块的向量中,但由于it
是副本,因此它不会对shared_ptr
中的任何内容执行任何操作旧的。结果,它现在同时在两个网格图块中。
似乎有些混乱:std::move
(单参数版本)不会移动任何东西;它只是将参数转换为rvalue来发出信号&#34;该对象的内容可以被移动&#34;。 shared_ptr
/ unique_ptr
移动构造函数实质上移动了指针对象的所有权,而不是智能指针对象本身。移动的智能指针(处于空状态)将保留在它所在的容器中,直到您实际将其从容器中删除。