Search code examples
xnacollision-detectionxna-4.0

Collision stops all characters moving in the list


I am making a game where characters come from opposite sides of the screen and collide and attack each other then they are removed when they die. I have managed to enable the lists to stop moving and do damage when they collide but my problem is when 2 of them collide all of them stop moving. My code for the shortswordsman collisions is:

private void shortMoveCollisions(GameTime gameTime)
    {
        Rectangle shortRect;
        int shortSpeed = 2;
        int shortDamage = 20;
        bool collided = false;

        for (int i = 0; i < shortList.Count; i++)
        {
            List<Goblin> tempGoblinList = new List<Goblin>(goblinList);
            shortRect = new Rectangle((int)shortList[i].position.X, (int)shortList[i].position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);

            foreach (Goblin goblin in tempGoblinList)
            {
                Rectangle goblinRect = new Rectangle((int)goblin.position.X, (int)goblin.position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
                if (shortRect.Intersects(goblinRect))
                {
                    collided = true;
                    shortList[i].AnimateAttack(gameTime);

                    shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    if (shortTimer >= shortDelay)
                    {
                        shortTimer -= shortDelay;
                        goblin.health -= shortDamage;
                        if (goblin.health <= 0)
                        {
                            goblinList.Remove(goblin);
                        }
                    }
                }
            }
            if (shortRect.Intersects(background.badCastleRect))
            {
                collided = true;
                shortList[i].AnimateAttack(gameTime);

                shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (shortTimer >= shortDelay)
                {
                    shortTimer -= shortDelay;
                    badCastleHealth -= shortDamage;
                }
             }
            if (collided == false)
            {
                shortList[i].AnimateWalk(gameTime);

                shortList[i].position.X += shortSpeed;
            }
        }
    }

And my code for the goblins collisions is:

private void GoblinMoveCollisions(GameTime gameTime)
    {
        Rectangle goblinRect;
        int goblinSpeed = 2;
        int goblinDamage = 20;
        bool collided = false;

        for (int i = 0; i < goblinList.Count; i++)
        {
            List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
            goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);

            foreach (ShortSwordsman shortSwordsman in tempShortList)
            {
                Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
                if (goblinRect.Intersects(shortRect))
                {
                    collided = true;
                    goblinList[i].AnimateAttack(gameTime);

                    goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    if (goblinAttackTimer >= goblinAttackDelay)
                    {
                        goblinAttackTimer -= goblinAttackDelay;
                        shortSwordsman.health -= goblinDamage;
                        if (shortSwordsman.health <= 0)
                        {
                            shortList.Remove(shortSwordsman);
                        }
                    }
                }
            }
            if (goblinRect.Intersects(background.goodCastleRect))
            {
                collided = true;
                goblinList[i].AnimateAttack(gameTime);

                goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (goblinAttackTimer >= goblinAttackDelay)
                {
                    goblinAttackTimer -= goblinAttackDelay;
                    goodCastleHealth -= goblinDamage;
                }
            }
            if (collided == false)
            {
                goblinList[i].AnimateWalk(gameTime);

                goblinList[i].position.X -= goblinSpeed;
            }
        }
    }

Solution

  • Your collided bool shouldn't be a variable of those classes, as those classes seem to operate on the entire lists of all the entities. Instead the collision detection should happen on an entity by entity basis, basically: make the collided bool a property of goblins and swordsmen. This would mean that you'll have to check for intersections with other creatures of the same type as well, probably without an attack command.