Tweening engine

Advanced game related topics
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Tweening engine

Post by Papala »

Hi ! Here is a module (EZEase) for a reaaaaly easy use of tweening based on this list of easeing.
Have fun !!

Code: Select all

DeclareModule EZEase
  ;{ Ease list
  #EZEase_easeLinear = "easeLinear"
  #EZEase_easeInQuad = "easeInQuad"
  #EZEase_easeOutQuad = "easeOutQuad"
  #EZEase_easeInOutQuad = "easeInOutQuad"
  #EZEase_easeInCubic = "easeInCubic"
  #EZEase_easeOutCubic = "easeOutCubic"
  #EZEase_easeInOutCubic = "easeInOutCubic"
  #EZEase_easeInQuart = "easeInQuart"
  #EZEase_easeOutQuart = "easeOutQuart"
  #EZEase_easeInOutQuart = "easeInOutQuart"
  #EZEase_easeInQuint = "easeInQuint"
  #EZEase_easeOutQuint = "easeOutQuint"
  #EZEase_easeInOutQuint = "easeInOutQuint"
  #EZEase_easeInSine = "easeInSine"
  #EZEase_easeOutSine = "easeOutSine"
  #EZEase_easeInOutSine = "easeInOutSine"
  #EZEase_easeInExpo = "easeInExpo"
  #EZEase_easeOutExpo = "easeOutExpo"
  #EZEase_easeInOutExpo = "easeInOutExpo"
  #EZEase_easeInCirc = "easeInCirc"
  #EZEase_easeOutCirc = "easeOutCirc"
  #EZEase_easeInOutCirc = "easeInOutCirc"
  #EZEase_easeInElastic = "easeInElastic"
  #EZEase_easeOutElastic = "easeOutElastic"
  #EZEase_easeInOutElastic = "easeInOutElastic"
  #EZEase_easeInBack = "easeInBack"
  #EZEase_easeOutBack = "easeOutBack"
  #EZEase_easeInOutBack = "easeInOutBack"
  #EZEase_easeInBounce = "easeInBounce"
  #EZEase_easeOutBounce = "easeOutBounce"
  #EZEase_easeInOutBounce = "easeInOutBounce"
  Enumeration #PB_EventType_FirstCustomValue
    #EZEase_EndEase
  EndEnumeration ;}
  Declare CreateEase(EaseType.s,StartValue.f,ChangeInValue.f,Duration.f)
  Declare FreeEase(*Ease)
  Declare InitEase(*Ease)
  Declare.f EaseResult(*Ease)
  Declare EditeEase(*Ease,StartValue.f,ChangeInValue.f,Duration.f)
EndDeclareModule

