Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7627341
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T05:26:46+00:00 2026-05-31T05:26:46+00:00

I have a list populated with a sprite class I created. I use this

  • 0

I have a list populated with a sprite class I created. I use this to call the update and draw methods on each. The problem is, when one is destroyed, I need to remove it from that list. When I try to do so, the next update or draw method gets an error: “Collection was modified; enumeration operation may not execute.” I don’t know how to fix this…any help would be appreciated. Thank you!

EDIT: Okay, source code it is, but be warned, it’s spread out across many classes and it’s not very organized:

Okay, so here’s the GameComponent class this is all originating from:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 
using ShipBattle.Classes; 
using ShipBattle.Classes.Ships.Fighters; 

namespace ShipBattle 
{ 
    /// <summary> 
    /// This is a game component that implements IUpdateable. 
    /// </summary> 
    public class BuildMenu : DrawableGameComponent 
    { 
        enum RaceSelected { Tauri, Goauld } 
        RaceSelected raceSelected; 

        Button f302Button, engageButton; 
        ListButton tauriButton, goauldButton; 
        Sprite deathGlider, menu, f302Stats; 

        SpriteBatch spriteBatch; 
        SpriteFont font; 

        /*
         * [0] F302s 
         * [1] Death Gliders
         * [2] Al'kesh's
         * [3] Promethei
         * [4] Ha'tak's
         * [5] Daedaluses
         */ 
        List<int> buildList; 
        List<int> enemyBuildList; 

        public BuildMenu(Game game) 
            : base(game) 
        { 
            spriteBatch = new SpriteBatch(Game.GraphicsDevice); 
            buildList = new List<int>(); 
            enemyBuildList = new List<int>(); 
            raceSelected = RaceSelected.Tauri; 
        } 

        /// <summary> 
        /// Allows the game component to perform any initialization it needs to before starting 
        /// to run.  This is where it can query for any required services and load content. 
        /// </summary> 
        public override void Initialize() 
        { 
            buildList.Add(0); 
            base.Initialize(); 
            enemyBuildList.Add(10); 
        } 

        /// <summary> 
        /// LoadContent will be called once per game and is the place to load 
        /// all of your content. 
        /// </summary> 
        protected override void LoadContent() 
        { 
            //Fonts needed for info 
            font = Game.Content.Load<SpriteFont>(@"Fonts/MenuFont"); 

            //The little enemy ship icons at the top 
            deathGlider = new Sprite(Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Enemy Ships/Death Glider"), new Vector2(30, 85), Color.White, 
                0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f); 

            //The actual build buttons 
            f302Button = new Button(new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Player Ships/F-302/F-302") }, 
                new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Player Ships/F-302/F-302 On Over") }, 
                new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Player Ships/F-302/F-302 On Click") }, 
                new Vector2(50, 175), Color.White, 0.0f, Vector2.Zero, 0.5f, SpriteEffects.None, 0.5f, 1, false, false, false, true); 
            f302Button.onClick += new OnClick(f302_onClick); 
            f302Button.onRightClick +=new OnClick(f302Button_onRightClick); 
            f302Stats = new Sprite(Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Player Ships/F-302/Stats"),  
                new Vector2(f302Button.Position.X + (f302Button.Textures[0].Width / 2), f302Button.Position.Y), Color.White, 0.0f, Vector2.Zero, 0.5f, SpriteEffects.None, 1.0f); 

            //The button to change the race 
            tauriButton = new ListButton(Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri On Over"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri On Click"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri Selected"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri Selected On Over"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Tauri/Tauri Selected On Click"), 
                new Vector2(512, 710), true); 
            tauriButton.onClick +=new OnClick(tauriButton_onClick); 
            goauldButton = new ListButton(Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld On Over"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld On Click"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld Selected"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld Selected On Over"), 
                Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Race Buttons/Goauld/Goauld Selected On Click"), 
                new Vector2(562, 710), true); 
            goauldButton.onClick += new OnClick(goauldButton_onClick); 

            //The menu background 
            menu = new Sprite(Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Build Menu"), Vector2.Zero, Color.White, 0.0f, Vector2.Zero, 1.0f, 
                SpriteEffects.None, 0.0f); 

            //The little button that says, "Engage" at the buttom 
            engageButton = new Button(new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Engage Button/Engage Button") }, 
                new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Engage Button/Engage Button On Over") }, 
                new Texture2D[] { Game.Content.Load<Texture2D>(@"Textures/Menus/Build Menu/Engage Button/Engage Button On Click") }, 
                new Vector2 (1024 - 125, 768 - 125), Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f, 1, false, false, false, false); 
            engageButton.onClick += new OnClick(engageButton_onClick); 


