Sign in to follow this  
ProjectOlle

Weird out of bounds problem (XNA)

Recommended Posts

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:

[code]
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[i].Intersects(obstecalList[oi].shotList[x].boundingSphere))
{
killBoid(i);
continue;
}
}
continue;
}
continue;
}

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

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

}
[/code]

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.

[code]public void killBoid(int i)
{
positionList.Remove(positionList[i]);
velocityList.Remove(velocityList[i]);
boundingSphereList.Remove(boundingSphereList[i]);
}[/code]

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 ???? ...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
[font="arial, verdana, tahoma, sans-serif"][size="2"]There are several ways to delete an item when iterating forward through an array. You can decrement the counter when the delete happens.[/size][/font]
[font="arial, verdana, tahoma, sans-serif"] [/font]
[font="arial, verdana, tahoma, sans-serif"][size="2"]List list;[/size][/font]
[font="arial, verdana, tahoma, sans-serif"] [/font][font="arial, verdana, tahoma, sans-serif"][size="2"]for(int i=0; i<list.Count; i++)[/size][/font][font="arial, verdana, tahoma, sans-serif"][size="2"]
[color="#333333"][color="#000000"]{[/color][/color][/size][/font]
[color="#333333"][color="#000000"] if(DeleteCondition(list[i])[/color][/color]
[color="#333333"][color="#000000"] {[/color][/color]
[color="#333333"][color="#000000"] list.RemoveAt(i);[/color][/color]
[color="#333333"][color="#000000"] i--;[/color][/color]
[color="#333333"][color="#000000"] }[/color][/color]
[color="#333333"][color="#000000"]}
[/color][/color]
Or you can iterate backward through the list:


List list;
[color="#333333"][color="#000000"]for(int i=list.Count-1; i>=0; i--)[/color][/color]
[color="#333333"][color="#000000"]{[/color][/color]
if(DeleteCondition(list[i])
[color="#333333"][color="#000000"] {[/color][/color]
[color="#333333"][color="#000000"] list.RemoveAt(i);[/color][/color]
[color="#333333"][color="#000000"] }[/color][/color]
[color="#333333"][color="#000000"]}
[/color][/color]
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this