2013-05-24 11 views
6

Tôi đang tạo ra một trò chơi sinh tồn và cố gắng loại bỏ một vật khi nó tắt màn hình. Đây là mã:Xóa vật thể khi ở trong mỗi vòng

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 

Các lỗi tôi nhận được là: Một ngoại lệ unhandled của loại 'System.InvalidOperationException' xảy ra ở mscorlib.dll Thông tin thêm: Bộ sưu tập đã được sửa đổi; hoạt động điều tra có thể không thực hiện được.

Nếu có ai đó có thể giúp điều đó thật tuyệt vời, cảm ơn.

+2

Bạn canot thay đổi bộ sưu tập như trong khi điều này lặp qua nó , vì những lý do hiển nhiên nếu bạn nghĩ về nó. Nhận một tham chiếu đến đối tượng trong khi ở vòng lặp, sau đó xóa aterwards – DavidB

Trả lời

1

.NET thực sự không thích khi bạn thay đổi bộ sưu tập khi bạn đang liệt kê nội dung của nó. Bạn có thể thử quay vòng foreach của mình thành vòng lặp for nếu bạn định loại bỏ các phần tử khỏi bộ sưu tập như thế này.

13

Bạn không thể xóa đối tượng khỏi bộ sưu tập trong quá trình liệt kê. Bạn không thể sửa đổi bộ sưu tập. Điều đó sẽ gây ra lỗi (Bộ sưu tập đã được sửa đổi; hoạt động liệt kê có thể không thực thi). Nhưng bạn có thể thêm các đối tượng mà bạn muốn xóa/gỡ bỏ các bộ sưu tập khác:

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 

Những phương pháp này sẽ gây ra một danh sách để thay đổi nó là phiên bản (mà sẽ được kiểm tra trong quá trình điều tra):

  • Thêm
  • Rõ ràng
  • Chèn
  • InsertRange
  • Di
  • .210
  • RemoveRange
  • RemoveAt
  • Xếp
  • [các Indexer setter]
  • Sắp xếp

Một lựa chọn khác là sử dụng một For-Loop và vòng lặp nó ngược:

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 

chí này không tăng lỗi đó nhưng không thể đọc được. Bạn cần phải đi từ list.Count - 1 Đến 0 vì bạn muốn xóa các mục sẽ thay đổi thuộc tính Count và chỉ mục có sẵn trước khi mục bị xóa hiện tại là ArgumentOutOfRangeException.

Cuối cùng nhưng không kém, bạn có thể sử dụng List.RemoveAll:

lstEnemy.RemoveAll(Function(enemy) enemy.enemy.Left < 0) 
+1

+1 Câu trả lời tuyệt vời –

+0

tùy chọn khác là sử dụng một thời gian. câu trả lời chính xác –

0

Một ví dụ sử dụng Entity Framework (elementAt (i)):

for (int i = 0; i < db.Itens.Count(); i++) 
{ 
    Item item = db.Itens.ElementAt(i); 
    if (item.Id == 0) // put a condition 
    { 
     db.Itens.Remove(item); 
     i--; 
    } 
} 
Các vấn đề liên quan