            base.LoadContent(); 
        } 

        /// <summary> 
        /// Allows the game component to update itself. 
        /// </summary> 
        /// <param name="gameTime">Provides a snapshot of timing values.</param> 
        public override void Update(GameTime gameTime) 
        { 
            switch (((Game1)Game).Level) 
            { 
                case 1: 
                    Level1Update(); 
                    break; 
            } 

            switch (raceSelected) 
            { 
                case RaceSelected.Tauri: 
                    tauriButton.IsSelected = true; 
                    goauldButton.IsSelected = false; 
                    break; 

                case RaceSelected.Goauld: 
                    tauriButton.IsSelected = false; 
                    goauldButton.IsSelected = true; 
                    break; 
            } 



            tauriButton.Update(); 
            goauldButton.Update(); 
            engageButton.Update(); 

            base.Update(gameTime); 
        } 

        /// <summary> 
        /// This is called when the game should draw itself. 
        /// </summary> 
        /// <param name="gameTime">Provides a snapshot of timing values.</param> 
        public override void Draw(GameTime gameTime) 
        { 
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend); 


            switch (((Game1)Game).Level) 
            { 
                case 1: 
                    Level1Draw(); 
                    break; 
            } 

            engageButton.Draw(spriteBatch); 

            spriteBatch.DrawString(font, "$" + ((Game1)Game).player.Money.ToString(), new Vector2(800, 160), Color.White, 0.0f, Vector2.Zero, 1.0f, 
                SpriteEffects.None, 1.0f); 

            menu.Draw(spriteBatch); 

            spriteBatch.End(); 
            base.Draw(gameTime); 
        } 

        /*
         * Event Handlers
         */ 

        //Click the button! 
        private void f302_onClick(object sender, EventArgs e) 
        { 
            if (((Game1)Game).player.Money > 0) 
            { 
                buildList[0]++; 
                ((Game1)Game).player.Money -= 200; 
            } 
        } 

        private void f302Button_onRightClick (object sender, EventArgs e) 
        { 
            if (buildList[0] > 0) 
            { 
                buildList[0]--; 
                ((Game1)Game).player.Money += 200; 
            } 
        } 

        //Click the go button! 
        private void engageButton_onClick (object sender, EventArgs e) 
        { 
            ((Game1)Game).fightScreen.GetShips(enemyBuildList, buildList); 
            ((Game1)Game).gameState = GameState.InGame; 
        } 

        //Change the race 
        private void tauriButton_onClick(object sender, EventArgs e) 
        { 
            raceSelected = RaceSelected.Tauri; 
        } 

        private void goauldButton_onClick(object sender, EventArgs e) 
        { 
            raceSelected = RaceSelected.Goauld; 
        } 

        //Level-specific Update and Draw  
        //functions 
        private void Level1Update() 
        { 
            switch (raceSelected) 
            { 
                case RaceSelected.Tauri: 
                    f302Button.Update(); 

                    break; 

                case RaceSelected.Goauld: 
                    break; 
            } 
        } 

        private void Level1Draw() 
        { 
            switch (raceSelected) 
            { 
                case RaceSelected.Tauri: 
                    //F-302 Stuff 
                    f302Button.Draw(spriteBatch); 
                    f302Stats.Draw(spriteBatch); 
                    spriteBatch.DrawString(font, buildList[0].ToString(), 
                        new Vector2(f302Button.Position.X, (f302Button.Position.Y + (f302Button.Textures[0].Height / 2)) - 35), 
                        Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f); 

                    break; 

                case RaceSelected.Goauld: 
                    break; 
            } 

            tauriButton.Draw(spriteBatch); 
            goauldButton.Draw(spriteBatch); 
            deathGlider.Draw(spriteBatch); 

        } 
    } 
} 

And this is my Ship class:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using ShipBattle.Classes.Ships.Projectiles; 
using ShipBattle.Classes.Ships.Projectiles.Tauri; 

namespace ShipBattle.Classes.Ships 
{ 
    public abstract class Ship 
    { 
        public Texture2D Texture { get; set; } 
        public Vector2 Position 
        { 
            get 
            { 
                return _position; 
            } 
            set 
            { 
                _position = value; 
            } 
        } 
        public float Rotation { get; set; } 

