循环碰撞逻辑错误

时间:2013-01-15 22:26:27

标签: c# loops for-loop

我有一个循环,它应该检测并删除列表中与放置对象相交的任何对象。代码如下:

for (int i = 0; i < levelObjects.Count(); i++)
{
    if (levelObjects[i].BoundingBox.Intersects(mouseBlock.BoundingBox))
    {
        levelObjects.RemoveAt(i);
    }
}

遇到多次碰撞的情况时,有时无法检测到碰撞。交叉口功能正常。我的循环导致了什么呢?

4 个答案:

答案 0 :(得分:5)

由于您正在从循环中删除,因此最终会跳过元素。更好的选择是向后循环:

for (int i=levelObjects.Count() - 1; i >= 0; --i)
{
  // ...

这可以防止您现在丢失的“跳过”对象,因为当您删除并且索引向下移动时,您只会移动已经测试过的对象。

答案 1 :(得分:3)

删除索引i处的对象时,索引i + 1处的值向下滑动到索引i。您的循环将移至索引i + 1,并且永远不会检查索引i处的新值。你可以通过简单地向后循环来避免这种情况。

答案 2 :(得分:2)

在索引i处删除levelObject时,会按索引向下移动所有内容。因此,下一项目现在是索引i。避免这种情况的一种简单方法是从最后开始,然后向后工作,即

for (int i = levelObjectsCount - 1; i >= 0; i--)
{
    if (levelObjects[i].BoundingBox.Intersects(mouseBlock.BoundingBox))
    {
        levelObjects.RemoveAt(i);
    }
}

答案 3 :(得分:1)

您无法从列表中删除您正在迭代的内容!迭代副本或创建要删除的项目列表,然后删除它们。示例(如果性能不是问题):

foreach (var obj in levelObjects.ToList())
{
    if (obj.BoundingBox.Intersects(mouseBlock.BoundingBox))
    {
        levelObjects.Remove(obj);
    }
}
相关问题