C# 由于冲突,removeAt()出现问题
我昨天发布了关于游戏中敌人和子弹两个实例之间碰撞的请求帮助 解决办法是:C# 由于冲突,removeAt()出现问题,c#,xamarin,monogame,C#,Xamarin,Monogame,我昨天发布了关于游戏中敌人和子弹两个实例之间碰撞的请求帮助 解决办法是: foreach (Enemy enemy in enemies) foreach (Bullet bullet in bullets) if (bullet.boundingBox.Intersects(enemy.boundingBox)) { score += 1; } 当然,这在得分方面起到了作用,因为现在每当子弹与敌人相交时,我都
foreach (Enemy enemy in enemies)
foreach (Bullet bullet in bullets)
if (bullet.boundingBox.Intersects(enemy.boundingBox))
{
score += 1;
}
当然,这在得分方面起到了作用,因为现在每当子弹与敌人相交时,我都会得到一分。当我需要销毁两个对象(不是全部,只是相交的对象)时,就会出现问题。我的第一个想法是像这样使用removeAt()函数:
if (bullet.boundingBox.Intersects(enemy.boundingBox))
{
score += 1;
removeAt();
}
但这当然行不通,因为它通常与诸如“removeAt(i)”之类的索引一起使用。然后,我尝试将我引用的整个代码块放在顶部,并将其放在两个列表中,如下所示:
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update(delta);
//Bullets being destroyed upon leaving
if (bullets[i].position.Y < 0)
bullets.RemoveAt(i);
foreach (Enemy enemy in enemies)
foreach (Bullet bullet in bullets)
if (bullet.boundingBox.Intersects(enemy.boundingBox))
{
bullets.RemoveAt(i);
}
}
for(int i=bullets.Count-1;i>=0;i--)
{
项目符号[i]。更新(增量);
//子弹在离开时被销毁
if(项目符号[i].位置.Y<0)
子弹。移除(i);
foreach(敌人中的敌人)
foreach(子弹中的子弹)
if(bullet.boundingBox.Intersects(bullet.boundingBox))
{
子弹。移除(i);
}
}
游戏将在这一点上运行,但一旦子弹与敌人相撞,游戏就会崩溃。在“foreach(项目符号中的项目符号)”行抛出错误“System.invalidoOperationException”
老实说,我不知道我应该从这里走到哪里,因此非常感谢您的帮助。这样做的原因可能是您在枚举时正在从
项目符号中删除元素。请参见以下内容:
for (int i = bullets.Count - 1; i >= 0; i--)
您将项目符号的计数存储在i中,每次都将其减少。然后,您的代码中有两个位置的逻辑删除了项目符号,从而更改了项目符号的计数。您永远不应该修改正在枚举的数组
至于一个可能的解决方案,您可以完全按照Jason在评论中指出的那样做。在类中添加一个bool Delete
属性,然后将Delete
标记设置为true,而不是调用RemoveAt
。代码如下所示:
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update(delta);
//Bullets being destroyed upon leaving
if (bullets[i].position.Y < 0)
{
bullets[i].Delete = true;
}
foreach (Enemy enemy in enemies)
{
if (bullets[i].boundingBox.Intersects(enemy.boundingBox))
{
bullets[i].Delete = true;
}
}
}
bullets.RemoveAll(b => b.Delete);
for(int i=bullets.Count-1;i>=0;i--)
{
项目符号[i]。更新(增量);
//子弹在离开时被销毁
if(项目符号[i].位置.Y<0)
{
项目符号[i]。删除=true;
}
foreach(敌人中的敌人)
{
if(子弹[i].boundingBox.Intersects(敌方.boundingBox))
{
项目符号[i]。删除=true;
}
}
}
项目符号.RemoveAll(b=>b.Delete);
这样做的原因可能是,在对项目符号进行枚举时,您正在从项目符号中删除元素。请参见:
for (int i = bullets.Count - 1; i >= 0; i--)
您将项目符号的计数存储在i中,每次都将其减少。然后,您的代码中有两个位置的逻辑删除了项目符号,从而更改了项目符号的计数。您永远不应该修改正在枚举的数组
至于一个可能的解决方案,您可以完全按照Jason在评论中指出的那样做。在类中添加一个bool Delete
属性,然后将Delete
标记设置为true,而不是调用RemoveAt
。代码如下所示:
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update(delta);
//Bullets being destroyed upon leaving
if (bullets[i].position.Y < 0)
{
bullets[i].Delete = true;
}
foreach (Enemy enemy in enemies)
{
if (bullets[i].boundingBox.Intersects(enemy.boundingBox))
{
bullets[i].Delete = true;
}
}
}
bullets.RemoveAll(b => b.Delete);
for(int i=bullets.Count-1;i>=0;i--)
{
项目符号[i]。更新(增量);
//子弹在离开时被销毁
if(项目符号[i].位置.Y<0)
{
项目符号[i]。删除=true;
}
foreach(敌人中的敌人)
{
if(子弹[i].boundingBox.Intersects(敌方.boundingBox))
{
项目符号[i]。删除=true;
}
}
}
项目符号.RemoveAll(b=>b.Delete);
这样做的原因可能是,在对项目符号进行枚举时,您正在从项目符号中删除元素。请参见:
for (int i = bullets.Count - 1; i >= 0; i--)
您将项目符号的计数存储在i中,每次都将其减少。然后,您的代码中有两个位置的逻辑删除了项目符号,从而更改了项目符号的计数。您永远不应该修改正在枚举的数组
至于一个可能的解决方案,您可以完全按照Jason在评论中指出的那样做。在类中添加一个bool Delete
属性,然后将Delete
标记设置为true,而不是调用RemoveAt
。代码如下所示:
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update(delta);
//Bullets being destroyed upon leaving
if (bullets[i].position.Y < 0)
{
bullets[i].Delete = true;
}
foreach (Enemy enemy in enemies)
{
if (bullets[i].boundingBox.Intersects(enemy.boundingBox))
{
bullets[i].Delete = true;
}
}
}
bullets.RemoveAll(b => b.Delete);
for(int i=bullets.Count-1;i>=0;i--)
{
项目符号[i]。更新(增量);
//子弹在离开时被销毁
if(项目符号[i].位置.Y<0)
{
项目符号[i]。删除=true;
}
foreach(敌人中的敌人)
{
if(子弹[i].boundingBox.Intersects(敌方.boundingBox))
{
项目符号[i]。删除=true;
}
}
}
项目符号.RemoveAll(b=>b.Delete);
这样做的原因可能是,在对项目符号进行枚举时,您正在从项目符号中删除元素。请参见:
for (int i = bullets.Count - 1; i >= 0; i--)
您将项目符号的计数存储在i中,每次都将其减少。然后,您的代码中有两个位置的逻辑删除了项目符号,从而更改了项目符号的计数。您永远不应该修改正在枚举的数组
至于一个可能的解决方案,您可以完全按照Jason在评论中指出的那样做。在类中添加一个bool Delete
属性,然后将Delete
标记设置为true,而不是调用RemoveAt
。代码如下所示:
for (int i = bullets.Count - 1; i >= 0; i--)
{
bullets[i].Update(delta);
//Bullets being destroyed upon leaving
if (bullets[i].position.Y < 0)
{
bullets[i].Delete = true;
}
foreach (Enemy enemy in enemies)
{
if (bullets[i].boundingBox.Intersects(enemy.boundingBox))
{
bullets[i].Delete = true;
}
}
}
bullets.RemoveAll(b => b.Delete);
for(int i=bullets.Count-1;i>=0;i--)
{
项目符号[i]。更新(增量);
//子弹在离开时被销毁
if(项目符号[i].位置.Y<0)
{
项目符号[i]。删除=true;
}
foreach(敌人中的敌人)
{
if(子弹[i].boundingBox.Intersects(敌方.boundingBox))
{
项目符号[i]。删除=true;
}
}
}
项目符号.RemoveAll(b=>b.Delete);
通常,我更喜欢为要删除的对象维护一个新集合,然后在处理完成后删除它们。我发现这很容易遵循,而且没有可疑的附加项