[bmx] Tween/Easing by coffeedotbean [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : Tween/Easing
Author : coffeedotbean
Posted : 1+ years ago

Description : Port of Skn3's Code from MonkeyX

Example on usage here -http://www.blitzbasic.com/Community/posts.php?topic=105550


Code :
Code (blitzmax) Select
' ===========================================================================================================================
' Date: 28/12/2015
' ===========================================================================================================================
' Original authorcode Skn3 (michael contento)
' Ported from his Monkey-x code <a href="https://github.com/michaelcontento/monkey/blob/master/bananas/skn3/tweening/tween.monkey" target="_blank">https://github.com/michaelcontento/monkey/blob/master/bananas/skn3/tweening/tween.monkey</a>
' All Credit to Skn3, BlitzMax port by Supertino A.K.A coffeedotbean
'
' Usage - Simply 'Include' this .bmx file into your existing project and use the functions below
' Important - all Equations but Linear must use an EaseIn, EaseOut or EaseInOut Call
' ===========================================================================================================================

' Example
' =======
' local x:Float
' local myTween:Tween
' myTween = CreateTween(Tween.Sine.EaseInOut,0,480,5000)
' StartTween(myTween)
'
' While
'    UpdateTween(myTween)
'    x=TweenValue(myTween)
'    DrawRect x,0,32,32
' Wend

' ###########################################################################################################################
' #                                                           Required to Create & return a Tween object
' ###########################################################################################################################
Function CreateTween:Tween(equation:TweenEquationCall, startValue:Float, endValue:Float, duration:Int)
Local a:Tween = New Tween; a.Init(equation, startValue, endValue, duration) ; Return a
End Function

' ###########################################################################################################################
' #   Functions - these just call methods in the Tween Class, class methods can also be called directly for that OOP goodness
' ###########################################################################################################################

'// Return Value
Function TweenValue:Float(a:Tween) ; Return a.Value() ; End Function

'// Start
Function TweenStart:Int(a:Tween) ; a.Start ; End Function

'// Stop (Pause)
Function TweenStop:Int(a:Tween) ; a.Stop ; End Function

'// Resume from Stop
Function TweenResume:Int(a:Tween) ; a.Resume ; End Function

'// Call to update
Function TweenUpdate:Int(a:Tween) ; a.Update ; End Function

'// Set YoYo (back and forth)
Function TweenSetYoYo:Int(a:Tween, flag:Int = True) ; a.SetYoYo(flag) ; End Function

'// Infinate looping
Function TweenSetLooping:Int(a:Tween, flag:Int = True) ; a.SetLooping(flag) ; End Function

'// Force to start point
Function TweenRewind:Int(a:Tween) ; a.Rewind ; End Function

'// Force to end point
Function TweenFastForward:Int(a:Tween) ; a.FastForward ; End Function

'// Change end value, if 0 duration original duration is used
Function TweenContinueTo:Int(a:Tween, endValue:Float, duration:Int = 0) ; a.ContinueTo(endValue, duration) ; End Function

'// Return if the Tween is running
Function TweenIsActive:Int(a:Tween) ; Return a.isActive ; End Function

'// Set duration time - if changed since creation
Function TweenSetDuration:Int(a:Tween, duration:Int) ; a.SetDuration(duration) ; End Function

'// Set Equation - if changed since creation
Function TweenSetEquation:Int(a:Tween, equation:TweenEquationCall) ; a.SetEquation(equation:TweenEquationCall) ; End Function

'// Set Value - if changed since creation
Function TweenSetValue:Int(a:Tween, startValue:Float, endValue:Float) ; a.SetValue(startValue:Float, endValue:Float) ; End Function


' ###########################################################################################################################
' ###########################################################################################################################
' ###########################################################################################################################
' #                                            Tween module contents - all credit to Skn3 for orginal code, 99% original code
' ###########################################################################################################################
Type Tween
   
Global Linear:TweenEquationCall = New TweenEquationCallLinear
Global Sine:TweenEquation = New TweenEquationSine
    Global Quint:TweenEquation = New TweenEquationQuint
Global Quart:TweenEquation = New TweenEquationQuart
Global Quad:TweenEquation = New TweenEquationQuad
Global Back:TweenEquation = New TweenEquationBack
    Global Bounce:TweenEquation = New TweenEquationBounce
    Global Circ:TweenEquation = New TweenEquationCirc
    Global Cubic:TweenEquation = New TweenEquationCubic
    Global Elastic:TweenEquation = New TweenEquationElastic
    Global Expo:TweenEquation = New TweenEquationExpo
   
Field equation:TweenEquationCall

    Field startt:Float
    Field change:Float
    Field current:Float

    Field isActive:Int = False
    Field isLooping:Int = False
    Field isYoYo:Int = False

    Field duration:Int
    Field loopCount:Int
    Field timeStart:Int
    Field timeCurrent:Int
    Field timePrevious:Int
Field timePaused:Int

    ' --- constructors ---
    Method Init(equation:TweenEquationCall, startValue:Float, endValue:Float, duration:Int)
        SetEquation(equation)
        SetDuration(duration)
        SetValue(startValue,endValue)
    End Method

    ' --- private methods ---
    Method UpdateValue:Int()
        Current = equation.Call(timeCurrent, startt, change, duration)
    End Method

    ' --- value methods ---
    Method Value:Float()
        Return current
    End Method

    ' --- setup methods methods ---
    Method SetEquation:Int(equation:TweenEquationCall)
        Self.equation = equation
    End Method

    Method SetDuration:Int(duration:Int)
        Self.duration = duration
    End Method

    Method SetValue:Int(startValue:Float, endValue:Float)
        startt = startValue
        change = endValue - startValue
    End Method

    Method SetYoYo:Int(flag:Int)
        isYoYo = flag
    End Method

    Method SetLooping:Int(flag:Int)
        isLooping = flag
    End Method

    ' --- control methods ---
    Method Start:Int()
        ' --- this will re-start the tween ---
        Rewind()
        isActive = True
        loopCount = 0
    End Method

    Method Stop:Int()
        ' --- stop the tween from updating ---
If isActive
        isActive = False
timePaused = Millisecs()
EndIf
    End Method

Method Resume:Int()
' --- resume the tween from a paused state ---
If isActive = False
isActive = True

'update the start timer!
'get difference
Local difference:Int = timePaused - timeStart

'update timestamps
timeCurrent = Millisecs()
timeStart = timeCurrent - difference
timePrevious = timeCurrent
timePaused = 0

Print "difference = " + difference
Print "timeStart = " + timeStart
EndIf
End Method

    Method Rewind:Int()
        ' --- put the tween at the start of its tween ---
        timeCurrent = 0
timePaused = 0
        timeStart = Millisecs()
        UpdateValue()
    End Method

    Method FastForward:Int()
        ' --- set the tween at the end ---
        timeCurrent = duration
        UpdateValue()
        Stop()
    End Method

    Method ContinueTo:Int(endValue:Float, duration:Int = 0)
        ' --- change the end target for teh value
        startt = Current
        SetValue(startt, endValue)

        If isActive
            'isActive so need to continue operation
            If duration = 0
                'no duration specified so use previous duration!
                Self.duration = duration - timeCurrent
            Else
                'override duration
                Self.duration = duration
            Endif

            timeStart = Millisecs()
            timeCurrent = 0

            If duration <= 0
                duration = 0
                Stop()
            Endif
        Else
            If duration > 0 SetDuration(duration)
            Start()
        EndIf
    End Method

    Method YoYo:Int()
        ContinueTo(startt)
    End Method

    ' --- class methods ---
    Method Update:Int()
        If isActive
            'update the current time!
            timePrevious = timeCurrent
            Local time:Int = MilliSecs() - timeStart

            If time > duration
                'time is beyond length of tween
                If isLooping Or isYoYo
                    'increase the loop count
                    loopCount:+1

                    'look at yoyoing the values
                    If isYoYo
                        timeCurrent = duration
                        Current = startt + change

                        If isLooping Or loopCount <= 1
                            ContinueTo(startt, duration)
                        Else
                            Stop()
                        Endif
                    Else
                        'wrap around the tween to the start
                        timeCurrent = 0'
                        timeStart = Millisecs()
                    Endif
                Else
                    'set the tween to the end
                    timeCurrent = duration
                    Current = startt + change
                    Stop()
                Endif
            Else If time < 0
                'time is before the start of the tween
                timeCurrent = 0
                timeStart = Millisecs()
                UpdateValue()
            Else
                'time is within the tween
                timeCurrent = time
                UpdateValue()
            Endif
        Endif
    End Method
End Type

Type TweenEquation
    ' --- really just a grouping class for user access ---
    Field EaseIn:TweenEquationCall
    Field EaseOut:TweenEquationCall
    Field EaseInOut:TweenEquationCall

End Type

Type TweenEquationCall
    ' --- base class to provide a call function pointer work around ---
    Method Call:Float(t:Float, b:Float, c:Float, d:Float) Abstract

Function Pow:Float(a:Float, b:Float)
Return a ^ b
End Function

End Type

' ###########################################################################################################################
' #                                                                                                                    Linear
' ###########################################################################################################################
Type TweenEquationCallLinear Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        Return c*t/d + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                      Sine
' ###########################################################################################################################
Type TweenEquationSine Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallSineEaseIn
        EaseOut = New TweenEquationCallSineEaseOut
        EaseInOut = New TweenEquationCallSineEaseInOut
    End Method
End Type

Type TweenEquationCallSineEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        Return - c * Cos((t / d * (Pi / 2)) * 57.2957795) + c + b
    End Method
End Type

Type TweenEquationCallSineEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        Return c * Sin((t/d * (PI/2)) * 57.2957795) + b
    End Method
End Type

Type TweenEquationCallSineEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        Return -c/2 * (Cos((PI*t/d) * 57.2957795) - 1) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                     Quint
' ###########################################################################################################################
Type TweenEquationQuint Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallQuintEaseIn
        EaseOut = New TweenEquationCallQuintEaseOut
        EaseInOut = New TweenEquationCallQuintEaseInOut
    End Method
End Type

Type TweenEquationCallQuintEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return c * t * t * t * t * t + b
    End Method
End Type

Type TweenEquationCallQuintEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t = t / d - 1
        Return c * (t * t * t * t * t + 1) + b
    End Method
End Type

Type TweenEquationCallQuintEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
t:/d / 2
If t < 1 Return c / 2 * t * t * t * t * t + b
        t:-2
Return c / 2 * (t * t * t * t * t + 2) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                     Quart
' ###########################################################################################################################
Type TweenEquationQuart Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallQuartEaseIn
        EaseOut = New TweenEquationCallQuartEaseOut
        EaseInOut = New TweenEquationCallQuartEaseInOut
    End Method
End Type

Type TweenEquationCallQuartEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return c * t * t * t * t + b
    End Method
End Type

Type TweenEquationCallQuartEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t = t / d - 1
        Return -c * (t * t * t * t - 1) + b
    End Method
End Type

Type TweenEquationCallQuartEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d / 2
If t < 1 Return c / 2 * t * t * t * t + b
        t:-2
Return -c / 2 * (t * t * t * t - 2) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                      Quad
' ###########################################################################################################################
Type TweenEquationQuad Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallQuadEaseIn
        EaseOut = New TweenEquationCallQuadEaseOut
        EaseInOut = New TweenEquationCallQuadEaseInOut
    End Method
End Type

Type TweenEquationCallQuadEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return c * t * t + b
    End Method
End Type

Type TweenEquationCallQuadEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return -c * t * (t - 2) + b
    End Method
End Type

Type TweenEquationCallQuadEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d / 2
If t < 1 Return c / 2 * t * t + b
t:-1
Return -c / 2 * (t * (t - 2) - 1) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                   Explode
' ###########################################################################################################################
Type TweenEquationExpo Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallExpoEaseIn
        EaseOut = New TweenEquationCallExpoEaseOut
        EaseInOut = New TweenEquationCallExpoEaseInOut
    End Method
End Type

Type TweenEquationCallExpoEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        If t = 0 Return b
        Return c * Pow(2, 10 * (t / d - 1)) + b
    End Method
End Type

Type TweenEquationCallExpoEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        If t = d Return b + c
        Return c * (-Pow(2, -10 * t / d) + 1) + b
    End Method
End Type

Type TweenEquationCallExpoEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
If t =0 Return b
If t = d Return b + c
t:/d / 2
If t < 1 Return c / 2 * Pow(2, 10 * (t - 1)) + b
t:-1
Return c / 2 * (-Pow(2, -10 * t) + 2) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                     Cubic
' ###########################################################################################################################
Type TweenEquationCubic Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallCubicEaseIn
        EaseOut = New TweenEquationCallCubicEaseOut
        EaseInOut = New TweenEquationCallCubicEaseInOut
    End Method
End Type

Type TweenEquationCallCubicEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return c * t * t * t + b
    End Method
End Type

Type TweenEquationCallCubicEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t = t / d - 1
        Return c * (t * t * t + 1) + b
    End Method
End Type

Type TweenEquationCallCubicEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d / 2
If t < 1 Return c / 2 * t * t * t + b
t:-2
Return c / 2 *(t * t * t + 2) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                      Circ
' ###########################################################################################################################
Type TweenEquationCirc Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallCircEaseIn
        EaseOut = New TweenEquationCallCircEaseOut
        EaseInOut = New TweenEquationCallCircEaseInOut
    End Method
End Type

Type TweenEquationCallCircEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
        Return - c * (Sqr(1 - t * t) - 1) + b
    End Method
End Type

Type TweenEquationCallCircEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t = t / d - 1
        Return c * Sqr(1 - t * t) + b
    End Method
End Type

Type TweenEquationCallCircEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d / 2
If t < 1 Return - c / 2 * (Sqr(1 - t * t) - 1) + b
t:-2
Return c / 2 * (Sqr(1 - t * t) + 1) + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                    Bounce
' ###########################################################################################################################
Type TweenEquationBounce Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallBounceEaseIn
        EaseOut = New TweenEquationCallBounceEaseOut
        EaseInOut = New TweenEquationCallBounceEaseInOut
    End Method
End Type

Type TweenEquationCallBounceEaseIn Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t = (d-t) / d
If t < 0.3636363
Return c - (c * (7.5625 * t * t)) + b
Else If t < 0.7272727
            t:-0.5454545
Return c - (c * (7.5625 * t * t + 0.75)) + b
Else If t < 0.9090909
            t:-0.8181818
Return c - (c * (7.5625 * t * t + 0.9375)) + b
Else
            t:-0.9636363
Return c - (c * (7.5625 * t * t + 0.984375)) + b
        Endif
    End Method
End Type

Type TweenEquationCallBounceEaseOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
If t < 0.3636363
Return c *(7.5625 * t * t) + b
Else If t < 0.7272727
            t:-0.5454545
Return c * (7.5625 * t * t + 0.75) + b
Else If t < 0.9090909
            t:-0.8181818
Return c * (7.5625 * t * t + 0.9375) + b
Else
            t:-0.9636363
Return c * (7.5625 * t * t + 0.984375) + b
        Endif
    End Method
End Type

Type TweenEquationCallBounceEaseInOut Extends TweenEquationCall
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
If t < d/2
            t = (d - t * 2) / d
    If t < 0.3636363
    Return (c - (c * (7.5625 * t * t))) * 0.5 + b
    Else If t < 0.7272727
                t:-0.5454545
    Return (c - (c * (7.5625 * t * t + 0.75))) * 0.5 + b
    Else If t < 0.9090909
                t:-0.8181818
    Return (c - (c * (7.5625 * t * t + 0.9375))) * 0.5 + b
    Else
                t:-0.9636363
    Return (c - (c * (7.5625 * t * t + 0.984375))) * 0.5 + b
            Endif
        Else
            t = (t * 2 - d) / d
    If t < 0.3636363
    Return (c *(7.5625 * t * t)) * 0.5 + c * 0.5 + b
    Else If t < 0.7272727
                t:-0.5454545
    Return (c * (7.5625 * t * t + 0.75)) * 0.5 + c * 0.5 + b
    Else If t < 0.9090909
                t:-0.8181818
    Return (c * (7.5625 * t * t + 0.9375)) * 0.5 + c * 0.5 + b
    Else
                t:-0.9636363
    Return (c * (7.5625 * t * t + 0.984375)) * 0.5 + c * 0.5 + b
            Endif
        Endif
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                   Elastic
' ###########################################################################################################################
Type TweenEquationElastic Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallElasticEaseIn
        EaseOut = New TweenEquationCallElasticEaseOut
        EaseInOut = New TweenEquationCallElasticEaseInOut
    End Method
End Type

Type TweenEquationCallElasticEaseIn Extends TweenEquationCall
    Field p:Float
    Field a:Float
    Field s:Float

    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
If t = 0 Return b
t:/d
        If t = 1 Return b+c
        p = d *  0.3
a = c
        s = p / 4
        t:-1
Return -(a * Pow(2,10 * (t)) * Sin(((t * d - s) * (2 * PI) / p) * 57.2957795)) + b
    End Method
End Type

Type TweenEquationCallElasticEaseOut Extends TweenEquationCall
    Field p:Float
    Field a:Float
    Field s:Float

    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
If t = 0 Return b
t:/d
        If t = 1 Return b+c
        p = d * 0.3
a = c
        s = p / 4
Return (a * Pow(2,-10 * t) * Sin(((t * d - s) * (2 * PI) / p) * 57.2957795) + c + b)
    End Method
End Type

Type TweenEquationCallElasticEaseInOut Extends TweenEquationCall
    Field p:Float
    Field a:Float
    Field s:Float

    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
If t = 0 Return b
t:/d / 2
        If t = 2 Return b+c
        p = d * (0.3 * 1.5)
a = c
        s = p / 4
If t < 1
            t:-1
            Return -0.5 * (a * Pow(2,10 * t) * Sin(((t * d - s) * (2 * PI) / p) * 57.2957795)) + b
        Endif
        t:-1
Return a * Pow(2,-10 * t) * Sin(((t * d - s) * (2 * PI) / p) * 57.2957795) * 0.5 + c + b
    End Method
End Type

' ###########################################################################################################################
' #                                                                                                                      Back
' ###########################################################################################################################
Type TweenEquationBack Extends TweenEquation
    Method New()
        EaseIn = New TweenEquationCallBackEaseIn
        EaseOut = New TweenEquationCallBackEaseOut
        EaseInOut = New TweenEquationCallBackEaseInOut
    End Method
End Type

Type TweenEquationCallBackEaseIn Extends TweenEquationCall
    Field s:Float = 1.70158
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d
Return c * t * t * ((s + 1) * t - s) + b
    End Method
End Type

Type TweenEquationCallBackEaseOut Extends TweenEquationCall
    Field s:Float = 1.70158
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        t:/d - 1
Return c * (t * t * ((s + 1) * t + s) + 1) + b
    End Method
End Type

Type TweenEquationCallBackEaseInOut Extends TweenEquationCall
    Field s:Float = 1.70158
    Field s2:Float
    Method Call:Float(t:Float,b:Float,c:Float,d:Float)
        s2 = s
        t:/d / 2
        s2:*1.525
If t < 1
            Return c / 2 * (t * t *((s2+1) * t - s2)) + b
        Endif
t:-2
Return c / 2 * (t * t * ((s2 + 1) * t + s2) + 2) + b
    End Method
End Type


Comments : none...