# Safe zone implementation in Asteroids [closed]

I would like to implement a safe zone for asteroids so that when the ship gets destroyed, it shouldn't be there unless it is safe from other asteroids.

I tried to check the distance between each asteroid and the ship, and if it is above threshold, it sets a flag to the ship that's a safe zone, but sometimes it work and sometimes it doesn't. What am I doing wrong?

Here's my code:

for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end(); )
{
{
float distance = itr_astroid->getCenter().distance(Vec2f(getWindowWidth()/2,getWindowHeight()/2));
if( distance>200)
{
currentShip.m_saveField = true;

break;
}
else
{
currentShip.m_saveField = false;
itr_astroid++;
}
}
else
{
itr_astroid++;
}
}


At ship's death:

if(m_state == Ship_Dead && m_saveField==true)
{
--m_lifeSpan;

}

if(m_lifeSpan<=0 && m_saveField == true)
{
m_state = Ship_Alive;
m_Vel   = Vec2f(0,0);
m_Pos.x = app::getWindowWidth()/2;
m_Pos.y = app::getWindowHeight()/2;
m_lifeSpan = 100;

}

• Sometimes life is great, and sometimes it isn't. But no one can tell why unless you show something...like code. – Sidar Nov 2 '12 at 16:31
• @sidar added code – Ahmed Saleh Nov 2 '12 at 17:20
• I think the problem lies in your boolean logic. You overwrite the "saveField" variable each time you check an asteroid. What you might want to do is set "saveField" to true before the loop, and then only set the value again on a failed state (the else clause). Your current code essentially ignores everything it's done until the last time through the loop. – Benjamin Danger Johnson Nov 2 '12 at 17:41
• @BenjaminDangerJohnson Thanks it worked!. why I did that fault ? is it normal ? or I need more practice ? – Ahmed Saleh Nov 2 '12 at 19:42
• @BenjaminDangerJohnson There is still some logic error, would you fix it please? like I want to check wheter it is safe now to place or not ? should I check the m_saveField boolean ? – Ahmed Saleh Nov 2 '12 at 20:17

This should work for checking if the center of the screen is safe for the ship only when the ship is dead. As soon as your ship is no longer in the dead state, the center will be considered safe (because of the if statement and intialization to true.) If you want the ship to be considered unsafe when it is not dead, you can change the logic around a bit (set initial value to false, check if ship is dead, if dead make safe, run asteroid check for loop.)

I see that you mentioned my comment about boolean logic helped make things a bit more consistent, but I'm not really sure what the new problem is. I would be happy to edit my answer if you can tell me more about what the goal of your check is, when it should succeed, and when it should fail.

currentShip.m_saveField = true;

for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end(); iter_astroid++)
{
{
float distance = itr_astroid->getCenter().distance(Vec2f(getWindowWidth() / 2, getWindowHeight() / 2));
if (distance < 200)
{
currentShip.m_saveField = false;
}

}
}


it seems you want your ship to not be safe when it is not in the Ship_Dead state so you should use a modified version of the above code:

currentShip.m_saveField = currentShip.m_state == Ship::Ship_Dead;

if (currentShip.m_saveField)
{
for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end(); iter_astroid++)
{
float distance = itr_astroid->getCenter().distance(Vec2f(getWindowWidth() / 2, getWindowHeight() / 2));
if (distance < 200)
{
currentShip.m_saveField = false;
break;
}
}
}

• Now If I want to reset the ship state, according to the distance and the life span, it doesn't work see my question for more code – Ahmed Saleh Nov 2 '12 at 22:14
• You question shows that this should only work when the ship is in the Ship_Dead state. If you want this to work for all states, just remove the if statement. – Benjamin Danger Johnson Nov 2 '12 at 22:24
• Simply I just want when the ship dies, it checks if it's safe to place it in the center of the screen by calculating all the distances between the asteroids and the center of the screen, if it is safe, then reset the ship again at the center of the screen – Ahmed Saleh Nov 2 '12 at 22:32
• Everything looks like it should work with your respawn code. But I noticed that you only reduce the lifespan (respawn time?) while the center is safe. If your asteroids continue to move it could take a while for the center to clear. I suggest you move "--lifespan" outside of the if statement. – Benjamin Danger Johnson Nov 2 '12 at 22:38
• just stick a break; after currentShip.m_saveField = false; line because it is pointless checking the remaining asteroids from then on. – John Nov 2 '12 at 23:26

If you want to put the ship in center of the screen, it may happen that player will wait a long time until the area is safe (potentially even forever). Especially because in a typical Asteroids game the asteroids are teleporting from one side of screen to another, making you unable to control their position. So if you want to block player's movement when "dead" (just before placing a new ship), and your asteroids indeed wrap around the screen boundaries, the only way I see to solve it is creating a repel field in the center, that pushes approaching meteors away. Strength of the repel could be based on squared distance of an asteroid from screen's center.

• do you think is that the same way designed for the original asteroid ? – Ahmed Saleh Nov 2 '12 at 16:49
• Weren't you invulnerable for a few seconds in the original? That way the player can find a safe place himself. – Roy T. Nov 2 '12 at 16:58
• @MarkusvonBroady True in an answer context, but Moaz's comment seems to ask about the original doing a safe zone, which (to my knowledge) it didn't. – Lunin Nov 2 '12 at 19:59
• @Lunin Thanks, I totally missed it was question author in first comment. – Markus von Broady Nov 2 '12 at 20:37
• @MarkusvonBroady you can take a look at it here youtube.com/watch?v=elEyz3YpKMI – Ahmed Saleh Nov 2 '12 at 20:52