10
\$\begingroup\$

I'm making a simple space game in JavaScript, but now I've hit a wall regarding vectors.

The game view is top-down on a 2d grid. When the user clicks on the grid, the space ship will fly to that spot.

So, if I have two sets of points:

{ x : 100.2, y : 100.6 }; // the ship
{ x : 20.5,  y : 55.95 }; // the clicked coordinates

If the game loop ticks at 60 iterations per second, and the desired ship velocity is 0.05 points per tick (3 points per second), how do I calculate the new set of coordinates for the ship for each tick of the game loop?

p.s. I do not want to account for inertia, or multiple vectors affecting the ship, I just want the ship to stop whatever it is doing (i.e. flying one way) and move to the clicked coordinates at a static speed.

\$\endgroup\$
10
\$\begingroup\$

In Pseudocode:

speed_per_tick = 0.05
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (goal_dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}
\$\endgroup\$
0
23
\$\begingroup\$

LERP - Linear Interpolation

I gave this answer for a similar problem some days ago, but here we go:

Linear Interpolation is a function that gives you a number between two numbers, based on the progress. You could actually, get a point between two points.


The Great Formula - How to calculate it

The general LERP Formula is given by pu = p0 + (p1 - p0) * u. Where:

  • pu: The result number
  • p0: The initial number
  • p1: The final number
  • u: The progress. It is given in percentage, between 0 and 1.

How to get percentage

You may be wondering, "How can I get this percentage!?". Don't worry. It's like this: How much time the point will take to travel from the start point to the end point? Ok, now divide it by the time that has already passed. This will give you the percentage.

Something like this: percentage = currentTime / finalTime;


Calculating Vectors

To get a resultant vector, all you need to do is apply the formula two times, one for X component and one for Y component. Like so:

point.x = start.x + (final.x - start.x) * progress;
point.y = start.y + (final.y - start.y) * progress;

Some frameworks/engines allow you to do the above in a single operation on the vector:

point = start + (final - start) * progress;
// or even
point = start.lerp(final, progress);

Calculating variate time

You may want to have your points to travel at a 0.5 points speed, yea? So let's say, a longer distance should be traveled in a longer time.

You can do it as follow:

  • Get the distance length For it, you'll need two things. Get the distance vector, then find its length value.

    distancevec = final - start;
    distance = distancevec.length();

If you don't know vectors math, you can calculate a vector length with this formula: d = sqrt(pow(v.x, 2) + pow(v.y, 2));.

  • Get the time it will take and update finaltime. This one is easy. As you want to have each tick travel a 0.5 length, we just have to do a simple division and see how many ticks we got.

    finalTime = distance / 0.5f;

Done.

NOTICE: Maybe, this may not be the intended speed for you, but this is the right one. So you have a linear movement, even on diagonal moves. If you apply x += 0.5f and y += 0.5f, the resultant speed would be different at diagonals (given by the length formula above)

\$\endgroup\$
2
  • \$\begingroup\$ What if you want % left to destination from your position ? IF you cannot use delta time but rather x:y co ordinates. \$\endgroup\$
    – Dave
    Jan 8 '15 at 5:14
  • \$\begingroup\$ If you calculated progress as stated in this answer, it should be in the 0..1 range. Just do: progressLeft = 1.0 - progress; \$\endgroup\$ Jan 19 '15 at 23:31
4
\$\begingroup\$

This can be done by computing the normal of the direction and then computing the current position via the parametric equation

newPoint = startPoint + directionVector * velocity * t

Where t is the time elapsed since the ship started traveling in the desired direction. You can also perform this per update via

newPoint = currentPoint + directionVector * velocity * timeDelta

And you just calculate this at every frame/physics/etc. update until the ship reaches its destination.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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