        private Vector2 _position; 
        #region Health & Shielding 
        protected float hullIntegrity; 
        protected float shieldStrength; 
        #endregion 
        #region Guns 
        protected List<Vector2> WeaponsEnplacements = new List<Vector2>(); 
        protected List<Vector2> WeaponEmplacementOffsets = new List<Vector2>(); 
        /// <summary> 
        /// The rates of fire for all weapons, represented in terms of the delay between frames 
        /// </summary> 
        protected List<float> WeaponRatesOfFire = new List<float>(); 
        protected abstract List<float> CooldownLeft { get; set; } 
        protected List<Projectile> Projectiles = new List<Projectile>(); 
        protected int[] Ammo; 
        protected int[] Damage; 
        #endregion 
        #region Targeting Logic 
        bool hasTarget = false; 
        int targetHashCode; 
        Vector2 targetShipPosition; 
        Ship target; 
        #endregion 
        #region Physics Stuff 
        float angleA, b, a, speed = 0; 
        double turningRadius = 10 * (Math.PI / 180); 

        //Acceleration 
        protected int mass; // kg 
        protected float force; // kN, thruster power 
        protected float acceleration; // m/s^2 

        //Velocity 
        protected float maxSpeed; // m/s, calculated using 30-second burn 
        protected float initialSpeed = 0; 
        protected float finalSpeed = 0; 
        protected float time = 0.016666f; 
        #endregion 

        public void Update(List<Ship> ships) 
        { 
            if (!hasTarget) 
            { 
                targetHashCode = GetTarget(ships).GetHashCode(); 
                hasTarget = true; 
            } 
            else 
                foreach (Ship ship in ships) 
                    if (targetHashCode == ship.GetHashCode()) 
                    { 
                        CheckTarget(ship); 
                        targetShipPosition = ship.Position; 
                        target = ship; 
                    } 


            //Rotate the sprite using the turning radius 
            Rotation = Utilities.TurnToFace(Position, new Vector2(targetShipPosition.X, targetShipPosition.Y), (float)Rotation, (float)turningRadius); 

            //Move the sprite, using KINEMATIC PHYSICS, ***!!! 
            Move(); 

            //Recalculate the List<Vector2> weapons enplacements based on the current rotation angle 
            RecalculateWeaponsPositions(); 

            //Cooldown the guns 
            Cooldown(); 

            for (int i = 0; i < Projectiles.Count; i++) 
                if (Projectiles[i].Remove) 
                    Projectiles.RemoveAt(i); 

            foreach (Projectile p in Projectiles) 
                p.Update(targetShipPosition); 
        } 

        public void Draw(SpriteBatch spriteBatch) 
        { 
            spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, new Vector2(Texture.Width / 2, Texture.Height / 2), 0.5f, 
                SpriteEffects.None, 0.0f); 

            foreach (Projectile p in Projectiles) 
                p.Draw(spriteBatch); 
        } 

        /// <summary> 
        /// Uses trig and the thruster power to move the ship. b is the y distance to move, a is the x distance to move 
        /// </summary> 
        private void Move() 
        { 
            if (finalSpeed < maxSpeed) 
                finalSpeed = speed + (acceleration * time); 

            angleA = Rotation; 

            b = (float)Math.Cos(angleA) * finalSpeed; 
            a = (float)Math.Sin(angleA) * finalSpeed; 

            _position.Y -= b; 
            _position.X += a; 

            speed = finalSpeed; 
        } 

        /// <summary> 
        /// Acquires the closes enemy ship 
        /// </summary> 
        /// <param name="ships">The ships to search through</param> 
        /// <returns></returns> 
        private Ship GetTarget(List<Ship> ships) 
        { 
            Ship rVal = null; 
            int distance = int.MaxValue; 
            float c; 

            foreach (Ship ship in ships) 
            { 
                c = Vector2.Distance(Position, ship.Position); 

                if (c < distance) 
                    rVal = ship; 
            } 

            return rVal; 
        } 

        /// <summary> 
        /// Reorients the positions of all the weapon positions on this ship 
        /// </summary> 
        private void RecalculateWeaponsPositions() 
        { 
            for (int i = 0; i < WeaponsEnplacements.Count; i++) 
            { 
                WeaponsEnplacements[i] = RotateWeapons(WeaponEmplacementOffsets[i]); 
            } 
        } 

