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.

Im working on a Galaxian/Space Invaders Inspired game. Im working on the enemy movement and am running into an issue where the enemies get out of sync when changing direction.

My setup is that I have a global variable enemyHorizontalDirection. Its initially set to left and any time an enemy hits the left or right side of the screen its set to whatever direction the enemies should go in. While this works Im running into an issue where the enemy that triggers the global variable enemyHorizontalDirection gets out of place. Below is a video of the behavior. http://www.youtube.com/watch?v=3kRlT9_Dt1Q&feature=youtube_gdata_player

The enemies are created from left to right from a 2d array. Each enemy is added to a List at creation. I am looping through the list end to beginning at the moment. The problem occurs on the left side. When I loop through from beginning to end the problem occurs on the right side.

Here is the enemy Update Method:

if(groupedMovement) 
{
    // When hitting right side of the screen set direction to left
    if(this.x > (Futile.screen.halfWidth - GMain.instance.gameScreenOffset) - (this.width / 2))
    {
        GMain.instance.enemyHorizontalDirection = "left";
    }

    // When hitting left side of the screen set direction to right
    else if(this.x < (-Futile.screen.halfWidth + GMain.instance.gameScreenOffset) + (this.width / 2))
    {
        GMain.instance.enemyHorizontalDirection = "right";
    }

    if(GMain.instance.enemyHorizontalDirection == "left")
    {
        this.x -= 4f;
    }

    if(GMain.instance.enemyHorizontalDirection == "right")
    {
        this.x += 4f;
    }
}

Here is where I loop through the enemies and call their Update();

for(int p = _player.Count-1; p >= 0; p--)
{
    Player player = _player[p];
    player.UpdateLocalVertices();

    Rect playerRect = player.GetTextureRectRelativeToContainer();

    if(_player.Count == 0) break;

    // Handle player/enemy collisions
    for(int e = _enemies.Count-1; e >= 0; e--)
    {
        GSpriteEnemyGameObject enemy = _enemies[e];
        enemy.UpdateLocalVertices();

        if(enemy.active)
        {
            Rect enemyRect = enemy.GetTextureRectRelativeToContainer();

            if (enemyRect.CheckIntersect(playerRect))
            {
                CreateEnemyDeathEffect(enemy, true);    

                enemy.RemoveFromContainer();
                _enemies.Remove(enemy);
                PlayerHit();
            }   
        }

        if(enemy.y < -Futile.screen.halfHeight)
        {
            enemy.RemoveFromContainer();
            _enemies.Remove(enemy);
        }

        if (_debug) DebugLineDraw.drawHitBox(enemy, Color.red);

        enemy.Update();
    }
}

Im hoping someone can point me in the right direction. Im not sure of the exact cause of this or how to approach a fix for it.

Any help much appreciated!

share|improve this question

closed as too localized by Byte56, Sean Middleditch, bummzack, Trevor Powell, Josh Petrie Mar 22 '13 at 15:16

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.

1  
Related: gamedev.stackexchange.com/questions/31916/… –  Byte56 Mar 5 '13 at 4:16
    
I think your question is too localized for the site, so I'm voting to close it. I suggest you put some debug print statements in and check to make sure you're not triggering a collision more than once. –  Byte56 Mar 5 '13 at 4:20
    
I apologize, I did see that post, but didn't quite understand it by how it was worded. Kevin explained it and I have it working now! –  ismyhc Mar 5 '13 at 14:30

2 Answers 2

up vote 0 down vote accepted

You are looping through the enemies effectively from right to left. Every time the leftmost enemy hits the left side, it changes the movement direction, then moves according to the changed direction whereas the previous ones did not.

To fix this, defer the change until the end of the frame. There are many ways to do this; one is to have a second variable which stores the movement direction for the next frame, which you copy to the current direction variable at the beginning or end of each frame.

Another way would be to have a queue of deferred events which are dispatched after the enemies are looped through; this might be useful if you have many pieces of state that need treatment like this.

share|improve this answer
    
Awesome. I've banging my head against the wall with this problem all day. Now instead of checking for a change in direction and moving an enemy at the same time, I separated these so that I check for direction change, and then move the enemies. This insures they always move in the same direction per frame. By doing this they are keeping their formation. Thanks! –  ismyhc Mar 5 '13 at 14:27

The correct solution is to code exactly what you mean. You want the enemies to move as a single collective - so they should not have individual positions at all! (Or at least not update their own positions independently.)

By coding exactly what you mean, you completely eliminate the potential for this kind of bug. In fact, a good coding philosophy is that you are describing your intentions to the machine - and to other people - so it pays to be precise.

Personally I would make your enemy's positions parametric. That is to say - determined by an algorithm that takes some number of parameters (for example: the current time, and the enemy's position in a row) and outputs a position.

share|improve this answer

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