Module EZEase
  ;{ Declaration
  Structure Ease
    Type.s
    t.f
    b.f
    c.f
    d.f
  EndStructure
  Global NewList Ease.Ease()
  
  Prototype.f EaseName(t.f,b.f,c.f,d.f)
  
  Declare.f EaseLinear(t.f,b.f,c.f,d.f)
  Declare.f easeInQuad(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuad(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuad(t.f,b.f,c.f,d.f)
  Declare.f easeInCubic(t.f,b.f,c.f,d.f)
  Declare.f easeOutCubic(t.f,b.f,c.f,d.f)
  Declare.f easeInOutCubic(t.f,b.f,c.f,d.f)
  Declare.f easeInQuart(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuart(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuart(t.f,b.f,c.f,d.f)
  Declare.f easeInQuint(t.f,b.f,c.f,d.f)
  Declare.f easeOutQuint(t.f,b.f,c.f,d.f)
  Declare.f easeInOutQuint(t.f,b.f,c.f,d.f)
  Declare.f easeInSine(t.f,b.f,c.f,d.f)
  Declare.f easeOutSine(t.f,b.f,c.f,d.f)
  Declare.f easeInOutSine(t.f,b.f,c.f,d.f)
  Declare.f easeInExpo(t.f,b.f,c.f,d.f)
  Declare.f easeOutExpo(t.f,b.f,c.f,d.f)
  Declare.f easeInOutExpo(t.f,b.f,c.f,d.f)
  Declare.f easeInCirc(t.f,b.f,c.f,d.f)
  Declare.f easeOutCirc(t.f,b.f,c.f,d.f)
  Declare.f easeInOutCirc(t.f,b.f,c.f,d.f)
  Declare.f easeInElastic(t.f,b.f,c.f,d.f)
  Declare.f easeOutElastic(t.f,b.f,c.f,d.f)
  Declare.f easeInOutElastic(t.f,b.f,c.f,d.f)
  Declare.f easeInBack(t.f,b.f,c.f,d.f)
  Declare.f easeOutBack(t.f,b.f,c.f,d.f)
  Declare.f easeInOutBack(t.f,b.f,c.f,d.f)
  Declare.f easeInBounce(t.f,b.f,c.f,d.f)
  Declare.f easeOutBounce(t.f,b.f,c.f,d.f)
  Declare.f easeInOutBounce(t.f,b.f,c.f,d.f)
  ;}
  ; Public procedure
  Procedure CreateEase(EaseType.s,StartValue.f,ChangeInValue.f,Duration.f)
    AddElement(Ease())
    Ease()\Type  = EaseType
    Ease()\b = StartValue
    Ease()\c = ChangeInValue
    Ease()\d = Duration
    Ease()\t = ElapsedMilliseconds()
    ProcedureReturn @Ease()
  EndProcedure
 
  Procedure FreeEase(*Ease)
    ChangeCurrentElement(Ease(),*Ease)
    DeleteElement(Ease())
  EndProcedure
 
  Procedure InitEase(*Ease.Ease)
    *Ease\t = ElapsedMilliseconds()
  EndProcedure
 
  Procedure.f EaseResult(*Ease.Ease)
    Protected t.f = ElapsedMilliseconds() - *Ease\t, CallEase.EaseName = GetRuntimeInteger("EZEase::"+*Ease\Type + "()")
    If t > *Ease\d
      PostEvent(#EZEase_EndEase,0,0,0,*Ease)
      ProcedureReturn *Ease\c
    EndIf
    ProcedureReturn CallEase(t,*Ease\b,*Ease\c,*Ease\d)
  EndProcedure

  Procedure EditeEase(*Ease.Ease,StartValue.f,ChangeInValue.f,Duration.f)
    *Ease\b = StartValue
    *Ease\c = ChangeInValue
    *Ease\d = Duration
    *Ease\t = ElapsedMilliseconds()
  EndProcedure
  ; Private procedure
 
  Runtime Procedure.f easeLinear(t.f,b.f,c.f,d.f)
    ProcedureReturn c*t/d + b
  EndProcedure

  Runtime Procedure.f easeInQuad(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn c*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuad(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn -c *t*(t-2) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuad(t.f,b.f,c.f,d.f)
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2*t*t+b
    EndIf
    t - 1
    ProcedureReturn -c/2 * (t*(t-2)-1) +b
  EndProcedure

  Runtime Procedure.f easeInCubic(t.f,b.f,c.f,d.f)
    t / d
    ProcedureReturn c*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutCubic(t.f,b.f,c.f,d.f)
    t = t / d - 1
    ProcedureReturn c*(t*t*t+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutCubic(t.f,b.f,c.f,d.f)
    t= t/(d/2)
    If t < 1
      ProcedureReturn c/2*t*t*t + b
    EndIf
    t - 2
    ProcedureReturn c/2*(t*t*t + 2) + b
  EndProcedure

  Runtime Procedure.f easeInQuart(t.f,b.f,c.f,d.f)
    t / d
    ProcedureReturn c*t*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuart(t.f,b.f,c.f,d.f)
    t = t / d - 1
    ProcedureReturn -c * (t*t*t*t - 1) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuart(t.f,b.f,c.f,d.f)
    t = t/(d/2)
    If t < 1
      ProcedureReturn c / 2 * t*t*t*t + b
    EndIf
    t - 2
    ProcedureReturn -c/2 * (t*t*t*t - 2) + b
  EndProcedure

  Runtime Procedure.f easeInQuint(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn c*t*t*t*t*t + b
  EndProcedure

  Runtime Procedure.f easeOutQuint(t.f,b.f,c.f,d.f)
    t = t/d - 1
    ProcedureReturn c*(t*t*t*t*t+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutQuint(t.f,b.f,c.f,d.f)
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2*t*t*t*t*t + b
    EndIf
    t - 2
    ProcedureReturn c/2*(t*t*t*t*t + 2) + b
  EndProcedure

  Runtime Procedure.f easeInSine(t.f,b.f,c.f,d.f)
    ProcedureReturn -c * Cos(t/d * (#PI/2)) + c + b
  EndProcedure

  Runtime Procedure.f easeOutSine(t.f,b.f,c.f,d.f)
    ProcedureReturn c * Sin(t/d * (#PI/2)) + b
  EndProcedure

  Runtime Procedure.f easeInOutSine(t.f,b.f,c.f,d.f)
    ProcedureReturn -c/2 * Cos((#PI*t/d)-1) + b
  EndProcedure

  Runtime Procedure.f easeInExpo(t.f,b.f,c.f,d.f)
    If t = 0
      ProcedureReturn b
    EndIf
    ProcedureReturn c * Pow(2,10 * (t/d-1)) +b
  EndProcedure

  Runtime Procedure.f easeOutExpo(t.f,b.f,c.f,d.f)
    If t = d
      ProcedureReturn b+c
    EndIf
    ProcedureReturn c * (-Pow(2,-10*t/d)+1) + b
  EndProcedure

  Runtime Procedure.f easeInOutExpo(t.f,b.f,c.f,d.f)
    If t = 0 : ProcedureReturn b : EndIf
    If t = d : ProcedureReturn b+c : EndIf
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2 * Pow(2,10*(t-1))+b
    EndIf
    t-1
    ProcedureReturn c/2*(-Pow(2,-10 * t)+2)+b
  EndProcedure

  Runtime Procedure.f easeInCirc(t.f,b.f,c.f,d.f)
    t/d
    ProcedureReturn -c * Sqr(1- (t*t-1)) + b
  EndProcedure

  Runtime Procedure.f easeOutCirc(t.f,b.f,c.f,d.f)
    t = t/d-1
    ProcedureReturn c * Sqr(1-t*t) + b
  EndProcedure

  Runtime Procedure.f easeInOutCirc(t.f,b.f,c.f,d.f)
    t = t/(d/2)
    If t < 1
      ProcedureReturn -c/2 * (Sqr(1 - t*t)-1) + b
    EndIf
    t-2
    ProcedureReturn c/2 * (Sqr(1 - t*t)+1) + b
  EndProcedure

  Runtime Procedure.f easeInElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d * 0.3, a.f = c
    If t = 0 : ProcedureReturn b : EndIf
    t/d
    If t = 1 : ProcedureReturn b+c : EndIf
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    t-1
    ProcedureReturn -(a*Pow(2,10*t) * Sin( (t*d-s)*(2*#PI)/p)) + b
  EndProcedure

  Runtime Procedure.f easeOutElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d*0.3, a.f = c
    If t = 0 : ProcedureReturn b : EndIf
    t/d
    If t = 1 : ProcedureReturn b+c : EndIf
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    ProcedureReturn a*Pow(2,-10*t)* Sin((t*d-s)*(2*#PI)/p) + c + b
  EndProcedure

  Runtime Procedure.f easeInOutElastic(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158, p.f = d*(0.3*1.5), a.f = c
    If a < Abs(c)
      s = p/4
    Else
      s = p/(2*#PI) * ASin(c/a)
    EndIf
    t-1
    If t < 1
      ProcedureReturn -0.5*(a*Pow(2,10*t)) * Sin((t*d-s)*(2*#PI)/p) + b
    EndIf
    ProcedureReturn a*Pow(2,-10*t) * Sin((t*d-s)*(2*#PI)/p )* 0.5 + c+b
  EndProcedure

  Runtime Procedure.f easeInBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158
    t/d
    ProcedureReturn c*t*t*((s+1)*t -s ) + b
  EndProcedure

  Runtime Procedure.f easeOutBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.70158
    t = t/d-1
    ProcedureReturn c*(t*t*((s+1)*t+s)+1)+b
  EndProcedure

  Runtime Procedure.f easeInOutBack(t.f,b.f,c.f,d.f)
    Protected s.f = 1.525
    t = t/(d/2)
    If t < 1
      ProcedureReturn c/2*(t*t*((s+1)*t-s))+b
    EndIf
    t-2
    ProcedureReturn c/2*(t*t*((s+1)*t+s)+2)+b
  EndProcedure

  Runtime Procedure.f easeInBounce(t.f,b.f,c.f,d.f)
    ProcedureReturn c- easeOutBounce(d-t,0,c,d)+b
  EndProcedure

  Runtime Procedure.f easeOutBounce(t.f,b.f,c.f,d.f)
    t/d
    If t < 1/2.75
      ProcedureReturn c*(7.5625*t*t)+b
    ElseIf t < 2/2.75
      t = t - 1.5/2.75
      ProcedureReturn c*(7.5626*t*t + 0.75)+b
    ElseIf t < 2.5/2.75
      t = t-2.25/2.75
      ProcedureReturn c*(7.5625*t*t+0.9375)+b
    Else
      t = t- 2.625/2.75
      ProcedureReturn c*(7.5625*t*t+0.984375) + b
    EndIf
  EndProcedure

  Runtime Procedure.f easeInOutBounce(t.f,b.f,c.f,d.f)
    If t < d/2
      ProcedureReturn easeInBounce(t*2,0,c,d)*0.5+b
    EndIf
    ProcedureReturn easeOutBounce(t*2-d,0,c,d) * 0.5+c*0.5+b
  EndProcedure


EndModule


CompilerIf #PB_Compiler_IsMainFile
  Procedure resetEase()
    EZEase::InitEase(EventData())
  EndProcedure
 
  OpenWindow(0,0,0,500,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  InitSprite()
  OpenWindowedScreen(WindowID(0),0,0,500,500)
  SetFrameRate(60)
  BindEvent(EZEase::#EZEase_EndEase,@resetEase())
  spr = CreateSprite(#PB_Any,20,20)
  StartDrawing(SpriteOutput(spr))
  Box(0,0,20,20,$1122FF)
  StopDrawing()
  Elastic = EZEase::CreateEase(EZEase::#EZEase_easeOutElastic,0,400,2000)
  Bounce = EZEase::CreateEase(EZEase::#EZEase_easeOutBounce,0,400,1000)
  Circ = EZEase::CreateEase(EZEase::#EZEase_easeOutCirc,0,400,1500)
  Back = EZEase::CreateEase(EZEase::#EZEase_easeOutBack,0,400,1800)
  Expo = EZEase::CreateEase(EZEase::#EZEase_easeInExpo,0,400,3000)
  time = ElapsedMilliseconds()
  Repeat
    ClearScreen($000000)
    DisplaySprite(spr,EZEase::EaseResult(Elastic),10)
    DisplaySprite(spr,EZEase::EaseResult(Bounce),40)
    DisplaySprite(spr,EZEase::EaseResult(Circ),70)
    DisplaySprite(spr,EZEase::EaseResult(Back),100)
    DisplaySprite(spr,EZEase::EaseResult(Expo),130)
    FlipBuffers()
  Until WindowEvent() = #PB_Event_CloseWindow
CompilerEndIf
Last edited by Papala on Thu Feb 21, 2019 10:18 am, edited 2 times in total.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Tweening engine

Post by #NULL »

Very nice :) Thank you.
I put the word easing here so I'll find this thread next time I need it.
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Re: Tweening engine

Post by Papala »

Thank #NULL ^^
Just a little update for some little bug fix and remove the huge Select I used.
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Tweening engine

Post by dige »

Cool! :D Thx for sharing!
"Daddy, I'll run faster, then it is not so far..."
Fred
Administrator
Administrator
Posts: 16617
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Tweening engine

Post by Fred »

Very cool module !
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Tweening engine

Post by skywalk »

Wow, so eezy! 8)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Re: Tweening engine

Post by Papala »

Edit : little fix with the InOut, i'd forget some ()
Post Reply