        /// <summary> 
        /// Recalculates the positions of the weapons on this ship based off their default offset and the current angle 
        /// </summary> 
        /// <param name="weapon">The weapon position to recalculate</param> 
        /// <param name="offset">The default offset of that weapon</param> 
        private Vector2 RotateWeapons(Vector2 offset) 
        { 
            Quaternion rotation = Quaternion.CreateFromAxisAngle(Vector3.Backward, (float)Rotation); 
            return Vector2.Transform(offset, rotation) + Position; 
        } 

        protected void Projectile_Hit(Projectile sender, EventArgs e) 
        { 
            sender.Remove = true; 

            if (sender is RailgunRound) 
                if (target.shieldStrength <= 0) 
                    target.hullIntegrity -= sender.Damage; 
                else 
                    target.shieldStrength -= sender.Damage / 4; 
        } 


        /// <summary> 
        /// Checks to see if the target ship is within weapons range 
        /// </summary> 
        /// <param name="target"></param> 
        protected abstract void CheckTarget(Ship target); 

        /// <summary> 
        /// Decrements the cooldown of all weapons 
        /// </summary> 
        protected abstract void Cooldown(); 
    } 
} 

This is the subclassed F-302 that is producing the Projectile class: this is where the error actually occurs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.Graphics; 
using ShipBattle.Classes.Ships.Projectiles; 
using ShipBattle.Classes.Ships.Projectiles.Tauri; 

namespace ShipBattle.Classes.Ships.Fighters 
{ 
    public class F302 : Ship 
    { 
        const double missileMinimumFiringArc = Utilities.NINETY_DEGREES / 2; 
        const double missileMaximumFiringArc = Utilities.NINETY_DEGREES + (Utilities.NINETY_DEGREES / 2); 
        const double railgunMinimumFiringArc = 1.5; 
        const double railgunMaximumFiringArc = 1.6; 

        protected override List<float> CooldownLeft { get; set; } 
        private ContentManager content; 

        public F302(Vector2 position, ContentManager Content) 
        { 
            content = Content; 
            Texture = content.Load<Texture2D>(@"Textures\Ships\Tauri\Fighters\F302"); 
            Position = position; 
            Rotation = 0; 
            #region Physics Stuff 
            mass = 19200; 
            force = 76.3f; 

            acceleration = (force * 1000) / mass; 
            maxSpeed = Utilities.GetVelocity(acceleration); 
            #endregion 
            #region Hull & Shielding 
            hullIntegrity = 10; 
            shieldStrength = 0; 
            #endregion 
            #region Weapons!!! 
            /*
             * [0] = Port Missile
             * [1] = Starboard Missile
             * [2] = Port Railgun
             * [3] = Starboard Railgun
             */ 
            Ammo = new int[4]; 
            Damage = new int[4]; 

            //Port Missile 
            WeaponsEnplacements.Add(new Vector2(14, 5)); 
            WeaponEmplacementOffsets.Add(new Vector2(14, 5)); 
            Ammo[0] = 2; 
            Damage[0] = 50; 
            WeaponRatesOfFire.Add(0); 

            //Starboard Missile 
            WeaponsEnplacements.Add(new Vector2(35, 5)); 
            WeaponEmplacementOffsets.Add(new Vector2(35, 5)); 
            Ammo[1] = 2; 
            Damage[1] = 50; 
            WeaponRatesOfFire.Add(0); 

            //Cooldowns = 7.2f 
            //Port Railgun 
            WeaponsEnplacements.Add(new Vector2(24, 0)); 
            WeaponEmplacementOffsets.Add(new Vector2(24, 0)); 
            Ammo[2] = 10000; 
            Damage[2] = 2; 
            WeaponRatesOfFire.Add(30.0f); 

            //Starboard Railgun 
            WeaponsEnplacements.Add(new Vector2(26, 0)); 
            WeaponEmplacementOffsets.Add(new Vector2(26, 0)); 
            Ammo[3] = 10000; 
            Damage[3] = 2; 
            WeaponRatesOfFire.Add(30.0f); 

            CooldownLeft = WeaponRatesOfFire; 
            Projectiles = new List<Projectile>(); 
            #endregion 
        } 

        protected override void CheckTarget(Ship target) 
        { 
            double distance = Vector2.Distance(Position, target.Position); 

            Vector2 vector1 = Vector2.Normalize(Position - target.Position); 
            Vector2 vector2 = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation)); 

            double angle = Math.Acos(Vector2.Dot(vector1, vector2)); 

