Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Writing our own Tween easing (and looping?) functions

edited February 2015 Posts: 2,020

I just noticed on the wiki page for Codea's Tween API that we can write our own easing functions for Tween.

This is the template from the wiki page:

-- t is the current time -- d is the duration of the animation -- b is the initial animated value -- c is the change in the animated value by the end of the animation function myEasing(t, b, c, d) local result ... -- Code to calculate result return result end

It seems to be fairly close to this: https://github.com/kikito/tween.lua

What I wanted to ask is, would it also be possible to write a tween looping function in a similar way? Specifically I would like to write a pingpong.once function. If so, what would the template look like? (It'd be great if we could see the source for the existing pingpong function, assuming it is implemented in Lua)

Tagged:

• Posts: 3,297

i know it is not exactly what you ask for, but just in case you only need a pingpong once function, try this:

-- pingpongOnce

-- Use this function to perform your initial setup
function setup()
a = {x=100,y=100,w=50,h=50}
pingpongOnce(2, a, {x=300} )

end
function pingpongOnce(time, subject, target,...)
local back = {}
for k,v in pairs(target) do back[k] = subject[k] end
tween(time, subject, target,...)
local arg = arg or {}
tween.delay(time,function() tween(time, subject, back,unpack(arg)) end)
end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)

rect(a.x, a.y, a.w, a.h)
end

• edited February 2015 Posts: 2,020

@Jmv38 Wow, that is very clever.

^:)^

Thank you!

• Posts: 9,804

This is easier for me to understand and does the same thing.

function setup() p1={x=50,y=50} p2={x=400,y=600} p3={x=50,y=50} rec={x=50,y=50,w=50,h=50} tween1() end function tween1() tween.path(5,rec,{p1,p2,p3}) end function draw() background(40, 40, 50) fill(255) rect(rec.x,rec.y,rec.w,rec.h) end
• Posts: 3,297

i agree

• Posts: 9,804

@Jmv38 Actually, it can be shortened by eliminating p3 and just reusing p1 in the tween.path since we're going back to the starting point.

function setup() p1={x=50,y=50} p2={x=400,y=600} rec={x=50,y=50,w=50,h=50} tween1() end function tween1() tween.path(5,rec,{p1,p2,p1}) end function draw() background(40, 40, 50) fill(255) rect(rec.x,rec.y,rec.w,rec.h) end
• Posts: 2,020

@dave1707 I keep forgetting about tween.path... I'm experimenting with it now. Although maybe a tween.sequence might be closer to a pingpong.once as path adds a spline

• Posts: 2,020

This is slightly off-topic, but one thing that I think is odd about tweens is that when they're called as part of a class, and you want the callback to be a function of that class, you have to wrap it in an anonymous function. ie:

tween(1, self, {pos=newpos}, tween.easing.SineInOut, self:myFunction()) --the function is called immediately, rather than after the tween
tween(1, self, {pos=newpos}, tween.easing.SineInOut, self.myFunction(self)) --ditto
tween(1, self, {pos=newpos}, tween.easing.SineInOut, self.myFunction) --function is called at the right time, but doesn't have access to self, returns an error if self is called
tween(1, self, {pos=newpos}, tween.easing.SineInOut, function() self:myFunction() end) --success! function must be wrapped in an anonymous function to execute properly

It just seems slightly wasteful, given that advice on optimising Lua recommends not repeatedly creating closures:

http://lua-users.org/wiki/OptimisationCodingTips

Or are repeated anonymous functions (ie you have lots of tweens firing at once) not such an issue performance wise? Am I worrying unnecessarily here?

• Posts: 5,759

@yojimbo2000 it's necessary in order to bind self to the function. If you wrote your function as a static method (i.e., no access to self) then you could just pass the function name.

• Posts: 2,020

@Simeon and is it possible to add our own looping functions, like we can with easing?