【发布时间】:2020-07-01 10:47:03
【问题描述】:
我有一个游戏,我向一个物体射击子弹,然后我删除被子弹击中的物体和屏幕外的子弹。
例如:
std::vector<object> object_list;
for(size_t i = 0; i < object_list.size(); i++)
{
if(object_list[i].hit())
{
object_list.erase(object_list.begin() + i);
}
else
object_list[i].draw();
}
这样做的问题是,当我删除一个对象时,向量的大小会减小,因此当它检查条件时,它会失败并且我会收到诸如“向量下标超出范围”之类的错误。我可以选择不通过渲染那些没有被击中的小行星来渲染小行星,但问题是没有。当被击中(分裂)时,物体的数量会增加,所以最终程序会变慢。我对屏幕外的子弹使用了类似的概念,但我找不到解决方法。我正在寻找解决此问题或删除元素的更好方法。
object 和 bullet 都是类。
【问题讨论】:
-
我怀疑错误是在其他地方产生的 - 该循环应该在向量中留下太多元素。 (假设你有
v = {1,2,3,4, ...}并且想要删除所有内容。你删除v[0]并拥有v = {2,3,4, ...}。然后你删除v[1]并拥有{2,4, ...}。等等。) -
@furrylion 反向遍历向量。然后删除元素不会导致任何问题
-
避免循环问题的保证方法是完全消除循环并使用标准算法。在这种情况下,
std::remove_if(object_list.begin(), object_list.end(), [](const object &o) {return o.hit();})可以解决问题(假设 C++11 及更高版本)。它还将避免您的循环遇到的问题,包括不检查/删除紧跟在已删除元素之后的元素。