Advertisement
Guest User

tween

a guest
Apr 26th, 2019
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.56 KB | None | 0 0
  1. local List = setmetatable({}, {
  2.     __call = function(self)
  3.         return setmetatable({ __data = {}, __size = 0 }, self)
  4.     end
  5. })
  6. List.__index = List
  7.  
  8. function List:get(index)
  9.     return self.__data[index]
  10. end
  11.  
  12. function List:set(index, value)
  13.     self.__data[index] = value
  14. end
  15.  
  16. function List:add(value)
  17.     table.insert(self.__data, value)
  18.     self.__size = self.__size + 1
  19. end
  20.  
  21. function List:remove(value)
  22.     for i = 1, self.__size do
  23.         if rawequal(self.__data[i], value) then
  24.             table.remove(self.__data, i)
  25.             self.__size = self.__size - 1
  26.             return
  27.         end
  28.     end
  29. end
  30.  
  31. function List:clear()
  32.     self.__data = {}
  33.     self.__size = 0
  34. end
  35.  
  36. function List:foreach(predicate)
  37.     for i = 1, self.__size do
  38.         predicate(self.__data[i])
  39.     end
  40. end
  41.  
  42. function List:__iterator()
  43.     return coroutine.wrap(function()
  44.         for i = 1, self.__size do
  45.             coroutine.yield(self.__data[i])
  46.         end
  47.     end)
  48. end
  49.  
  50. local function invoke(func, ...)
  51.     if func then
  52.         return func(...)
  53.     end
  54. end
  55.  
  56. local tweens = List()
  57.  
  58. local FilterType = {
  59.     All          = 1,
  60.     TargetOrName = 2
  61. }
  62.  
  63. local isUpdateLoop = false
  64.  
  65. LoopType = {
  66.     Restart = 0,
  67.     Yoyo    = 1
  68. }
  69.  
  70. local function linear(from, to, time, duration)
  71.     return from + (to - from) * time / duration
  72. end
  73.  
  74. function Bind(f, ...)
  75.     local _1 = { n = select("#", ...), v = { ... } }
  76.  
  77.     return function ( ... )
  78.         local _2 = { n = select("#", ...), v = { ... } }
  79.  
  80.         local args = {}
  81.  
  82.         for i = 1, _1.n do
  83.             args[i] = _1.v[i]
  84.         end
  85.  
  86.         for i = 1, _2.n do
  87.             args[i + _1.n] = _2.v[i]
  88.         end
  89.  
  90.         return f(unpack(args, 1, _1.n + _2.n))
  91.     end
  92. end
  93.  
  94. function FilteredOperation(filter, action, id, filter_compliant)
  95.     tweens:foreach(function(tween)
  96.         local isFilterCompliant = false
  97.  
  98.         if filter_compliant then
  99.             isFilterCompliant = filter_compliant(tween)
  100.         elseif filter == FilterType.All then
  101.             isFilterCompliant = true
  102.         elseif filter == FilterType.TargetOrName then
  103.             if tween.parent then
  104.                 isFilterCompliant = rawequal(tween.parent, id) or rawequal(tween.parent:GetName(), id:GetName())
  105.             end
  106.         end
  107.  
  108.         if isFilterCompliant then
  109.             action(tween)
  110.         end
  111.     end)
  112. end
  113.  
  114. Tween = {}
  115. Tween.__index = Tween
  116. function Tween:SetParent(parent)
  117.     self.parent = parent
  118.     return self
  119. end
  120.  
  121. function Tween:SetAutoKill(auto_kill)
  122.     self.auto_kill = auto_kill
  123.     return self
  124. end
  125.  
  126. function Tween:SetLoops(loops, loop_type)
  127.     self.loops     = loops or 1
  128.     self.loop_type = loop_type or LoopType.Restart
  129.     return self
  130. end
  131.  
  132. function Tween:SetDelay(delay)
  133.     self.delay = delay or 0
  134.     return self
  135. end
  136.  
  137. function Tween:OnStart(callback)
  138.     self.on_start = callback
  139.     return self
  140. end
  141.  
  142. function Tween:OnComplete(callback)
  143.     self.on_complete = callback
  144.     return self
  145. end
  146.  
  147. function Tween:OnKill(callback)
  148.     self.on_kill = callback
  149.     return self
  150. end
  151.  
  152. function Tween:SetPartial(partial)
  153.     self.partial = partial
  154.     return self
  155. end
  156.  
  157. function Tween:Play(time)
  158.     if not self.playing then
  159.         self.playing         = true
  160.         self.started         = false
  161.         self.iterations      = 0
  162.         self.time            = time or 0
  163.     end
  164. end
  165.  
  166. function Tween:Relative()
  167.     self.relative = true
  168.     return self
  169. end
  170.  
  171. function Tween:Absolute()
  172.     self.relative = false
  173.     return self
  174. end
  175.  
  176. function Tween:Kill()
  177.     if self.killed == false then
  178.         self.killed = true
  179.         self.playing = false
  180.  
  181.         if self.on_kill then
  182.             self.on_kill()
  183.         end
  184.     end
  185. end
  186.  
  187. function Tween:IsAlive()
  188.     if self.parent and self.parent.IsAlive then
  189.         return self.parent:IsAlive()
  190.     end
  191.  
  192.     return true
  193. end
  194.  
  195. function Tween.init()
  196.     tweens = List()
  197. end
  198.  
  199. function Tween.new(get, set, to, duration)
  200.     local tween = setmetatable({
  201.         get             = get,
  202.         set             = set,
  203.         to              = to,
  204.         duration        = duration,
  205.         playing         = false,
  206.         time            = 0,
  207.         from            = get(),
  208.         pausing         = false,
  209.         ease            = linear,
  210.         delay           = 0,
  211.         iterations      = 0,
  212.         loops           = 1,
  213.         loop_type       = LoopType.Restart,
  214.         backward        = false,
  215.         auto_kill       = true,
  216.         killed          = false,
  217.         partial         = false,
  218.     }, Tween)
  219.  
  220.     tweens:add(tween)
  221.     return tween
  222. end
  223.  
  224. TweenSequence = {}
  225. TweenSequence.__index = TweenSequence
  226. function TweenSequence:Append(tween)
  227.     return self:Insert(self.duration, tween)
  228. end
  229.  
  230. function TweenSequence:AppendInterval(interval)
  231.     self.duration = self.duration + interval
  232.     return self
  233. end
  234.  
  235. function TweenSequence:AppendCallback(callback)
  236.     return self:InsertCallback(self.duration, callback)
  237. end
  238.  
  239. function TweenSequence:AppendAnimation(bundle, name)
  240.     return self:InsertAnimation(self.duration, bundle, name)
  241. end
  242.  
  243. function TweenSequence:InsertAnimation(location, bundle, name)
  244.     local anim = bundle:GetAnimation(name)
  245.     self.queue:add({ triggered = false, delay = location, callback = function()
  246.         anim:SetVisible(true)
  247.         anim:Play()
  248.     end})
  249.     self.duration = math.max(self.duration, location + anim:GetDuration())
  250.     return self
  251. end
  252.  
  253. function TweenSequence:Insert(location, tween)
  254.     tweens:remove(tween)
  255.     self.queue:add({ triggered = false, delay = location, action = tween:SetParent(nil) })
  256.     self.duration = math.max(self.duration, location + tween.duration + tween.delay)
  257.     return self
  258. end
  259.  
  260. function TweenSequence:InsertCallback(location, callback)
  261.     self.queue:add({ triggered = false, delay = location, callback = callback })
  262.     self.duration = math.max(self.duration, location)
  263.     return self
  264. end
  265.  
  266. function TweenSequence:SetParent(parent)
  267.     return self
  268. end
  269.  
  270. function TweenSequence:Duration()
  271.     return self.duration
  272. end
  273.  
  274. function TweenSequence:OnComplete(callback)
  275.     return Tween.OnComplete(self, callback)
  276. end
  277. function TweenSequence:OnStart(callback)
  278.     return Tween.OnStart(self, callback)
  279. end
  280.  
  281. function TweenSequence:OnKill(callback)
  282.     return Tween.OnKill(self, callback)
  283. end
  284.  
  285. function TweenSequence:Kill()
  286.     Tween.Kill(self)
  287. end
  288.  
  289. function TweenSequence:__update(dt)
  290.     if self.playing then
  291.         self.time = self.time + dt
  292.  
  293.         local elapsed = self.time - self.delay
  294.         if elapsed > 0 then
  295.             if not self.started then
  296.                 self.started = true
  297.                 if self.on_start then
  298.                     self:on_start()
  299.                 end
  300.             end
  301.  
  302.             self.queue:foreach(function(entry)
  303.                 if not entry.triggered then
  304.                     if self.time >= entry.delay then
  305.                         entry.triggered = true
  306.  
  307.                         local action = entry.action
  308.                         self.actions:add(action or entry.callback)
  309.                        
  310.                         if action and action.get then
  311.                             action.from = action.get()
  312.                             action:Play()
  313.                         end
  314.                     end
  315.                 end
  316.             end)
  317.  
  318.             local to_remove = {}
  319.             self.actions:foreach(function(action)
  320.                 if type(action) == 'function' then
  321.                     table.insert(to_remove, action)
  322.                     action()
  323.                 elseif action:__update(dt) then
  324.                     table.insert(to_remove, action)
  325.                 end
  326.             end)
  327.  
  328.             for i, action in ipairs(to_remove) do
  329.                 self.actions:remove(action)
  330.             end
  331.  
  332.             if self.time >= self.duration then
  333.                 self.playing = false
  334.  
  335.                 if self.on_complete then
  336.                     self:on_complete()
  337.                 end
  338.                 return true
  339.             end
  340.         end
  341.     end
  342.  
  343.     return self.killed
  344. end
  345.  
  346. function Tween.sequence()
  347.     local sequence = setmetatable({
  348.         queue     = List();
  349.         actions   = List();
  350.         playing   = true;
  351.         time      = 0;
  352.         duration  = 0;
  353.         delay     = 0;
  354.     }, TweenSequence)
  355.  
  356.     tweens:add(sequence)
  357.     return sequence
  358. end
  359.  
  360. function Tween:__update(dt)
  361.     if not self:IsAlive() then
  362.         return true
  363.     end
  364.    
  365.     if self.playing then
  366.         self.time = self.time + dt
  367.  
  368.         local elapsed = self.time - self.delay
  369.         if elapsed > 0 then
  370.             if not self.started then
  371.                 self.started = true
  372.                 if self.on_start then
  373.                     self:on_start()
  374.                 end
  375.             end
  376.            
  377.             if self.partial then
  378.                 self.partial = false
  379.                 self.from   = self.get()
  380.             end
  381.  
  382.             local from = self.from
  383.             local to   = self.to
  384.  
  385.             if self.relative then
  386.                 to = from + to
  387.             end
  388.  
  389.             if self.backward then
  390.                 from, to = to, from
  391.             end
  392.  
  393.             if elapsed < self.duration then
  394.                 local value = self.ease(from, to, elapsed, self.duration)
  395.  
  396.                 self.set(value)
  397.  
  398.                 if self.on_update then
  399.                     self:on_update(value)
  400.                 end
  401.             else
  402.                 self.set(to)
  403.  
  404.                 self.iterations = self.iterations + 1
  405.                 if (self.loops == -1) or (self.iterations < self.loops) then
  406.                     self.time = 0
  407.  
  408.                     if self.loop_type == LoopType.Yoyo then
  409.                         self.backward = not self.backward
  410.                     end
  411.                 else
  412.                     self.playing = false
  413.  
  414.                     if self.on_complete then
  415.                         self:on_complete()
  416.                     end
  417.  
  418.                     if self.auto_kill then
  419.                         return true
  420.                     end
  421.                 end
  422.             end
  423.         end
  424.     end
  425.    
  426.     return self.killed
  427. end
  428.  
  429. function Tween.toolFoundEffect(save, obj, fade_time, fade_delay, scale)
  430.     if type(obj) == 'string' then
  431.         obj = play_field:GetObject(obj)
  432.     end
  433.     fade_time = fade_time or 0.35
  434.     fade_delay = fade_delay or 0.2
  435.     scale = scale or 0.3
  436.  
  437.     if save then
  438.         obj:Hide()
  439.     else
  440.         obj:DoFade(0, fade_time):SetDelay(fade_delay):Play()
  441.         obj:DoScale(scale, fade_time + fade_delay):Play()
  442.     end
  443. end
  444.  
  445. --[[
  446.     force_not_show is for Composition Element/Sequence, Show() function leads to the crash
  447.     todo: rewrite Show/Hide function for Composition Element/Sequence
  448. --]]
  449. function Tween.fadeShow(obj, duration, force_not_show)
  450.     if type(obj) == 'string' then
  451.         obj = play_field:GetObject(obj)
  452.     end
  453.  
  454.     local tween = obj:DoFade(1, duration or CHANGE_OBJECT_OPACITY)
  455.     tween.partial = true
  456.     tween.on_start = function()
  457.         obj:SetOpacity(0)
  458.  
  459.         if not force_not_show then
  460.             obj:Show()
  461.         end
  462.     end
  463.     tween:Play()
  464.     return tween
  465. end
  466.  
  467. function Tween.fadeHideChildrens(save, obj, duration, detach)
  468.     if type(obj) == 'string' then
  469.         obj = play_field:GetObject(obj)
  470.     end
  471.  
  472.     local anim = Tween.sequence()
  473.  
  474.     local childs = obj:GetChildren()
  475.     for i = 0, childs:size() - 1 do
  476.         local child = play_field:GetObject(childs:get(i))
  477.  
  478.         if save then
  479.             child:Hide()
  480.         else
  481.             if detach then
  482.                 AttachInPlace(child, play_field)
  483.             end
  484.             anim:Insert(0, Tween.fadeHide(child, duration))
  485.         end
  486.     end
  487.  
  488.     return anim
  489. end
  490.  
  491. function Tween.makeSpline(self, startPt, endPt, maxDeltaPos, pointCount, duration)
  492.     local startHandle = startPt + Vector(RandomFloat(-maxDeltaPos, maxDeltaPos), RandomFloat(-maxDeltaPos, maxDeltaPos))
  493.     local endHandle = endPt + Vector(RandomFloat(-maxDeltaPos, maxDeltaPos), -240)
  494.  
  495.     local dT = 1.0 / pointCount;
  496.     local x0 = startPt.x;
  497.     local y0 = startPt.y;
  498.     local xH0 = startHandle.x;
  499.     local yH0 = startHandle.y;
  500.     local x1 = endPt.x;
  501.     local y1 = endPt.y;
  502.     local xH1 = endHandle.x;
  503.     local yH1 = endHandle.y;
  504.  
  505.     local t = 0.0;
  506.     for i = 0, pointCount do
  507.         local oT = 1.0 - t;
  508.         local a0 = math.pow(oT, 3.0);
  509.         local a1 = 3.0 * t * oT * oT;
  510.         local a2 = 3.0 * t * t * oT;
  511.         local a3 = math.pow(t, 3.0);
  512.         local x = a0 * x0 + a1 * xH0 + a2 * xH1 + a3 * x1;
  513.         local y = a0 * y0 + a1 * yH0 + a2 * yH1 + a3 * y1;
  514.  
  515.         self:SetKey(_TRACK_X, t * duration, x);
  516.         self:SetKey(_TRACK_Y, t * duration, y);
  517.  
  518.         t = t + dT
  519.     end
  520. end
  521.  
  522. function Tween.flyObjectTo(object, target, fly_time, maxDeltaPos, pointCount)
  523.     if type(object) == 'string' then
  524.         object = play_field:GetObject(object)
  525.     end
  526.  
  527.     if type(target) == 'string' then
  528.         target = play_field:GetObject(target)
  529.     end
  530.  
  531.     fly_time = fly_time or 0.7
  532.     maxDeltaPos = maxDeltaPos or 56
  533.     pointCount = pointCount or 15
  534.  
  535.     local layer = object:GetLayer()
  536.     local anim = Tween.sequence()
  537.     anim:OnStart(function()
  538.         object:ResetRenderBox()
  539.         object:SetLayer(layer + 10)
  540.  
  541.         local startPos = Vector(object:GetScrX(), object:GetScrY())
  542.         local finishPos = Vector(target:GetScrX(), target:GetScrY())
  543.  
  544.         -- todo: replace effector with tween
  545.         local mover = CreateAnimationEffector()
  546.         mover:SetDestroysOnEnd(true)
  547.         mover:AttachTo(object)
  548.         mover:SetKeysMode(_KEYS_XY_SCR)
  549.         Tween.makeSpline(mover, startPos, finishPos, maxDeltaPos, pointCount, fly_time)
  550.         mover:Play()
  551.  
  552.         object:AddParticleSystem('Data/Particles/ItemFound2.sps', 'particles', false)
  553.         object:AddParticleSystem('Data/Particles/MoveTail.sps', 'particles', true)
  554.     end)
  555.     anim:Insert(0.7 * fly_time, Tween.fadeHide(object, 0.3 * fly_time))
  556.     anim:Insert(0.7 * fly_time, Tween.fadeShow(target, 0.3 * fly_time))
  557.     anim:OnComplete(function()
  558.         object:SetLayer(layer)
  559.     end)
  560.  
  561.     return anim
  562. end
  563.  
  564. function Tween.fadeHide(obj, duration)
  565.     if type(obj) == 'string' then
  566.         obj = play_field:GetObject(obj)
  567.     end
  568.  
  569.     local tween = obj:DoFade(0, duration or CHANGE_OBJECT_OPACITY)
  570.     tween.on_complete = function()
  571.         obj:Hide()
  572.     end
  573.     tween:Play()
  574.     return tween
  575. end
  576.  
  577. function Tween.moveXY(obj, x, y, duration, relative, on_complete)
  578.     if type(obj) == 'string' then
  579.         obj = play_field:GetObject(obj)
  580.     end
  581.    
  582.     local tween = obj:DoMove(Vector(x, y), duration)
  583.     tween.on_complete = on_complete
  584.     tween.relative = relative or false
  585.     tween:Play()
  586.     return tween
  587. end
  588.  
  589. function Tween.rotate(obj, angle, duration, relative)
  590.     if type(obj) == 'string' then
  591.         obj = play_field:GetObject(obj)
  592.     end
  593.    
  594.     local tween = obj:DoRotate(angle, duration)
  595.     tween.relative = relative or false
  596.     tween:Play()
  597.     return tween
  598. end
  599.  
  600. function Tween.requireHighlight(obj, fade_time, delay, on_complete)
  601.     if type(obj) == 'string' then
  602.         obj = play_field:GetObject(obj)
  603.     end
  604.  
  605.     local anim = Tween.sequence()
  606.     anim:Append(Tween.fadeShow(obj, fade_time))
  607.     if delay then
  608.         anim:AppendInterval(delay)
  609.     end
  610.     anim:Append(Tween.fadeHide(obj, fade_time))
  611.     anim.on_complete = on_complete
  612.     return anim
  613. end
  614.  
  615. function Tween.update(dt)
  616.     local to_remove = {}
  617.     tweens:foreach(function(tween)
  618.         if tween:__update(dt) then
  619.             table.insert(to_remove, tween)
  620.         end
  621.     end)
  622.  
  623.     for i, tween in ipairs(to_remove) do
  624.         tweens:remove(tween)
  625.     end
  626. end
  627.  
  628. local function Kill(self)
  629.     self:Kill()
  630. end
  631.  
  632. function Tween.KillAll()
  633.     FilteredOperation(FilterType.All, Kill)
  634. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement