• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Math, tweening between 2 numbers - Chamaeleon is cool

Foldup

Member
Hello my friends!!! I am not the best with math, I am sorry to say, and I have been struggling.

I want to use a function like LERP to move smoothly between 2 given values: currentwidth and goalwidth for smooth camera zooming.

I thought lerp(currentwidth,goalwidth,.5) was the way to go, but that's to literally give me the 50% value of those two numbers so I'm confused.

Actual code:
GML:
currentwidth = camera_get_view_width(view_camera[0])
camwidth=lerp(currentwidth,bracket[width],.5);
camheight=camwidth/ratio;
Any thoughts?

bracket[width] is an array that contains all the potential camera scaling options. I can just jump between them, but thought it would be nice to do it smoothly.
 
Last edited:

Foldup

Member
Still working on this but my get camera view width is plainly wrong and returning wrong data....hm....
 

chamaeleon

Member
1. The second parameter, 0.5 in your example, is supposed to be a value between 0 and 1, with 0 resulting lerp's first parameter, 0.5 resulting in the midway point between the two values, and 1 resulting in the second value
2. Keep track of the starting value and the end value before you start the transition, and keep them the same throughout the entire transition, and over a suitable number of steps vary a variable for the third argument to lerp() between 0 and 1

Using the current value as the first value for lerp() and a constant 0.5 will give you the behavior of Zeno's Paradox, which is typically not what you want out of lerp() (although that is similar to ease-in/ease-out behavior).
 

Foldup

Member
1. The second parameter, 0.5 in your example, is supposed to be a value between 0 and 1, with 0 resulting lerp's first parameter, 0.5 resulting in the midway point between the two values, and 1 resulting in the second value
2. Keep track of the starting value and the end value before you start the transition, and keep them the same throughout the entire transition, and over a suitable number of steps vary a variable for the third argument to lerp() between 0 and 1

Using the current value as the first value for lerp() and a constant 0.5 will give you the behavior of Zeno's Paradox, which is typically not what you want out of lerp() (although that is similar to ease-in/ease-out behavior).
Oh......OK. So you're suggesting that LERP should be used as a slider and I am meant to be popping in a variable there. Hm.....OK.....let's have a think.

Thanks for the input.
 

chamaeleon

Member
GML:
var msg = "";
var i = 0;
var value = 0;
repeat 11 {
    value = lerp(0, 100, i/10);
    msg += msg == "" ? string(value) : ", " + string(value);
    i++;
}
show_debug_message(msg);

msg = "";
i = 0;
value = 0;
repeat 11 {
    value = lerp(value, 100, 0.5);
    msg += msg == "" ? string(value) : ", " + string(value);
    i++;
}
show_debug_message(msg);
Code:
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
50, 75, 87.50, 93.75, 96.88, 98.44, 99.22, 99.61, 99.80, 99.90, 99.95
Now imagine that instead of using a repeat loop, you perform the code in the code block once per step, incrementing i every step.
 

chamaeleon

Member
Some initialization code
GML:
currentwidth = camera_get_view_width(view_camera[0]);
lerping  = false;
start_value = undefined;
end_value = undefined;
lerp_position = undefined;
number_of_steps = 2*game_get_speed(gamespeed_fps);
Some step event code
GML:
if (!lerping && should_start_lerping()) {
    lerping = true;
    start_value = currentwidth;
    end_value = bracket[width];
    lerp_position = 0;
    currentwidth = lerp(start_value, end_value, lerp_position / number_of_steps); // or currentwidth = start_value
} else if (lerping) {
    lerp_position++;
    currentwidth = lerp(start_value, end_value, lerp_position / number_of_steps);
    if (lerp_position >= number_of_steps)
        lerping = false;
}
Perhaps it works, perhaps it doesn't. :) Totally untested, and I might have overlooked something.

Edited to fix bug that compared lerping with number_steps
 
Last edited:

Foldup

Member
I'm gonna go out on a limb and say yours would be better. BUT I have something that starts to improve on what I had without hurting my brain too much.

It's not a nice exponential movement, but it takes this arbitrary "currentwidth" value and tries to compare it to the goal of "camwidth"

GML:
camwidth=bracket[width];
if currentwidth != camwidth
currentwidth = (currentwidth + camwidth) / 2
camheight=round(currentwidth/ratio);
Ohhhhhh.....I think I can actually understand what you're doing in that code. I may be getting smarter just by being around you, haha.
 
Last edited:

Foldup

Member
OH! Holy crap, I DO understand it!!!!

The only error in the code was
if (lerping >= number_of_steps)
should have been
if (lerp_position >= number_of_steps)

That IS smoother. You're too cool, Chamaeleon. For reals.
 
Top