• 13
• 14
• 27
• 9
• 9

# Problem with my sprite generator

This topic is 3650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

OK. I am randomly generating new enemies that goes from one side of the screen to another. I am using a vector to store these. However. It seems that sometimes i am just creating the enemy, and not storing it in the vector. I am not quite sure of what is going wrong. (result in some textured boxes, and some not) this is the only place where i generate new bodies, so the problem has to be located here.
[source langg = "cpp"]
vector<Sprite> Sprites;
.........................

if( rand() % 150 == 0)
{
cout << "About to spawn sprite " << endl;
spawnsprites();

}
............
void spawnsprites()
{

Sprite tempbox;

//define tempbox
if(!Sprites.empty())
{

for(vector<Sprite>::iterator iter = Sprites.begin(); iter != Sprites.end(); iter++)
{
if(!inside(tempbox,(*iter)))
{
cout << "couldnt make body, calculating new pos" << endl;
tempbox.body->SetOriginPosition( b2Vec2(screen->w ,rand() % (screen->h-tempbox.height/2)),0);
iter = Sprites.begin();

}
}

cout << "body made" << endl;
Sprites.push_back(tempbox);

}
else
{

cout << "1st. body made" << endl;
Sprites.push_back(tempbox);
}

}


inside function:
[source langg = "cpp"]
bool inside(Sprite& sprite1, Sprite& sprite2)
{

cout << "checking if inside.." << endl;

//top of s1 < bot. of s2
if(sprite1.body->GetOriginPosition().y + sprite1.height/2 < sprite2.body->GetOriginPosition().y - sprite2.height/2)
{

return true;

}
//bot. of s1 > top. of s2
if(sprite1.body->GetOriginPosition().y - sprite1.height/2 > sprite2.body->GetOriginPosition().y + sprite2.height/2)
{
return true;
}
//right of s1 < left of s2
if(sprite1.body->GetOriginPosition().x + sprite1.width/2 < sprite2.body->GetOriginPosition().x - sprite2.width/2)
{
return true;
}
//left of s1 > rigt of s2
if(sprite1.body->GetOriginPosition().x - sprite1.width/2 > sprite2.body->GetOriginPosition().x + sprite2.width/2)
{
return true;
}

//if no collisions
return false;
}


do to the
iter = Sprites.begin();
in the for loop, it also tend to make an infinite loop if there is no room, so feel free to suggest another way to do this :P.

##### Share on other sites
0) An empty vector is not a special case. There is no benefit to making that check separately. If the vector is empty, then .begin() == .end(), and the loop simply executes zero times, which is exactly the behaviour you want.

1) You are trying to check if the tempbox is "inside" each sprite, where tempbox is default-constructed the first time around. What position will you be checking?

2) I assume "inside" actually checks if two things intersect, not if one is inside the other. You should name it accordingly.

3) It looks like you're *rejecting* the new sprite if it is *not* "inside" any given existing sprite, i.e. requiring it to be "inside" *all* of them. I strongly suspect that's the opposite of what you want.

4) When you detect a collision, you reset 'iter = Sprites.begin()', but then the end of the loop is reached, causing the 'iter++' to happen. That means that the first sprite will not be checked against the new box position.

What you want to do is separate the "check for collision against any sprite" step from the "generate a random coordinate" step. The process logically looks like this:

To spawn:  Create a box.  do:    set the box's position.  while intersects_with_anything(box).  Add the box to Sprites.To test intersects_with_anything(box):  for each sprite in Sprites:    if inside(box, sprite):      answer True.  answer False.

In C++, that becomes:

bool inside_anything(const Sprite& box) {  for (vector<Sprite>::iterator iter = Sprites.begin();       iter != Sprites.end(); ++iter) {    if (inside(box,(*iter))) { return true; }  }  return false;}void spawnsprites() {  Sprite tempbox;  do {    tempbox.body->SetOriginPosition( b2Vec2(screen->w ,rand() % (screen->h-tempbox.height/2)),0);  } while (inside_anything(tempbox)); // i.e., until not inside anything.   Sprites.push_back(tempbox);}