4
\$\begingroup\$

Let's say I got an object A and object B in a 2D game. I create a vector leading from A to B. It's name is AB.

How can I make A move along the vector AB and reach B?

One way I was thinking of doing this, is calculate the angle between AB and the x axis, and then move the object every game-loop cycle in that angle, using trigonometry.

I would calculate that angle by making a new normalized vector (1,0) (the x axis), normalize AB, and then get the angle between them by getting their dot product and using arccos on it.

But is there an easier way to make an object follow the path of a vector?

EDIT:

In this question: Make objects follow a strict path (Xna), the way someone suggested to move an object along a vector, is like so:

position += direction * speed * elapsed;

Where:

  • position = current position of the object.
  • direction = a normalized vector pointing in the direction of the destination.
  • speed = a scalar to decide how much to advance the object every cycle of the game-loop. (Is this a 'scalar'? Am I using this word correctly?)
  • elapsed = what is this?

I get everything but elapsed. What is this? Is this necessary?

Anyhow, is this method a good method? Would you recommend it?

Thanks

\$\endgroup\$
  • 1
    \$\begingroup\$ possible duplicate of Make objects follow a strict path (Xna) \$\endgroup\$ – user15805 Jan 28 '14 at 21:51
  • \$\begingroup\$ @AlexM. Thanks, I have a question regarding this, in a minute I'll edit it into my question. \$\endgroup\$ – user3150201 Jan 28 '14 at 21:56
  • \$\begingroup\$ @user3150201 elapsed is the time elapsed since the vector was created \$\endgroup\$ – Pip Jan 28 '14 at 22:03
  • 1
    \$\begingroup\$ @Pip No, elapsed is the time since the last frame, otherwise known as deltaTime. That's why the speed (presumably in units-per-second) is being multiplied by it. \$\endgroup\$ – kevintodisco Jan 28 '14 at 23:20
  • \$\begingroup\$ @ktodisco I stand corrected! I myself use that In my game... don't know why I said what I did.... \$\endgroup\$ – Pip Jan 28 '14 at 23:39
1
\$\begingroup\$

Yes, as the answer to the other question suggests, the best method of doing this is to move the object each frame along the directional vector according to the speed of the object. It's the fastest in terms of mathematical operations, and also is the least prone to numerical or floating point drift.

You can use either implicit (commonly used for curves or splines) or explicit integration:

Implicit:
    // t starts at 0
    // PA' is the current position of A
    // PA is the original position of A
    // PB is the position of B
    t += deltaTime
    PA' = PA * (1 - t) + PB * t

Explicit:
    // PA' is the current position of A
    // D is the direction vector
    // S is the speed
    PA' = PA' + (D * (S * deltaTime))

Caveats: Over longer periods of time, explicit Euler integration (as shown above) becomes rather inaccurate. Also, the direction vector must be normalized before use.

\$\endgroup\$
0
\$\begingroup\$

elapsed is time change. look at it

position += direction * speed * elapsed;

if you move at speed, say, 5m/s you don't know how to change your position, unless you know, say, 2 second elapsed. then you know change is 10 meters

\$\endgroup\$
  • \$\begingroup\$ But if we're using a game-loop, it's unnecessary, right? Because a game-loop has a consistent speed, for example runs every 30 milliseconds. So we know that the update of the position vector (or point) happens every 30 milliseconds. Am I wrong? \$\endgroup\$ – user3150201 Jan 28 '14 at 22:15
  • \$\begingroup\$ yes. then elapsed would be constant. \$\endgroup\$ – Lukáš Rutar Jan 28 '14 at 22:18
  • \$\begingroup\$ Unless you're using a very reliable Sleep(x) function (which doesn't really exist) then elapsed will not be constant. In short, never rely upon elapsed (deltaTime) being constant. \$\endgroup\$ – kevintodisco Jan 28 '14 at 23:23
  • \$\begingroup\$ there are engines where virtual step is still constant but real time is not bounded to virtual time. (step will always be virtual 30 ms but may take real 30 ms or real 50 ms etc.) so game will be precieved as slower or faster it depends on implementation. if you have somehow reliable sleep(x) function nobody will notice that step taken 32 ms instead 30. \$\endgroup\$ – Lukáš Rutar Jan 29 '14 at 11:29
  • \$\begingroup\$ @LukášRutar What engines are these? Coordinating internal systems according to something other than real time is generally considered poor practice. \$\endgroup\$ – kevintodisco Jan 31 '14 at 20:21
0
\$\begingroup\$

Another option, which is more useful if you need to know the rotation of your object as well, is this:

rotation = atan2(dy, dx);
px += speed * elapsed * cos(rotation);
py += speed * elapsed * sin(rotation);

Where elapsed is the time since your last game loop, dy and dx are the y and x coordinates of the vector from your current position to the target destination, and px and py are your current x and y coordinates.

You should also check if the distance you need to go is less than the total amount you can move so that you don't pass your target. A method to do this is:

if( dx*dx + dy*dy < speed * elapsed * speed * elapsed){
    px += dx;
    py += dy;
}
else { 
    calculate position with the first formula
}

This method saves you from having to normalize your vectors and gives you your rotation relative to the x axis in the range of -180 to +180 degrees, while using arccos will not tell you whether your angle is positive or negative.

\$\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.