本文介绍了在每个循环中删除一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在制作一个生存游戏,并试图删除一个对象,当它离开屏幕。这里是代码:
pre $ Public Sub tmrEnemyMove_Tick(sender As Object,e As EventArgs)Handle tmrEnemyMove.Tick
Dim koopaAnimation作为布尔
对于每个敌人作为敌人在lstEnemy
enemy.enemy.Left = enemy.enemy.Left - 20
如果enemy.enemy.Tag = koopa然后
enemy.enemy.Image = Image.FromFile(Application.StartupPath +\Graphics\koopa+ Trim(Str(koopaPosition))+.png)
如果koopaAnimation =假然后
如果koopaPosition = 0那么
koopaPosition = 1
否则
koopaPosition = 0
如果
结束如果
koopaAnimation = True
结束如果
如果picMario.Left< enemy.enemy.Left AndAlso enemy.enemy.Left< picMario.Right或picMario.Left< enemy.enemy.Right AndAlso enemy.enemy.Right< picMario.Right然后
如果picMario.Top< enemy.enemy.Top AndAlso enemy.enemy.Top< picMario.Bottom或picMario.Top< enemy.enemy.Bottom AndAlso enemy.enemy.Bottom< picMario.Bottom Then
'MsgBox(Collision)
End If
End If
If enemy.enemy.Left< 0 Then
lstEnemy.Remove(enemy)
Me.Controls.Remove(enemy.enemy)
End If
Next
End Sub
$
$ b 我得到的错误是:
在mscorlib.dll $ b $中发生未处理的类型为System.InvalidOperationException的异常b更多信息:收集已修改;枚举操作可能不会执行。
如果有人能帮上忙的话,谢谢。
在枚举过程中,不能从集合中删除对象。根本不能修改集合。这将导致一个错误(集合被修改;枚举操作可能不会执行)。但是,您可以将要删除/移除的对象添加到另一个集合中:
Dim removeEnemies =新列表(敌人)
对于每个敌人作为敌人在lstEnemy
'...'
如果enemy.enemy.Left< 0然后
removeEnemies.Add(enemy.enemy)
结束如果
下一个
对于每个敌人在移除敌人
lstEnemy.Remove(敌人)
Me.Controls.Remove(enemy.enemy)
下一个
这些方法会导致一个列表来改变它的版本(在枚举过程中被检查):
$ b $ ul
添加 清除 插入 InsertRange 删除 RemoveRange RemoveAt 反向 / li>
另一个选项是使用 For-Loop
并向后循环:
For I作为Int32 = lstEnemy.Count - 1到0步骤-1
Dim enemy = lstEnemy(i)
'...'
如果enemy.enemy.Left< 0 Then
lstEnemy.Remove(enemy)
Me.Controls.Remove(enemy.enemy)
End If
Next
这不会引起这个错误,但它不可读。你需要从 list.Count - 1
到 0
去,因为你想删除将会改变 Count
属性和在项目被移除之前可用的索引现在导致 ArgumentOutOfRangeException
。
最后但并非最不重要的,你可以使用:
lstEnemy。 RemoveAll(函数(敌人)enemy.enemy.Left< 0)
I'm making a survival game and trying to remove an object when it goes off the screen. Here is the code:
Public Sub tmrEnemyMove_Tick(sender As Object, e As EventArgs) Handles tmrEnemyMove.Tick
Dim koopaAnimation As Boolean
For Each enemy As enemy In lstEnemy
enemy.enemy.Left = enemy.enemy.Left - 20
If enemy.enemy.Tag = "koopa" Then
enemy.enemy.Image = Image.FromFile(Application.StartupPath + "\Graphics\koopa" + Trim(Str(koopaPosition)) + ".png")
If koopaAnimation = False Then
If koopaPosition = 0 Then
koopaPosition = 1
Else
koopaPosition = 0
End If
End If
koopaAnimation = True
End If
If picMario.Left < enemy.enemy.Left AndAlso enemy.enemy.Left < picMario.Right Or picMario.Left < enemy.enemy.Right AndAlso enemy.enemy.Right < picMario.Right Then
If picMario.Top < enemy.enemy.Top AndAlso enemy.enemy.Top < picMario.Bottom Or picMario.Top < enemy.enemy.Bottom AndAlso enemy.enemy.Bottom < picMario.Bottom Then
'MsgBox("Collision")
End If
End If
If enemy.enemy.Left < 0 Then
lstEnemy.Remove(enemy)
Me.Controls.Remove(enemy.enemy)
End If
Next
End Sub
The error I get is:An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dllAdditional information: Collection was modified; enumeration operation may not execute.
If anyone could help that would be great, thanks.
解决方案
You cannot delete an object from a collection during enumeration. You cannot modify the collection at all. That will cause an error(Collection was modified; enumeration operation may not execute). But you could add the objects that you want to delete/remove to another collection:
Dim removeEnemies = New List(Of enemy)
For Each enemy As enemy In lstEnemy
' ... '
If enemy.enemy.Left < 0 Then
removeEnemies.Add(enemy.enemy)
End If
Next
For Each enemy In removeEnemies
lstEnemy.Remove(enemy)
Me.Controls.Remove(enemy.enemy)
Next
These methods will cause a list to change it's version(which is checked during enumeration):
- Add
- Clear
- Insert
- InsertRange
- Remove
- RemoveRange
- RemoveAt
- Reverse
- [the Indexer setter]
- Sort
Another option is to use a For-Loop
and loop it backwards:
For i As Int32 = lstEnemy.Count - 1 To 0 Step -1
Dim enemy = lstEnemy(i)
' ... '
If enemy.enemy.Left < 0 Then
lstEnemy.Remove(enemy)
Me.Controls.Remove(enemy.enemy)
End If
Next
This will not raise that error but it's not as readable. You need to go from list.Count - 1
To 0
because you want to remove items which would change the Count
property and an index that was available before the item was removed causes now an ArgumentOutOfRangeException
.
Last but not least, you can use List.RemoveAll
:
lstEnemy.RemoveAll(Function(enemy) enemy.enemy.Left < 0)
这篇关于在每个循环中删除一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!