3
\$\begingroup\$

I am making a defence game. Naturally, this means that there needs to be objects following a path on the screen. I want to make it a strict path from one point to another to another. I could use an array of vertices, but i need some help. Can someone please show me some code that could help me with this? Thanks.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ do you want to know how to make a pathfinding, or how to make objects pass through a set of points? the second is just going interpolating, easy peasy. \$\endgroup\$ May 1, 2012 at 3:10

1 Answer 1

6
\$\begingroup\$

Okay, I gave it a quick test run and it seems to be working on my end. Here's my solution. Imagine your entity has the following members, and you'd like to make the entity follow whatever path is currently set to the path member variable:

class Entity
{
    Vector2 position;
    float speed;
    List<Vector2> path;
    void Update(float elapsed);
}

I started by adding an helper method inside the class that moves the entity towards some goal, and returns true if that goal was 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;
}

Using this helper method, following the path is as simple as doing:

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

Notes

I think the only line that isn't really clear is the following:

Math.Abs(Vector2.Dot(direction, Vector2.Normalize(goal - position)) + 1) < 0.1f

What I'm doing here is checking if the direction before the move, and the direction after the move are opposite. I do this by checking if the dot product between both directions is close to -1 using an epsilon comparison. Another solution that seems to work is replacing the same check by:

Vector2.Distance(direction, Vector2.Normalize(position - goal)) < 0.1f

When I tried it the result was the same. As for the update loop:

if(path.Count > 0 && MoveTowardsPoint(path[0], elapsed))
       path.RemoveAt(0);

It's relying on the && operator not bothering to run the second portion of the operation unless the first one is true. So if there's no path, nothing else happens. If there's a path, then MoveTowardsPoint is called, and its return value is what decides whether we should remove the point from the path list or not.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .