Object slowing into target coordinate over specified number of frames

46 views Asked by At

I searched and couldn't find a solution to this (maybe I'm using the wrong terms?), and I feel a bit silly because I believe I'm overlooking something simple. Here's what I'd like to do:

I have an object in my game that needs to travel a specific x distance in a specified number of frames. But, I'd like to have it ease into the target point instead of moving the same distance/velocity every frame.

So rather than just dividing the number of frames by the distance, and applying that velocity each frame, I'd I'd like to slowly ease itself into the target coordinate in a specified number of frames.

So for example (I'm terrible at explaining, perhaps an example could help)... say I have a spaceship, and he needs to travel 32 pixels to the right. I'd like to input a value that specifies he'll travel 32 pixels in... say, 4 frames. In a linear system, he'd travel 8 pixels each frame, but I want him to ease into it, so maybe on frame 1 (and I'm using completely random values) he'd move 16 pixels, frame 2 he'd move 10, frame 3 he'd move 4, and frame 4 he'd move 2, and he'll end up traveling the 32 pixels distance in those 4 frames, slowly easing into the target point.

The first thing that came to mind was using exponent/logarithms somehow, but I'd like some suggestions. Any help would be greatly appreciated, thanks! :D

1

There are 1 answers

0
aong152 On

The general solution is the following:

You have a value (distanceTravelled) which has a range from 0.0 to 1.0. You have a function (fancyCurve) which takes in a float from 0.0 to 1.0 and remaps it from 0.0 to 1.0, except in a curve.

Every frame, you increase distanceTravelled by a linear amount. But you get the actual value by calling fancyCurve(distanceTravelled).

Here's a pseudo-code example

float linearFunction(float t) { return t; }

float speedUpFunction(float t) { return t*t; }

float slowDownFunction(float t)
{
    //do your own research. Theres plenty of curves from http://easings.net/
}

float easingCurve(float t) {
    //choose one.
    //return linearFunction(t);
    //return speedUpFunction(t);
    return slowDownFunction(t);
}

int main() {
    //setting up a spaceship with starting x coordinate
    spaceshipX = 2;
    spaceshipTargetX = 34;
    animationFrames = 8;


    //Below is the actual algorithm
    distanceTravelled = 0;
    startValue = spaceshipX;
    animRange = spaceshipTargetX - startValue; // 32
    distancePerFrame = 1.0f / animationFrames; // 0.125, since 8 frames

    while (distanceTravelled < 1.0f) {
        WaitForEndOfFrame();
        distanceTravelled += distancePerFrame;
        spaceshipX = startValue + (easingCurve(distanceTravelled) * animRange);
    }
}