            if (angle > missileMinimumFiringArc && angle < missileMaximumFiringArc) 
            { 
                if (distance < 250) 
                    FireMissiles(); 
            } 

            if (angle > railgunMinimumFiringArc && angle < railgunMaximumFiringArc) 
                FireRailguns(); 
        } 

        protected void FireMissiles() 
        { 
            //Add code so you don't waste all your missiles on one death glider 
        } 

        protected void FireRailguns() 
        { 
            //If the port railgun is ready to fire 
            if (CooldownLeft[2] <= 0) 
            { 
                RailgunRound rr = new RailgunRound(WeaponsEnplacements[0], Rotation, content); 
                rr.hit += new ProjectileHit(Projectile_Hit); 
                Projectiles.Add(rr); 

                //Reset the cooldown 
                CooldownLeft[2] = WeaponRatesOfFire[2]; 
            } 

            //If the port railgun is ready to fire 

            if (CooldownLeft[3] <= 0) 
            { 
                Projectiles.Add(new RailgunRound(WeaponsEnplacements[1], Rotation, content)); 

                //Reset the cooldown 
                CooldownLeft[3] = WeaponRatesOfFire[3]; 
            } 
        } 

        protected override void Cooldown() 
        { 
            for (int f = 0; f < CooldownLeft.Count; f++) 
                CooldownLeft[f]--; 
        } 
    } 
} 

This is the projectile class that’s causing the issue:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework; 
using ShipBattle.Classes; 

namespace ShipBattle.Classes.Ships.Projectiles 
{ 
    public abstract class Projectile 
    { 
        protected Texture2D Texture { get; set; } 
        public Vector2 Position 
        { 
            get 
            { 
                return _position; 
            } 

            set 
            { 
                _position = value; 
            } 
        } 
        protected Vector2 _position; 
        protected float Rotation { get; set; } 

        public event ProjectileHit hit; 
        protected Rectangle enemyRect; 

        public float Damage { get; set; } 
        public bool Remove { get; set; } 

        #region Physics Stuff 
        protected float angleA, b, a, speed = 0; 
        protected double turningRadius = MathHelper.ToRadians(360); 

        //Acceleration 
        protected float mass; // kg 
        protected float force; // kN, thruster power 
        protected float acceleration; // m/s^2 

        //Velocity 
        protected float maxSpeed; // m/s, calculated using 30-second burn 
        protected float initialSpeed = 0; 
        protected float finalSpeed = 0.0f; 
        protected float time = 0.016666f; 
        #endregion 

        /// <summary> 
        /// Updates the projectile sprite 
        /// </summary> 
        /// <param name="Pos">The position of the enemy</param> 
        public void Update(Vector2 pos) 
        { 
            enemyRect.X = (int)pos.X; 
            enemyRect.Y = (int)pos.Y; 

            Rotation = Utilities.TurnToFace(Position, new Vector2(pos.X, pos.Y), (float)Rotation, (float)turningRadius); 
            //Is things up? 
            Move(); 

            if (enemyRect.Contains((int)Position.X, (int)Position.Y)) 
                hit(this, new EventArgs()); 
        } 

        public void Draw(SpriteBatch spriteBatch) 
        { 
            spriteBatch.Draw(Texture, Position, null, Color.White, Rotation, new Vector2(Texture.Width / 2, Texture.Height / 2), 1.0f, SpriteEffects.None, 0.1f); 
        } 

        protected void Move() 
        { 
            if (finalSpeed < maxSpeed) 
                finalSpeed = speed + (acceleration * time); 

            angleA = Rotation; 

            b = (float)Math.Cos(angleA) * finalSpeed; 
            a = (float)Math.Sin(angleA) * finalSpeed; 

            _position.Y -= b; 
            _position.X += a; 

            speed = finalSpeed; 
        } 

    } 
} 

And finally, this is the RailgunRounds, a subclass of projectile, the only one I’m currently spawning, but it’s causing the issue:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Content; 

