Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm creating a simple asteroids game and I have three lists with: big asteroids, small asteroids and missiles. When the player hits a big asteroid two small asteroids are created. But The problem is that for the most of the time, the two small asteroids never get time to show up! It seems like the missile hits them too, despite that I remove the missile from the list, before the small asteroids are created. The code below is from my object manager.

What is wrong and how can I improve my code to avoid this?

 // Check if missile hit big asteroid
    public void CollisionControlMissileHitAsteroidBig(ContentManager content)
    {
        for (int i = 0; i < missilesList.Count(); i++) 
        {
            for (int ii = 0; ii < asteroidsBigList.Count(); ii++) 
            {
                if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(ii).Bounds()))
                {
                    missilesList.RemoveAt(i); 
                    for(int x = 0; x < 2; x++)
                        AddNewSmallAsteroidToList(new AsteroidSmall(content, asteroidsBigList.ElementAt(ii).Position));

                    asteroidsBigList.RemoveAt(ii); 
                    i--;
                    ii--;
                }
            }
        }
    }

    // Check if missile hit small asteroid
    public void CollisionControlMissileHitAsteroidSmall()
    {
        for (int i = 0; i < missilesList.Count(); i++) 
        {
            for (int ii = 0; ii < asteroidsSmallList.Count(); ii++) 
            {
                if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsSmallList.ElementAt(ii).Bounds()))
                {
                    missilesList.RemoveAt(i); 
                    asteroidsSmallList.RemoveAt(ii); 
                    i--;
                    ii--;
                }
            }
        }
    }

EDIT:

I'm not sure I have done right? There are some problems, the big asteroids is still on the screen and then I guess the missile is still there to, because when two new small asteroids are created, most of the time there is only one, which I think is because it collide with the old missile? That's why I removed the missile from the list before I created the new small asteroids. More help is appreciated!

    public void CollisionControlMissileHitAsteroidBig(ContentManager content)
    {
        for (int i = 0; i < missilesList.Count(); i++)
        {
            for (int ii = 0; ii < asteroidsBigList.Count(); ii++) 
            {
                if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(ii).Bounds()))
                {
                    //missilesList.RemoveAt(i); 
                    for(int x = 0; x < 2; x++)
                        AddNewSmallAsteroidToList(new AsteroidSmall(content, asteroidsBigList.ElementAt(ii).Position));

                    asteroidsBigListRemove.Add(asteroidsBigList.ElementAt(ii)); 
                    missilesListRemove.Add(missilesList.ElementAt(i));
                }
            }
        }
        asteroidsBigListRemove.Clear();
        missilesListRemove.Clear();
    }
share|improve this question

put on hold as off-topic by Byte56 1 hour ago

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions about debugging a problem in your project must present a concise selection of code and context so as to allow a reader to diagnose the issue without needing to read all of your code or to engage in extensive back-and-forth dialog. For more information, see this meta thread." – Byte56
If this question can be reworded to fit the rules in the help center, please edit the question.

2  
Fix my code questions are not good questions. Too localized. –  Byte56 Jul 18 '12 at 14:42
    
Not sure, but maybe worth posting over at codereview.stackexchange.com –  Nate Jul 18 '12 at 20:12
    
@NateBross I don't think code review likes fix my code questions either :). From their FAQ, if you answer no to "To the best of your knowledge, does the code work?" then your question is off topic. So it appears they accept functional code only. –  Byte56 Jul 18 '12 at 20:27
    
@Byte56 good call, I just found out about them... (or maybe I knew before and was just reminded?) but a good catch on their FAQ never-the-less. –  Nate Jul 18 '12 at 21:33
    
Down voters are starting to turn into bouncers around here. If we're not here to help solve problems, what's the point? –  David Lively Jul 23 '12 at 20:05

1 Answer 1

Are you accidentally firing more than one missile at a time? Is it possible that your code creates two missiles at the same point in time and it's the second one that's hitting the asteroids?

Edit:

To solve the problem of removing asteroids and missiles, you create 'to remove' lists. Using your code:

public void CollisionControlMissileHitAsteroidBig(ContentManager content)
{
    for (int i = 0; i < missilesList.Count(); i++)
    {
        for (int ii = 0; ii < asteroidsBigList.Count(); ii++) 
        {
            if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(ii).Bounds()))
            {
                //missilesList.RemoveAt(i); 
                for(int x = 0; x < 2; x++)
                    AddNewSmallAsteroidToList(new AsteroidSmall(content, asteroidsBigList.ElementAt(ii).Position));

                asteroidsBigListRemove.Add(asteroidsBigList.ElementAt(ii)); 
                missilesListRemove.Add(missilesList.ElementAt(i));
            }
        }
    }

    foreach( var asteroid in asteroidsBigListRemove )
    {
        asteroidsBigList.Remove( asteroid );
    }
    asteroidsBigListRemove.Clear();

    foreach( var missile in missilesListRemove)
    {
        asteroidsBigList.Remove( asteroid );
    }
    missilesListRemove.Clear();
}

This means that you don't remove items from the list while you're still iterating over them. If you don't want to do this, the second option is to check items from the back first:

for (int i = missilesList.Count() - 1; i >= 0; i--)
{
    for (int ii = asteroidsBigList.Count() - 1; ii >= 0; ii--)
    {
        if (missilesList.ElementAt(i).Bounds().Intersects(asteroidsBigList.ElementAt(ii).Bounds()))
        {
            missilesList.RemoveAt(i); 

and so on.

share|improve this answer
    
From the beginning I only created and added one missile, but since I sometimes got and Argument out of range exception error, I added 3 missile each time I pressed the fire button. Now when I changed back the first issue is solved, but then I'm back at the other problem with this error. Now I need to solve this instead! Any suggestions how I can avoid this problem. This problem can occure at any time. When I fire fore the forst time och after some playing and sometimes never at all!? Preciate some help! –  3D-kreativ Jul 18 '12 at 9:47
1  
You're removing items from the missileList as you iterate over the missileList. You should add the missiles and asteroids to 'to be deleted' lists and them remove them when you're done iterating over them. –  Matt Kemp Jul 18 '12 at 10:12
    
Please look at my edit! –  3D-kreativ Jul 18 '12 at 14:35
    
Want to make this more answer like and less comment like? –  Byte56 Jul 18 '12 at 14:39
    
@MattKemp alternatively, iterate backwards through the list and remove as you go. Saves a loop. –  David Lively Jul 18 '12 at 19:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.