Making an object follow a set path?

Hi folks,

So I’ve come to an issue which I can’t seem to think of a way through.

I don’t currently have any produced code, just thinking of it and procedural thoughts as text right now.

The goal: To have an object find it’s way to the exit by following a pre-defined array containing co-ordinates of each tile it must go to.

The issue: If I were to do the code below, it wouldn’t work since the Y value would always be greater than the objects current Y value.


// there would be an array that contains value such as [0][0] = start pos, [7][7] = end pos

// the first if statement would continuously be run and...
// the object would always move up and would never go right/left etc.
if (object.y < nextPoint[i][1]) {
    // move up
}
if (object.x < nextPoint[i][0]) {
    // move right
}

I guess the easiest would be to do a simple parametric linear interpolation between each two successive waypoints.
This means, you simply compute a vector equation for each line segment between any two successive waypoints, like this:

P(t) = nextPoint.xy * t + currentPoint.xy * (1 - t)

This ‘.xy’ is just an abbreviation for component-wise operations, that can also be written as two equations:
Px(t) = nextPoint.x * t + currentPoint.x * (1 - t) Py(t) = nextPoint.y * t + currentPoint.y * (1 - t)

You would then advance the parameter ‘t.’ If ‘t’ is 0.0 (at the start) your character would be at position ‘currentPosition.’ If ‘t’ advances and eventually reaches 1.0 your character would be at ‘nextPoint.’

Given that you advance ‘t’ at a constant pace using some wallclock time, the thing now is that the character’s speed will vary depending on the distance between ‘nextPoint’ and ‘currentPoint.’
One approach to remedy this is to first compute the distance (using euclidean metric) between both points:

dist = sqrt((nextPoint.x - currentPoint.x)^2 + (nextPoint.y - currentPoint.y)^2)

The ‘sqrt’ means square root (as in Math.sqrt in Java) and ‘^2’ means potentiation (multiply by itself or Math.pow).
Then you build a “direction” vector and normalize it using:

dir = (nextPoint.xy - currentPoint.xy) / dist

which again is an abbreviation for:
dirx = (nextPoint.x - currentPoint.x) / dist diry = (nextPoint.y - currentPoint.y) / dist

Then you change your linear interpolation to:

NP(t) = currentPoint.xy + dir.xy * t

Now your character follows along this direction at a constant linear speed, but you would not know when it reached the ‘nextPoint.’ To know that you can compute the ‘t’ at which NP(t) = nextPoint.
But this is also easy, since it is the computed ‘dist.’ So, if the distance between ‘currentPoint’ and ‘nextPoint’ is 2.0 then ‘dist’ will be 2.0 and ‘t’ would be 2.0 for NP(t) to become ‘nextPoint.’
Then you can switch the two points, for ‘currentPoint’ to become ‘nextPoint’ and ‘nextPoint’ to become the next point in the sequence of waypoints, and then repeat the interpolation.

Thanks, although I thought something like this would be simpler than that.

I’m afraid not. But it is already very very simple. :slight_smile:

Here is the code for all of this using JOML:


Vector2f[] points = ...; // <- your waypoints
int curr = 0;

// Initialize:
Vector2f dir = new Vector2f(points[curr+1]).sub(points[curr]);
float length = dir.length();
dir.normalize();
float t = 0.0f;
Vector2f p = new Vector2f();

// Each frame:
float dt = ...; // <- elapsed time since last frame
t += dt;
p.set(dir).mul(t).add(points[curr]);
yourObject.setPosition(p);

// Once t > length:
if (curr + 1 < points.length) {
  curr++;
  // execute code in "Initialize" phase again
} else {
  // Finished!
}

You can however probably encapsulate this in some “Interpolator” class and then have it take the waypoints during initialization/constructor and then just have some interface Vector2f advance(float dt) to it which will return the new interpolated position and probably return null when the interpolation ended or notify the client via some form of callback.