Hey Everyone,
I'm running into a strange exception while dealing with enumerators, in C#. The odd part is that it is inconsistent as to when the exception is thrown. I'll post clips of my code to help explain.
I have CheckCollisions() which runs in Update() and works perfectly fine when I collide with a gc that is a Wall.
but, I get the exception when I collide with a gc that is a Plant. (in line 5 at "in")
| 1 |
protected void CheckCollisions() |
| 2 |
{ |
| 3 |
bool hasCollision = false; |
| 4 |
|
| 5 |
foreach (GameComponent gc in Components) |
| 6 |
{ |
| 7 |
if (gc is Wall) |
| 8 |
{ |
| 9 |
hasCollision = ((Wall)gc).CircleCollides(player); |
| 10 |
if (hasCollision) |
| 11 |
{ |
| 12 |
Vector2 pVelocity = player.GetVelocity(); |
| 13 |
Vector2 pPosition = player.GetPosition(); |
| 14 |
player.SetPosition(pPosition-pVelocity); |
| 15 |
player.SetVelocity(-pVelocity *0.2f); |
| 16 |
} |
| 17 |
} |
| 18 |
|
| 19 |
else if (gc is Plant) |
| 20 |
{ |
| 21 |
hasCollision = ((Plant)gc).CircleCollides(player); |
| 22 |
if (hasCollision) |
| 23 |
{ |
| 24 |
int current = player.GetPlant(); |
| 25 |
int value = ((Plant)gc).GetValue(); |
| 26 |
player.SetPlant(current + value); |
| 27 |
gc.Dispose(); |
| 28 |
} |
| 29 |
} |
| 30 |
} |
The interesting part, is that they is very little difference between the two classes. Both are created in a similar fashion and both are displaying properly on the screen.
| 1 |
// Spawn Walls on right click |
| 2 |
if (player != null && mouse.RightButton == ButtonState.Pressed && lastmouse.RightButton == ButtonState.Released) |
| 3 |
{ |
| 4 |
Vector2 wallPosition = new Vector2((mouse.X - 32), (mouse.Y - 32)); |
| 5 |
SpawnWall(wallTexture, wallSize, wallPosition); |
| 6 |
} |
| 7 |
|
| 8 |
|
| 9 |
// Spawn plant on left control |
| 10 |
if (player != null && keyboard.IsKeyDown(Keys.LeftControl) && lastkeyboard.IsKeyUp(Keys.LeftControl)) |
| 11 |
{ |
| 12 |
Vector2 plantPosition = new Vector2((mouse.X - 8), (mouse.Y - 8)); |
| 13 |
Vector2 still = new Vector2(0, 0); |
| 14 |
SpawnPlant(plantTexture, plantSize, plantPosition, still, 1); |
| 15 |
} |
...
| public Wall SpawnWall(Texture2D texture, Vector2 size, Vector2 position) |
| { |
| Wall wall = new Wall(this, ref texture, size, position); |
| Components.Add(wall); |
| return wall; |
| } |
| |
| public Plant SpawnPlant(Texture2D texture, Vector2 size, Vector2 position, Vector2 velocity, int value) |
| { |
| Plant plant = new Plant(this, ref texture, size, position, velocity, value); |
| Components.Add(plant); |
| return plant; |
| } |
I have checked the enumeration list while running and both are being added properly, but only when I collide with a Plant, does it produce the exception.
I'm sure it is something simple, but I am not that experienced with C#.
Thank you for your help!
-Matthew Church
here is the extra info if you want:
System.InvalidOperationException was unhandled
Message="Collection was modified; enumeration operation may not execute."
Source="mscorlib"
StackTrace:
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at PathfindingA.Game1.CheckCollisions() in C:\Users\User\Documents\Visual Studio 2008\Projects\PathfindingD\PathfindingA\Main\Game1.cs:line 210
at PathfindingA.Game1.Update(GameTime gameTime) in C:\Users\User\Documents\Visual Studio 2008\Projects\PathfindingD\PathfindingA\Main\Game1.cs:line 170
at Microsoft.Xna.Framework.Game.Tick()
at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
at Microsoft.Xna.Framework.GameHost.OnIdle()
at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Microsoft.Xna.Framework.WindowsGameHost.Run()
at Microsoft.Xna.Framework.Game.Run()
at PathfindingA.Program.Main(String[] args) in C:\Users\User\Documents\Visual Studio 2008\Projects\PathfindingD\PathfindingA\Main\Program.cs:line 14
InnerException: