IceDragon200

[RUBY]Tween

Mar 8th, 2012
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 14.78 KB | None | 0 0
  1. #==============================================================================#
  2. # ♥ Tween
  3. #==============================================================================#
  4. # // • Created By    : CaptainJet
  5. # // • Modified By   : IceDragon
  6. # // • Data Created  : 12/15/2011
  7. # // • Data Modified : 01/03/2012
  8. # // • Version       : 1.0
  9. #==============================================================================#
  10. # // Special Credits To:
  11. # Robert Penner (For whatever reason Jet mentioned him)
  12. # UziMonkey (For whatever reason Jet mentioned him)
  13. # CaptainJet (For teh script)
  14. #
  15. #==============================================================================#
  16. # ● Change Log
  17. #     ♣ 12/15/2011 V1.0
  18. #     ♣ 01/03/2012 V1.0
  19. #         Fixed
  20. #           Small bug with Tween value_at_time
  21. #
  22. #==============================================================================#
  23. class Tween
  24.   @@_add_time = (1.0 / Graphics.frame_rate)
  25.   attr_reader :values
  26.   attr_reader :start_values
  27.   attr_reader :end_values
  28.   attr_reader :time
  29.   attr_reader :maxtime
  30.   def self.frames_to_tt( frames )
  31.     frames * @@_add_time
  32.   end
  33.   def self.f2tt( *args, &block )
  34.     frames_to_tt(*args, &block)
  35.   end  
  36.   def self.tt_to_frames( tt )
  37.     (tt * Graphics.frame_rate).to_i
  38.   end  
  39.   def self.tt2f( *args, &block )
  40.     tt_to_frames(*args,&block)
  41.   end  
  42.   def self._add_time
  43.     @@_add_time
  44.   end  
  45.   def initialize( start_values=[], end_values=[], easer=:linear, maxtime=1.0, extra_params=[] )
  46.     set_and_reset( start_values, end_values, easer, maxtime, extra_params )
  47.   end
  48.   def value( index=0 )
  49.     return @values[index]
  50.   end  
  51.   def start_value( index=0 )
  52.     return @start_values[index]
  53.   end  
  54.   def end_value( index=0 )
  55.     return @end_values[index]
  56.   end  
  57.   def set( start_values=[], end_values=[], easer=:linear, maxtime=1.0, extra_params=[] )
  58.     start_values = [start_values] unless start_values.is_a?(Enumerable)
  59.     end_values   = [end_values]   unless end_values.is_a?(Enumerable)
  60.     @start_values, @end_values = start_values, end_values
  61.     @easer, @maxtime = easer, maxtime
  62.     @extra_params = extra_params
  63.     scale_values()
  64.     @values = []
  65.     update_value( @time )
  66.   end  
  67.   def set_and_reset( *args )
  68.     reset_time()
  69.     set( *args )
  70.   end  
  71.   def scale_values( n=1.0 )
  72.     @start_values = @start_values.collect { |v| v * n }
  73.     @end_values   = @end_values.collect { |v| v * n }
  74.   end  
  75.   def change_easer( new_easer ) ; @easer = new_easer ; end
  76.   def reset_time()
  77.     @time = 0.0
  78.   end
  79.   def reset!()
  80.     reset_time()
  81.     update_value_now()
  82.   end  
  83.   def easer() ; return Tween::EASER_SYMBOLS[@easer] ; end # // YAY now u can dump it >_>
  84.   def done?() ; return @time == @maxtime ; end # // Time gets capped anyway
  85.   def pred_time
  86.     @time = (@time-@@_add_time).max(0)
  87.   end  
  88.   def succ_time
  89.     @time = (@time+@@_add_time).min(@maxtime)
  90.   end  
  91.   def time_rate()
  92.     time_to_rate(@time)
  93.   end  
  94.   def time_to_rate(t=@time)
  95.     t / @maxtime
  96.   end  
  97.   def update()
  98.     succ_time() unless done? # // Save a little cpu..
  99.     update_value_now()
  100.   end  
  101.   def update_value_now()
  102.     update_value( @time )
  103.   end  
  104.   def value_at_time( time, sv=@start_values[0], ev=@end_values[0], mt=@maxtime, exp=@extra_params )
  105.     easer.ease( time, sv, ev, mt, *exp )
  106.   end  
  107.   def update_value( time )
  108.     for i in 0...@start_values.size
  109.       @values[i] = value_at_time( time, @start_values[i], @end_values[i] )
  110.     end  
  111.   end
  112. end
  113. class Tween::Multi
  114.   attr_reader :tweeners
  115.   def initialize( *tweensets )
  116.     set( *tweensets )
  117.   end
  118.   def set( *tweensets )
  119.     clear
  120.     tweensets.each do |tset|
  121.       add_tween( *tset )
  122.     end
  123.   end
  124.   def done?
  125.     return @tweeners.all? { |t| t.done? }
  126.   end  
  127.   def clear()
  128.     @tweeners = []
  129.   end  
  130.   def tweener(index)
  131.     @tweeners[index]
  132.   end  
  133.   def tweener_value(index, vindex)
  134.     @tweeners[index].value(vindex)
  135.   end
  136.   def tweener_values(index)
  137.     @tweeners[index].values
  138.   end
  139.   def add_tween( *tset )
  140.     @tweeners << Tween.new( *tset )
  141.   end  
  142.   def reset()
  143.     @tweeners.each do |t| t.reset_time ; end
  144.   end  
  145.   def value(index)
  146.     @tweeners[index].value
  147.   end  
  148.   def values
  149.     @tweeners.collect do |t| t.value ; end
  150.   end
  151.   def all_values()
  152.     @tweeners.collect { |t| t.values ; }.flatten
  153.   end  
  154.   def update
  155.     @tweeners.each do |t| t.update ; end
  156.   end  
  157. end  
  158. # // 01/26/2012
  159. # // 01/26/2012
  160. class Tween::Osc
  161.   attr_reader :index
  162.   attr_reader :tindex
  163.   attr_reader :cycles
  164.   def initialize( *args, &block )
  165.     normal_cycle()
  166.     set( *args, &block )
  167.     set_cycles( -1 )
  168.     reset()
  169.   end
  170.   def reset
  171.     @tindex = 0
  172.     @index = 0
  173.     @tweeners.each { |t| t.reset! }
  174.   end  
  175.   def set_cycles( n )
  176.     @cycles = n
  177.   end  
  178.   def invert_cycle
  179.     @inverted = true
  180.   end  
  181.   def normal_cycle
  182.     @inverted = false
  183.   end  
  184.   def set( svs, evs, easers=[:linear, :linear], maxtimes=[1.0,1.0] )
  185.     @tweeners = []
  186.     for i in 0...easers.size
  187.       args = (i % 2 == 0 ? [svs, evs] : [evs, svs]) + [easers[i], maxtimes[i%maxtimes.size]]
  188.       @tweeners[i] = Tween.new( *args )
  189.     end
  190.     self
  191.   end  
  192.   def total_time
  193.     @tweeners.inject(0) { |r, t| r + t.maxtime }
  194.   end
  195.   def done?
  196.     return @tindex / @tweeners.size >= @cycles unless @cycles == -1
  197.     return false
  198.   end  
  199.   def update
  200.     return if done?
  201.     if @tweeners[@index].done?
  202.       @index = (@inverted ? @index.pred : @index.succ) % @tweeners.size
  203.       @tindex = @tindex.succ
  204.       @tweeners[@index].reset_time
  205.     end  
  206.     @tweeners[@index].update()
  207.   end  
  208.   def values
  209.     @tweeners[@index].values
  210.   end
  211.   def value(n=0)
  212.     @tweeners[@index].value(n)
  213.   end  
  214. end
  215. # // 01/31/2012
  216. # // 01/31/2012
  217. class Tween::Seqeuncer
  218.   attr_reader :index
  219.   attr_reader :tweeners
  220.   def initialize()
  221.     @tweeners = []
  222.     @index = 0
  223.   end
  224.   def add_tween(*args,&block)
  225.     @tweeners << Tween.new(*args,&block)
  226.   end  
  227.   def reset
  228.     @index = 0
  229.     @tweeners.each { |t| t.reset! }
  230.   end    
  231.   def total_time
  232.     @tweeners.inject(0) { |r, t| r + t.maxtime }
  233.   end
  234.   def done?
  235.     @tweeners.all?{|t|t.done?}
  236.   end
  237.   def update
  238.     return if done?
  239.     @index = (@inverted ? @index.pred : @index.succ) if @tweeners[@index].done?
  240.     @tweeners[@index].update()
  241.   end  
  242.   def values
  243.     @tweeners[@index].values
  244.   end
  245.   def value(n=0)
  246.     @tweeners[@index].value(n)
  247.   end
  248. end  
  249. class Tween::Easer
  250.   attr_accessor :name
  251.   attr_accessor :symbol
  252.   def initialize( name = nil, &function )
  253.     @name = name || ".Easer"
  254.     @symbol = :__easer
  255.     @function = function
  256.     # // time, start_value, change_value, current_time/elapsed_time
  257.     class << self ; define_method(:_ease, &@function) ; end
  258.     @function = nil
  259.   end  
  260.   def ease( et, sv, ev, t, *args )
  261.     _ease( et, sv, ev-sv, t, *args )
  262.   end  
  263. end  
  264. class Tween
  265.   # // IceDragon
  266.   # // 01/26/2012
  267.   # // 01/26/2012
  268.   module Null
  269.     In   = Easer.new("Null::In") { |t, st, ch, d| st }
  270.     Out  = Easer.new("Null::Out") { |t, st, ch, d| ch + st }
  271.   end
  272.   # // 01/26/2012
  273.   # // 01/26/2012
  274.   module Bee
  275.     In    = Easer.new("Bee::In") { |t, st, ch, d, b=4.0|
  276.       (ch * t / d + st) + (-ch * Math.sin(Math.cos((b * t / d)*Math::PI)*Math::PI) / b)
  277.     }
  278.     Out    = Easer.new("Bee::Out") { |t, st, ch, d, b=4.0|
  279.       (ch * t / d + st) + (ch * Math.sin(Math.cos((b * t / d)*Math::PI)*Math::PI) / b)
  280.     }
  281.     InOut = Easer.new("Bee::InOut") { |t, st, ch, d, b=4.0|
  282.       t < d/2.0 ?
  283.         In.ease(t*2.0, 0, ch, d, b) * 0.5 + st :
  284.         Out.ease(t*2.0 - d, 0, ch, d, b) * 0.5 + ch * 0.5 + st
  285.     }
  286.   end
  287.   # // 01/26/2012
  288.   # // 01/26/2012
  289.   module Modulate
  290.     Out = Easer.new("Modulate::Out") { |t, st, ch, d, e1=:linear, e2=:linear|
  291.       return st if ch == 0
  292.       Tween::EASER_SYMBOLS[e1].ease(t, 0, ch, d) * (Tween::EASER_SYMBOLS[e2].ease(t, 0, ch, d) / ch) + st
  293.     }
  294.     In = Easer.new("Modulate::In") { |t, st, ch, d, e1=:linear, e2=:linear|
  295.       return st if ch == 0
  296.       Tween::EASER_SYMBOLS[e1].ease(t, 0, ch, d) * (1.0-(Tween::EASER_SYMBOLS[e2].ease(d-t, 0, ch, d) / ch)) + st
  297.     }
  298.     InOut = Easer.new("Modulate::InOut") { |t, st, ch, d, e1=:linear, e2=:sine_in|
  299.       t < d/2.0 ?
  300.         In.ease(t*2.0, 0, ch, d) * 0.5 + st :
  301.         Out.ease(t*2.0 - d, 0, ch, d) * 0.5 + ch * 0.5 + st
  302.     }
  303.   end  
  304.   # // Jet
  305.   Linear  = Easer.new("Linear") { |t, st, ch, d| ch * t / d + st }
  306.   module Sine
  307.     In    = Easer.new("Sine::In") { |t, st, ch, d|
  308.       -ch * Math.cos(t / d * (Math::PI / 2)) + ch + st
  309.     }
  310.     Out   = Easer.new("Sine::Out") { |t, st, ch, d|
  311.       ch * Math.sin(t / d * (Math::PI / 2)) + st
  312.     }
  313.     InOut = Easer.new("Sine::InOut") { |t, st, ch, d|
  314.       -ch / 2 * (Math.cos(Math::PI * t / d) - 1) + st
  315.     }
  316.   end
  317.   module Circ  
  318.     In    = Easer.new("Circ::In") { |t, st, ch, d|
  319.       -ch * (Math.sqrt(1 - (t/d) * t/d) - 1) + st rescue st
  320.     }
  321.     Out   = Easer.new("Circ::Out") { |t, st, ch, d|
  322.       t = t/d - 1 ; ch * Math.sqrt(1 - t * t) + st rescue st
  323.     }
  324.     InOut = Easer.new("Circ::InOut") { |t, st, ch, d|
  325.       (t /= d/2.0) < 1 ?
  326.        -ch / 2 * (Math.sqrt(1 - t*t) - 1) + st :
  327.         ch / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + st rescue st
  328.     }
  329.   end  
  330.   module Bounce
  331.     Out    = Easer.new("Bounce::Out") { |t, st, ch, d|
  332.       if (t /= d) < (1/2.75)
  333.         ch * (7.5625 * t * t) + st
  334.       elsif t < (2 / 2.75)
  335.         ch * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + st
  336.       elsif t < (2.5 / 2.75)
  337.         ch * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + st
  338.       else
  339.         ch * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + st
  340.       end
  341.     }
  342.     In    = Easer.new("Bounce::In") { |t, st, ch, d|
  343.       ch - Out.ease(d-t, 0, ch, d) + st
  344.     }
  345.     InOut = Easer.new("Bounce::InOut") { |t, st, ch, d|
  346.       t < d/2.0 ?
  347.         In.ease(t*2.0, 0, ch, d) * 0.5 + st :
  348.         Out.ease(t*2.0 - d, 0, ch, d) * 0.5 + ch * 0.5 + st
  349.     }
  350.   end  
  351.   module Back  
  352.     In    = Easer.new("Back::In") { |t, st, ch, d, s=1.70158|
  353.       ch * (t/=d) * t * ((s+1) * t - s) + st
  354.     }
  355.     Out   = Easer.new("Back::Out") { |t, st, ch, d, s=1.70158|
  356.       ch * ((t=t/d-1) * t * ((s+1) * t + s) + 1) + st
  357.     }
  358.     InOut = Easer.new("Back::InOut") { |t, st, ch, d, s=1.70158|
  359.       (t /= d/2.0) < 1 ?
  360.         ch / 2.0 * (t * t * (((s *= (1.525)) + 1) * t - s)) + st :
  361.         ch / 2.0 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + st
  362.     }
  363.   end  
  364.   module Cubic
  365.     In    = Easer.new("Cubic::In") { |t, st, ch, d| ch * (t /= d) * t * t + st }
  366.     Out   = Easer.new("Cubic::Out") { |t, st, ch, d|
  367.       ch * ((t = t / d.to_f - 1) * t * t + 1) + st
  368.     }
  369.     InOut = Easer.new("Cubic::InOut") { |t, st, ch, d|
  370.       (t /= d / 2.0) < 1 ?
  371.         ch / 2.0 * t * t * t + st :
  372.         ch / 2.0 * ((t -= 2) * t * t + 2) + st
  373.     }
  374.   end
  375.   module Expo  
  376.     In    = Easer.new("Expo::In") { |t, st, ch, d|
  377.       t == 0 ? st : ch * (2 ** (10 * (t / d.to_f - 1))) + st
  378.     }
  379.     Out   = Easer.new("Expo::Out") { |t, st, ch, d|
  380.       t == d ? st + ch : ch * (-(2 ** (-10 * t / d.to_f)) + 1) + st
  381.     }
  382.     InOut = Easer.new("Expo::InOut") { |t, st, ch, d|
  383.       if t == 0                ; st
  384.       elsif t == d             ; st + ch
  385.       elsif (t /= d / 2.0) < 1 ; ch / 2.0 * (2 ** (10 * (t - 1))) + st
  386.       else                     ; ch / 2.0 * (-(2 ** (-10 * (t -= 1))) + 2) + st
  387.       end
  388.     }
  389.   end  
  390.   module Quad
  391.     In    = Easer.new("Quad::In") { |t, st, ch, d|
  392.       ch * (t /= d.to_f) * t + st
  393.     }
  394.     Out   = Easer.new("Quad::Out") { |t, st, ch, d|
  395.       -ch * (t /= d.to_f) * (t - 2) + st
  396.     }
  397.     InOut = Easer.new("Quad::InOut") { |t, st, ch, d|
  398.       (t /= d / 2.0) < 1 ?
  399.         ch / 2.0 * t * t + st :
  400.         -ch / 2.0 * ((t -= 1) * (t - 2) - 1) + st
  401.     }
  402.   end  
  403.   module Quart
  404.     In    = Easer.new("Quart::In") { |t, st, ch, d|
  405.       ch * (t /= d.to_f) * t * t * t + st
  406.     }
  407.     Out   = Easer.new("Quart::Out") { |t, st, ch, d|
  408.       -ch * ((t = t / d.to_f - 1) * t * t * t - 1) + st
  409.     }
  410.     InOut = Easer.new("Quart::InOut") { |t, st, ch, d|
  411.       (t /= d / 2.0) < 1 ?
  412.         ch / 2.0 * t * t * t * t + st :
  413.         -ch / 2.0 * ((t -= 2) * t * t * t - 2) + st
  414.     }
  415.   end  
  416.   module Quint
  417.     In    = Easer.new("Quint::In") { |t, st, ch, d|
  418.       ch * (t /= d.to_f) * t * t * t * t + st
  419.     }
  420.     Out   = Easer.new("Quint::Out") { |t, st, ch, d|
  421.       ch * ((t = t / d.to_f - 1) * t * t *t * t + 1) + st
  422.     }
  423.     InOut = Easer.new("Quint::InOut") { |t, st, ch, d|
  424.       (t /= d / 2.0) < 1 ?
  425.         ch / 2.0 * t * t *t * t * t + st :
  426.         ch / 2.0 * ((t -= 2) * t * t * t * t + 2) + st
  427.     }
  428.   end  
  429.   module Elastic
  430.     In    = Easer.new("Elastic::In") { |t, st, ch, d, a = 5, p = 0|
  431.       s = 0
  432.       if t == 0
  433.         st
  434.       elsif (t /= d.to_f) >= 1
  435.         st + ch
  436.       else  
  437.         p = d * 0.3 if p == 0
  438.         if (a == 0) || (a < ch.abs)
  439.           a = ch
  440.           s = p / 4.0
  441.         else
  442.           s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
  443.         end
  444.         -(a * (2 ** (10 * (t -= 1))) * Math.sin( (t * d - s) * (2 * Math::PI) / p)) + st
  445.       end
  446.     }
  447.     Out   = Easer.new("Elastic::Out") { |t, st, ch, d, a = 5, p = 0|  
  448.       s = 0
  449.       if t == 0
  450.         st
  451.       elsif (t /= d.to_f) >= 1
  452.         st + ch
  453.       else  
  454.         p = d * 0.3 if p == 0
  455.         if (a == 0) || (a < ch.abs)
  456.           a = ch
  457.           s = p / 4.0
  458.         else
  459.           s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
  460.         end
  461.         a * (2 ** (-10 * t)) * Math.sin((t * d - s) * (2 * Math::PI) / p.to_f) + ch + st
  462.       end  
  463.     }
  464.   end  
  465. end  
  466. class Tween
  467.   EASERS = [
  468.     Null::In,
  469.     Null::Out,
  470.    
  471.     Linear,
  472.    
  473.     Sine::In,
  474.     Sine::Out,
  475.     Sine::InOut,
  476.    
  477.     Circ::In,
  478.     Circ::Out,
  479.     Circ::InOut,
  480.    
  481.     Bounce::In,
  482.     Bounce::Out,
  483.     Bounce::InOut,
  484.    
  485.     Back::In,
  486.     Back::Out,
  487.     Back::InOut,
  488.    
  489.     Cubic::In,
  490.     Cubic::Out,
  491.     Cubic::InOut,
  492.    
  493.     Expo::In,
  494.     Expo::Out,
  495.     Expo::InOut,
  496.    
  497.     Quad::In,
  498.     Quad::Out,
  499.     Quad::InOut,
  500.    
  501.     Quart::In,
  502.     Quart::Out,
  503.     Quart::InOut,
  504.    
  505.     Quint::In,
  506.     Quint::Out,
  507.     Quint::InOut,
  508.    
  509.     Elastic::In,
  510.     Elastic::Out,
  511.    
  512.     Bee::In,
  513.     Bee::Out,
  514.     Bee::InOut,
  515.    
  516.     #Modulate::In,
  517.     #Modulate::Out,
  518.     #Modulate::InOut
  519.   ]
  520.   EASER_SYMBOLS = { }
  521.   EASERS.each { |e|
  522.     sym = e.name.gsub(/\:\:/i,"_").downcase.to_sym
  523.     EASER_SYMBOLS[sym] = e
  524.     EASER_SYMBOLS[sym].symbol = sym
  525.   }
  526. end
  527. #=■==========================================================================■=#
  528. #                           // ● End of File ● //                              #
  529. #=■==========================================================================■=#
Advertisement
Add Comment
Please, Sign In to add comment