#### 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,725

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,725

@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,718

@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?