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 in Questions 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:

Comments

  • Jmv38Jmv38 Mod
    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)
    
        -- Do your drawing here
        rect(a.x, a.y, a.w, a.h)
    end
    
    
    
  • edited February 2015 Posts: 2,020

    @Jmv38 Wow, that is very clever.

    ^:)^

    Thank you!

  • dave1707dave1707 Mod
    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
  • Jmv38Jmv38 Mod
    Posts: 3,297

    i agree

  • dave1707dave1707 Mod
    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?

  • SimeonSimeon Admin Mod
    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?

Sign In or Register to comment.