Log In  


Cart #easingcheatsheet-2 | 2020-11-28 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
126

load #easingcheatsheet

in the Pico-8 command line to load it straight into your Pico-8 application!

Easing functions are ways of modifying the rate of change for a linear interpolation function. You may have used these in animation programs (unity, blender, etc.) by manually editing animation curves. This editing isn't all that possible without a large engine backend, but you can easily create short math equations to imitate some of the commonly used curves. This is what I've done here, implementing a set of functions for these curves, and creating a little demo so you can see how each of them changes your interpolation!

Code

All of these functions are completely self sufficient (don't rely on anything outside the function), so you can easily pick and choose which ones you want! (476 tokens for all of them)
(also, none of the functions have any safety regulations, so passing values outside of 0-1 will result in unintended behavior. Be careful! you could also add t=mid(0,t,1) to the start of the functions to clamp the values)

Quadratic functions

function easeinquad(t)
	return t*t
end

function easeoutquad(t)
	t-=1
	return 1-t*t
end

function easeinoutquad(t)
	if(t<.5) then
		return t*t*2
	else
		t-=1
		return 1-t*t*2
	end
end

function easeoutinquad(t)
	if t<.5 then
		t-=.5
		return .5-t*t*2
	else
		t-=.5
		return .5+t*t*2
	end
end

Quartic functions

(these are very similar to quadratics, but flatter at the start and steeper towards the end)

function easeinquart(t)
	return t*t*t*t
end

function easeoutquart(t)
	t-=1
	return 1-t*t*t*t
end

function easeinoutquart(t)
	if t<.5 then
		return 8*t*t*t*t
	else
		t-=1
		return (1-8*t*t*t*t)
	end
end

function easeoutinquart(t)
	if t<.5 then
		t-=.5
		return .5-8*t*t*t*t
	else
		t-=.5
		return .5+8*t*t*t*t
	end
end

Overshooting functions

(these functions overshoot the range slightly and then return to it)

function easeinovershoot(t)
	return 2.7*t*t*t-1.7*t*t
end

function easeoutovershoot(t)
	t-=1
	return 1+2.7*t*t*t+1.7*t*t
end

function easeinoutovershoot(t)
	if(t<.5) then
		return (2.7*8*t*t*t-1.7*4*t*t)/2
	else
		t-=1
		return 1+(2.7*8*t*t*t+1.7*4*t*t)/2
	end
end

function easeoutinovershoot(t)
	if t<.5 then
		t-=.5
		return (2.7*8*t*t*t+1.7*4*t*t)/2+.5
	else
		t-=.5
		return (2.7*8*t*t*t-1.7*4*t*t)/2+.5
	end
end

Elastic functions

(these functions overshoot slightly and then oscillate near the edges of the range, like an elastic band)

function easeinelastic(t)
	if(t==0) return 0
	return 2^(10*t-10)*cos(2*t-2)
end

function easeoutelastic(t)
	if(t==1) return 1
	return 1-2^(-10*t)*cos(2*t)
end

function easeinoutelastic(t)
	if t<.5 then
		return 2^(10*2*t-10)*cos(2*2*t-2)/2
	else
		t-=.5
		return 1-2^(-10*2*t)*cos(2*2*t)/2
	end
end

function easeoutinelastic(t)
	if t<.5 then
		return .5-2^(-10*2*t)*cos(2*2*t)/2
	else
		t-=.5
		return 2^(10*2*t-10)*cos(2*2*t-2)/2+.5
	end
end

Bouncing functions

(these functions hit the edge values early, then bounce back a few times)

function easeinbounce(t)
	t=1-t
	local n1=7.5625
	local d1=2.75

	if (t<1/d1) then
		return 1-n1*t*t;
	elseif(t<2/d1) then
		t-=1.5/d1
		return 1-n1*t*t-.75;
	elseif(t<2.5/d1) then
		t-=2.25/d1
		return 1-n1*t*t-.9375;
	else
		t-=2.625/d1
		return 1-n1*t*t-.984375;
	end
end

function easeoutbounce(t)
	local n1=7.5625
	local d1=2.75

	if (t<1/d1) then
		return n1*t*t;
	elseif(t<2/d1) then
		t-=1.5/d1
		return n1*t*t+.75;
	elseif(t<2.5/d1) then
		t-=2.25/d1
		return n1*t*t+.9375;
	else
		t-=2.625/d1
		return n1*t*t+.984375;
	end
end

--(ease in+out function omitted, it doesn't really make sense for any uses IMO)

Other useful functions:

--(linear interpolation between a/b)
function lerp(a,b,t)
	return a+(b-a)*t
end

--(finds the t value that would
--return v in a lerp between a/b)
function invlerp(a,b,v)
	return (v-a)/(b-a)
end

Crediting:

If you use these in your own code, please just put a link to this BBS post in a comment near the function! I want to allow anyone reading your code to be able to find this and use it as well, for learning purposes.
All of the easing functions in this cart are based/translated from this site: https://easings.net/

Also, feel free to suggest any functions I'm missing! I omitted some of the functions that I thought were redundant/not commonly used, but correct me if I was wrong with that assumption!

126


2

This is such a nice resource, thanks for sharing! For those of us who haven't done "real" math in more than 30 years, this is a huge help.


This is beautiful! Thank you!


This is a super resource.
Thanks for creating it! 🤓👍


In your snippets below the cart, what is the difference between easeinout and easeoutin? The cart doesn't seem to have the latter.


@TBMcQueen those are at the bottom of the menu, after all of the other curves! I added them after I originally posted so they weren't mixed in with the others.


Thank you for this!


This is amazing, thank you!

Note: the 'elastic ease out' function is displayed wrong, it reads 2^(10t) but it should be 2^(-10t), as it is (correctly) in the code snippets


OMY this is really nice for experience points curve. Thank you, @ValerADHD. Gold star for mathematical excellence !

I might point out it would be interesting if you could develop the curves based upon the user setting a certain number of elements, the starting number, and the ending number.

I wrote something like this myself years ago in S2 calling it "RIDE" as it literally "rode" the array to the values I wanted and at the incremental values I also selected.

RETURN INT(((I * N + I ^ N2#) \ N) * N)

Let me give an example. Suppose I want experience points. Suppose level 1 starts at zero. I want level 99 to be at 9999 experience points with at least 1 point per level, yet I also want to have an exponential curve. How do I develop a program to generate the factor to do this ?

The solution (through trial and error is).

cls()
for i=0,98 do
  x=i+i^2.00669\1
  print("level="..(i+1).." exp="..x)
end
Level=1 Exp=0
Level=2 Exp=2
Level=3 Exp=6
Level=4 Exp=12
Level=5 Exp=20
. . .
Level=95 Exp=9201
Level=96 Exp=9397
Level=97 Exp=9596
Level=98 Exp=9797
Level=99 Exp=9999

How do I write a program that determines I need to use 2.00669 in this instance of 99 values without me manually through trial and error - finding it ?

Here is another example, you have a weapon that starts out as level 1. You go to the Smithy to upgrade it. Each upgrade costs the following. Note that the prices here always end in 0 or 5.

cls()
for i=0,24 do
  x=i*5+i^2.8943\5*5
  print("weapon level "..(i+1).." cost="..x)
end
Weapon Level 1 Cost=0
Weapon Level 2 Cost=5
Weapon Level 3 Cost=15
Weapon Level 4 Cost=35
Weapon Level 5 Cost=75
. . .
Weapon Level 21 Cost=5925
Weapon Level 22 Cost=6815
Weapon Level 23 Cost=7795
Weapon Level 24 Cost=8845
Weapon Level 25 Cost=9995

So when you start the game your weapon is at level 1. To upgrade it will cost you 5. To upgrade it again will be 15. So it costs 20 to get your weapon to level 3.

Yet without trial and error, how can this process of exponential value be automated ?


Super helpful! Thank you for this!!!


The ease out elastic function is displayed wrong, I think it should be "1-2^(-10t)cos(2t)" with the minus sign in the "2^(-10t)"


(you need to use backticks ` around code to avoid interpretation of * and other characters)


im confused how to use this?


most of functions are almost fully on if-else grounds, i think there is room for optimization... however still a great and helfull tool!


ridzpico: in short, these are functions that help you move something (player, object, camera…) in a pleasant way.

imagine a sokoban (box-pushing) game for example with an ice cube on ice floor. you push it and it should go from coordinate 20 to 80. the simplest way to do this is to add 1px to starting coordinate until you reach 80 (remember pico8 runs at 30 frames per second by default). you could also use a lerp function (lerp = linear interpolation), which is a simple function taking start and stop coordinates plus the time, and gives you back the number to use for coordinate.

this is where easing (also called tweening) comes in: lerp functions can call another function to change the way the number changes over time. this lets you for example have a little resistance at the start, then acceleration, then a little slowdown at the end. it is a great way to add realism and/or personality to animations and movements!

https://gamedev.stackexchange.com/questions/73920/what-are-easing-functions


This is great. Thank you.



[Please log in to post a comment]