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 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(); )
{
    if(currentShip.m_state == Ship::Ship_Dead)
    {
        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;

}
share|improve this question

closed as too localized by Tetrad Feb 14 '13 at 21:38

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

6  
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 –  Moaz Nov 2 '12 at 17:20
2  
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 ? –  Moaz 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 ? –  Moaz Nov 2 '12 at 20:17

2 Answers 2

up vote 3 down vote accepted

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++) 
{
    if(currentShip.m_state == Ship::Ship_Dead) 
    {
        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;
        }
    }        
}
share|improve this answer
    
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 –  Moaz 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 –  Moaz 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
1  
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.

share|improve this answer
    
do you think is that the same way designed for the original asteroid ? –  Moaz Nov 2 '12 at 16:49
4  
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 –  Moaz Nov 2 '12 at 20:52

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