Weird out of bounds problem (XNA)

Started by
4 comments, last by Postie 13 years ago
Hey guys.. I sure post a lot in these times ;)

Here I am again!

Im making a tower-defense like game, and I got boids moving around, and a player that can put towers up that shot and kill the boids.. Only problem is the program sometimes crahses when a boid dies!.. I save all the boids in a common list so I do with the towers (that right now is called Obstecals) and the shots per tower is also listed...

You can see the code here:


for (int i = 0; i < positionList.Count; i++)
{
for (int oi = 0; oi < obstecalList.Count; oi++)
{
for (int x = 0; x < obstecalList[oi].shotList.Count; x++)
{
if (boundingSphereList.Intersects(obstecalList[oi].shotList[x].boundingSphere))
{
killBoid(i);
continue;
}
}
continue;
}
continue;
}

for(int i = 0; i < positionList.Count; i++){
if (positionList.Translation.X <= -1000)
{
killBoid(i);
continue;
}
}

for (int i = 0; i < positionList.Count; i++)
{
if (player.boundingSphere.Intersects(boundingSphereList))
{
killBoid(i);
continue;
}

}


A boid will die when it is shot, reaches the end of the map, or collides with the player. The killBoid function deletes the boid from the positionList, velocityList and boundingSphereList and can be seen here.

public void killBoid(int i)
{
positionList.Remove(positionList);
velocityList.Remove(velocityList);
boundingSphereList.Remove(boundingSphereList);
}


btw. I know that right now this code is somewhat messy, but im far from the cleaning up stage ;) It will come!

The problem is apparently that when a boid gets killed the lists becomes shorter than they were before, and sometimes it will make a for-loop go out of bounds.. BUT! I don't understand why this happens, as I put a continue in to prevent this :S.. Shouldnt the continue make the program exit the loop as soon as it hits that ???? ...
Advertisement
Try having a vector list where the dead ones get stored. Then when you have looped throughout the other list then do the deleting with the new list. It should be faster the deleting then reordering your storage list.
Inefficiency of your code not withstanding, I think you mean break, not continue.

The continue keyword causes the program to immediately end that iteration of the inner-most loop and begin the next iteration.
The break keyword causes the program to immediately end the inner-most loop completely.
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler
thx both of you ^^

Im gonna try both things :) And as I said I know my code is messy at the moment, but Im just using this program/game to learn how to use XNA for a project, so I will reimplement pretty much everything at a later time ;) But thank you, both replies will help me quite a lot :)
[font="arial, verdana, tahoma, sans-serif"]There are several ways to delete an item when iterating forward through an array. You can decrement the counter when the delete happens.[/font]
[font="arial, verdana, tahoma, sans-serif"] [/font]
[font="arial, verdana, tahoma, sans-serif"]List list;[/font]
[font="arial, verdana, tahoma, sans-serif"] [/font][font="arial, verdana, tahoma, sans-serif"]for(int i=0; i<list.Count; i++)[/font][font="arial, verdana, tahoma, sans-serif"]
[color="#333333"][color="#000000"]{[/font]
[color="#333333"][color="#000000"] if(DeleteCondition(list)
[color="#333333"][color="#000000"] {
[color="#333333"][color="#000000"] list.RemoveAt(i);
[color="#333333"][color="#000000"] i--;
[color="#333333"][color="#000000"] }
[color="#333333"][color="#000000"]}

Or you can iterate backward through the list:


List list;
[color="#333333"][color="#000000"]for(int i=list.Count-1; i>=0; i--)
[color="#333333"][color="#000000"]{
if(DeleteCondition(list)
[color="#333333"][color="#000000"] {
[color="#333333"][color="#000000"] list.RemoveAt(i);
[color="#333333"][color="#000000"] }
[color="#333333"][color="#000000"]}

As mentioned above, you probably do not want to be managing your boids that way. Those C# lists you are using are managed arrays in consecutive memory. When you delete an item from the list, all items after it are copied forward (extremely inefficient if you have a lot of items, creates garbage which is bad on Xbox). You should probably be setting a "bool active" flag on each item in the list, where if "active!=true" that item is ignored. KillBoid() would simply set that active flag to false, no deleting anything. There are other ways as well.

edit: sorry, the code block functionality seems broken right now. It is inserting "color=xxxxxx" all over for no apparent reason.
EJH raises a good point. If you're going to be deleting random elements from the List all the time perhaps a LinkedList would be a better choice?
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler

This topic is closed to new replies.

Advertisement