2
\$\begingroup\$

I'm pretty sure I'm over thinking stuff, but I can't seem to figure this out. I want to move the object from one location to another. Here's what I got. I searched this up earlier here, and I found something similar, but I wasn't able to make it work. Any help would be appreciated, thanks.

//the current position of the object is at 400, 300
Vector2 nextPosition = new Vector(100, 200);
Vector2 difference = nextPosition - position;

difference.Normalize();

position += difference * 5;
\$\endgroup\$
1
  • \$\begingroup\$ I answer the question a lot more detailed, but as for your code in the question, you need to update the difference in every Update() call. Also, your object will stutter when close to the nextPosition. \$\endgroup\$
    – dimitris93
    Apr 13, 2015 at 14:51

2 Answers 2

1
\$\begingroup\$
position += velocity * DeltaTime * speed;

This is a better way of calculating the position. this way your movement wont slow down on framerate drops, because you take into account the time elapsed between the last Update call, if it was longer than usual (low fps) you move more distance.

The code you have simply keeps increasing the position and never stops. You need to stop the movement once it reached the target position. Here I show you how to move an object to the current mouse position.

//---Initialize some variables---
Vector2 targetPosition; //mouse current position
Vector2 currentPosition = new Vector2(200, 200); //start from (200,200)
Vector2 velocity = targetPosition - currentPosition;
float speed = 0.1f;

//---Update()---
//update velocity and target position according to the mouse's current position
MouseState ms = Mouse.GetState();
targetPosition = new Vector2(ms.Position.X, ms.Position.Y);
velocity = targetPosition - currentPosition;

//if we are currently not on target position
if (currentPosition != targetPosition)
{
    //move the current position towards target position
    currentPosition += Vector2.Normalize(velocity) * speed *
        (float)gameTime.ElapsedGameTime.TotalMilliseconds;

    //if we passed the target, set the current position to target position
    Vector2 nextVel = targetPosition - currentPosition;
    if (nextVel.X * velocity.X < 0 || nextVel.Y * velocity.Y < 0)
        currentPosition = targetPosition;
}

You only need to update the the velocity velocity = targetPosition - currentPosition; whenever you change the targetPosition. Here, I need to update the velocity in every Update, because I change the targetPosition in every Update (because I set the targetPosition to the mouse current position).

\$\endgroup\$
8
  • \$\begingroup\$ You should probably mention that if you use Deltatime that your speed is now measured in seconds, instead of frames. \$\endgroup\$ Apr 13, 2015 at 3:07
  • \$\begingroup\$ Sorry, but this just isn't going to work. Your check to see if you passed the target is going to fail due to floating point precision. \$\endgroup\$
    – mklingen
    Apr 13, 2015 at 3:35
  • \$\begingroup\$ @mklingen fixed it \$\endgroup\$
    – dimitris93
    Apr 13, 2015 at 14:20
  • \$\begingroup\$ You will still have a precision error. Better to check norm(currentPosition - targetPosition) < epsilon \$\endgroup\$
    – mklingen
    Apr 13, 2015 at 15:49
  • 1
    \$\begingroup\$ I see, you inserted some kind of crazy hack to check the dot product of the velocity and the delta between the target and the current position. IMO you should always follow the hard and fast rule to never check floats for equality. \$\endgroup\$
    – mklingen
    Apr 13, 2015 at 16:02
1
\$\begingroup\$

There are a lot of ways to move something between two points. Want it to go in a straight line at a constant velocity? Then you might want to consider simple linear interpolation.

// Gives you a value that linearly interpolates between the start and end.
// t is an interpolation parameter between 0 and 1. When t = 0, the position is
// at the stat. When t = 1, the position is at the end.
Vector2 lerp(Vector2 start, Vector2 end, float t)
{
    return (1 - t) * start + t * end;
}

You can scale this over time by doing this:

// Gives the position of the target at the given time by linearly interpolating. 
Vector2 move(Vector2 start, Vector2 end, float currentTime, float maxTime)
{
    return lerp(start, end, clamp(currentTime / maxTime, 0.0, 1.0));
}

Now, when you start moving, set the current time to 0.0. Increment the time by the change in time between frames until you get to the max time. Then the move is done.

\$\endgroup\$
2
  • \$\begingroup\$ You did not really explain what t does and someone who does not know how interpolation works will find this difficult to understand. \$\endgroup\$ Apr 13, 2015 at 19:42
  • \$\begingroup\$ I added a bit more text. \$\endgroup\$
    – mklingen
    Apr 13, 2015 at 22:17

You must log in to answer this question.

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