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 have an enemy that I would like to move as follows:

  1. Start at (0, 200, 0)
  2. Move to (200, 0, 0)
  3. Move to (0, -200, 0)
  4. Move to (-200, 0, 0)
  5. Move to start point, repeat as long as it remains active.

This is what I've done to achieve that:

if (position.X < 200 && position.Y > 0)
{
   Velocity = new Vector3(1, -1, 0) * speed;
}
else if (position.X >= 200 && position.Y <= 0 && position.Y > -200)
{
   Velocity = new Vector3(-1, -1, 0) * speed;
}
else if (position.X <= 0 && position.Y <= -200)
{
   Velocity = new Vector3(-1, 1, 0) * speed;
}
else
{
   Velocity = new Vector3(1, 1, 0) * speed;
}

It moves to the second point, but then gets stuck and appears to vibrate in place. How should I be doing this?

share|improve this question
add comment

1 Answer

up vote 9 down vote accepted

I think you should not try to hardcode this behavior as a series of if-elses like you're doing, because this will make it very difficult to extend or change if you need different values, or to add more positions in the path.

Instead look into adding the capability of following any path to your entity. Here's an example (I'll give the example in 2D but it should be the same for 3D), but there are certainly many ways to do this.

Suppose you're starting with:

class Entity
{
    public Vector2 position;
    public float speed;
}

First add this helper method to the class, which moves the entity towards a destination and returns true when the destination has been reached:

private bool MoveTowardsPoint(Vector2 goal, float elapsed)
{
    // If we're already at the goal return immediatly
    if(position == goal) return true;

    // Find direction from current position to goal
    Vector2 direction = Vector2.Normalize(goal - position);

    // Move in that direction
    position += direction * speed * elapsed;

    // If we moved PAST the goal, move it back to the goal
    if (Math.Abs(Vector2.Dot(direction, Vector2.Normalize(goal - position)) + 1) < 0.1f)
        position = goal;

    // Return whether we've reached the goal or not
    return position == goal;
}

Then add a list of positions to your entity which will hold the path for him to follow:

class Entity
{
    List<Vector2> path = new List<Vector2>();
}

And an update method that always moves the entity towards the next position in the path:

public void Update(float elapsed)
{
    if(path.Count > 0 && MoveTowardsPoint(path[0], elapsed))
        path.RemoveAt(0);
}

Finally, to make the entity follow the points you specified and make it repeat, add something like the code below to the Update method:

if(path.Count == 0)
{
    path.Add(new Vector2(0, 200));
    path.Add(new Vector2(200, 0);
    path.Add(new Vector2(0, -200));
    path.Add(new Vector2(-200, 0));
}
share|improve this answer
    
"I'll give the example in 2D but it should be the same for 2D" Really :) ? +1 –  Jaakko Lipsanen Oct 7 '12 at 11:41
    
@JaakkoLipsanen Woops :) –  David Gouveia Oct 7 '12 at 11:43
    
Very nice answer! +1. –  Austin Brunkhorst Oct 7 '12 at 21:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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