namespace ShipBattle.Classes.Ships.Projectiles.Tauri 
{ 
    public class RailgunRound : Projectile 
    { 
        public RailgunRound(Vector2 Pos, float Rot, ContentManager content) 
        { 
            this.Texture = content.Load<Texture2D>(@"Textures\Ships\Tauri\Weapons\Railgun Round"); 
            this.Position = Pos; 
            this.Rotation = Rot; 

            mass = 0.5f; 
            force = 5; 
            acceleration = (force * 1000) / mass; 
            maxSpeed = 28.3575f; 

            enemyRect = new Rectangle(); 
            enemyRect.Width = 50; 
            enemyRect.Height = 50; 

            Damage = 2; 
            Remove = false; 
        } 
    } 
} 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T05:26:47+00:00Added an answer on May 31, 2026 at 5:26 am

    The problem is that you’re using a foreach, and while looping through your sprites you’re removing one which alters the container, which makes it impossible to properly loop forward through. To better illustrate why this is causing a problem, let’s look at a simple example using a standard for loop.

    // For this example let's say myContainer has 4 elements in it.
    for ( int i = 0; i < myContainer.size(); ++i )
    {
        if ( someConditionIsMet )
        {
            myContainer.Remove(i);
        } 
    }
    

    In the example above, let’s just say that someConditionIsMet evaluates to true every other loop. So here’s the results of our loop:

    1.) i = 0, someConditionIsMet is false, so we do nothing.
    2.) i = 1, someConditionIsMet is true, so we remove myContainer at index 1. myContainer.size() is now 3.
    3.) i = 2, someConditionIsMet is false, so we do nothing.
    4.) i = 3, so we do not loop again because 3 is not less than myContainer.size(), which is 3.
    

    See the problem? When i was equal to 1, we removed something from myContainer, which changed its size, so when i was 3 we did not get a chance to remove another element from myContainer. This is what could happen if you were able to alter a container when you were using foreach.

    There are a couple of solutions to this problem:

    1.) Use a for loop, and iterate from the end of the container.

    // For this example let's say myContainer has 4 elements in it.
    for ( int i = myContainer.size() - 1; i >= 0; --i )
    {
        if ( someConditionIsMet )
        {
            myContainer.Remove(i);
        } 
    }
    
    1.) i = 3, someConditionIsMet is true, so we remove myContainer at index 3. myContainer.size() is now 3. 
    2.) i = 2, someConditionIsMet is false, so we do nothing.
    3.) i = 1, someConditionIsMet is true, so we remove myContainer at index 1. myContainer.size() is now 2. 
    4.) i = 0, someConditionIsMet is false, so we do nothing.
    

    Now you can see that we managed to properly delete two entries in which someConditionIsMet was true, whereas in the first example we were only able to delete one entry. This solution provides better performance than the next example (below).

    2.) You can maintain a list of everything that needs to be removed while iterating with your foreach, and then remove them later on with a reverse for loop. This is less efficient, but in some cases you’ll find that you need to iterate through a loop in the forward direction because order might matter.

    List<entries> entriesToRemove = new List<entries>();
    
    foreach(entry in myContainer)
    {
        if ( someConditionIsMet )
        {
            entriesToRemove.Add(entry);
        } 
    }
    
    for ( int i = entriesToRemove.size() - 1; i > 0; --i )
    {
        myContainer.Remove(entriesToRemove[i]);
    }
    entriesToRemove.clear();
    

    3.) Use a for loop, iterate in a the forward direction, and anytime you remove an element from the container just decrement your iterator afterward. This was already mentioned in another answer on this page already (posted by Acidic), so I don’t take credit for this:

    for ( int i = 0; i < myContainer.size(); ++i )
    {
        if ( someConditionIsMet )
        {
            myContainer.Remove(i);
            --i;
        } 
    }
    
    1.) i = 0, someConditionIsMet is false, so we do nothing.
    2.) i = 1, someConditionIsMet is true, so we remove myContainer at index 1. myContainer.size() is now 3. We decrement i by 1, so it's now 0 again but will be 1 on the next iteration because of the ++i in the for loop.
    3.) i = 1, someConditionIsMet is false, so we do nothing.
    4.) i = 2, someConditionIsMet is true, so we remove myContainer at index 2. myContainer.size() is now 2. We decrement i by 1, so it's now 1 again but will be 2 on the next iteration because of the ++i in the for loop so we will not loop again because 2 is not less than myContainer.size(), which is now 2.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a DataGridView populated with a BindingList . This list gets saved into
I have a UserForm class which has a select list populated from a related
I have a dropdown list which is populated via a jquery ajax call when
This is all in C#, using .NET 3.5. I have a list populated with
I have list of MyObject that looks like this: public class MyObject{ public int
I have a dropdown list populated with some items. When the user selects one
I have a dropdown list that is populated on a content page like this
I have a jquery mobile list. This list is populated with data. I want
I have a bound dropdown list populated with a table of names through a
We have an auto-complete list that's populated when an you send an email to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.