Commit 9811fc7dbe12c52748b1896ecd09a22771ae776f

Authored by DarkGod
2 parents 9fd9a6cc e985b690

Merge branch 'master' of git.net-core.org:darkgod/t-engine4

... ... @@ -20,6 +20,7 @@
20 20 require "engine.class"
21 21 require "engine.Mouse"
22 22 require "engine.DebugConsole"
  23 +local tween = require "tween"
23 24 local Shader = require "engine.Shader"
24 25
25 26 --- Represent a game
... ... @@ -181,6 +182,9 @@ function _M:display(nb_keyframes)
181 182 else self._timers_cb = nil end
182 183 for _, cb in ipairs(exec) do cb() end
183 184 end
  185 +
  186 + -- Update tweening engine
  187 + if nb_keyframes > 0 then tween.update(nb_keyframes) end
184 188 end
185 189
186 190 --- Register a timer
... ...
  1 +Copyright (c) 2011, Enrique García Cota
  2 +All rights reserved.
  3 +
  4 +Redistribution and use in source and binary forms, with or without modification,
  5 +are permitted provided that the following conditions are met:
  6 +
  7 + 1. Redistributions of source code must retain the above copyright notice,
  8 + this list of conditions and the following disclaimer.
  9 + 2. Redistributions in binary form must reproduce the above copyright notice,
  10 + this list of conditions and the following disclaimer in the documentation
  11 + and/or other materials provided with the distribution.
  12 + 3. Neither the name of tween.lua nor the names of its contributors
  13 + may be used to endorse or promote products derived from this software
  14 + without specific prior written permission.
  15 +
  16 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19 +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  20 +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  21 +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  24 +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  25 +OF THE POSSIBILITY OF SUCH DAMAGE.
  26 +
  27 +=====================================================================================
  28 +
  29 +The easing functions were taken from emmanuelOga's easing functions
  30 +(https://github.com/EmmanuelOga/easing).
  31 +
  32 +Here's its license:
  33 +
  34 +Tweener authors,
  35 +Yuichi Tateno,
  36 +Emmanuel Oga
  37 +
  38 +The MIT License
  39 +--------
  40 +Copyright (c) 2010, Emmanuel Oga.
  41 +
  42 +Permission is hereby granted, free of charge, to any person obtaining a copy
  43 +of this software and associated documentation files (the "Software"), to deal
  44 +in the Software without restriction, including without limitation the rights
  45 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  46 +copies of the Software, and to permit persons to whom the Software is
  47 +furnished to do so, subject to the following conditions:
  48 +
  49 +The above copyright notice and this permission notice shall be included in
  50 +all copies or substantial portions of the Software.
  51 +
  52 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  53 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  54 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  55 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  56 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  57 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  58 +THE SOFTWARE.
  59 +
  60 +=====================================================================================
  61 +
  62 +Emmanuel Oga's functions, in turn, were adapted from Penner's Easing Equations
  63 +and http://code.google.com/p/tweener/ (jstweener javascript version)
  64 +
  65 +Disclaimer for Robert Penner's Easing Equations license:
  66 +
  67 +TERMS OF USE - EASING EQUATIONS
  68 +
  69 +Open source under the BSD License.
  70 +
  71 +Copyright © 2001 Robert Penner
  72 +All rights reserved.
  73 +
  74 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  75 +
  76 + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  77 + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  78 + * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  79 +
  80 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  81 +
  82 +
... ...
  1 +-----------------------------------------------------------------------------------------------------------------------
  2 +-- tween.lua - v1.0.1 (2012-02)
  3 +-- Enrique García Cota - enrique.garcia.cota [AT] gmail [DOT] com
  4 +-- tweening functions for lua
  5 +-- inspired by jquery's animate function
  6 +-----------------------------------------------------------------------------------------------------------------------
  7 +local tween = {}
  8 +
  9 +-- private stuff
  10 +
  11 +local tweens -- initialized by calling to tween.stopAll()
  12 +
  13 +local function isCallable(f)
  14 + local tf = type(f)
  15 + if tf == 'function' then return true end
  16 + if tf == 'table' then
  17 + local mt = getmetatable(f)
  18 + return (type(mt) == 'table' and type(mt.__call) == 'function')
  19 + end
  20 + return false
  21 +end
  22 +
  23 +local function copyTables(destination, keysTable, valuesTable)
  24 + valuesTable = valuesTable or keysTable
  25 + local mt = getmetatable(keysTable)
  26 + if mt and getmetatable(destination) == nil then
  27 + setmetatable(destination, mt)
  28 + end
  29 + for k,v in pairs(keysTable) do
  30 + if type(v) == 'table' then
  31 + destination[k] = copyTables({}, v, valuesTable[k])
  32 + else
  33 + destination[k] = valuesTable[k]
  34 + end
  35 + end
  36 + return destination
  37 +end
  38 +
  39 +local function checkSubjectAndTargetRecursively(subject, target, path)
  40 + path = path or {}
  41 + local targetType, newPath
  42 + for k,targetValue in pairs(target) do
  43 + targetType, newPath = type(targetValue), copyTables({}, path)
  44 + table.insert(newPath, tostring(k))
  45 + if targetType == 'number' then
  46 + assert(type(subject[k]) == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' is missing from subject or isn't a number")
  47 + elseif targetType == 'table' then
  48 + checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
  49 + else
  50 + assert(targetType == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' must be a number or table of numbers")
  51 + end
  52 + end
  53 +end
  54 +
  55 +local function checkStartParams(time, subject, target, easing, callback)
  56 + assert(type(time) == 'number' and time > 0, "time must be a positive number. Was " .. tostring(time))
  57 + local tsubject = type(subject)
  58 + assert(tsubject == 'table' or tsubject == 'userdata', "subject must be a table or userdata. Was " .. tostring(subject))
  59 + assert(type(target)== 'table', "target must be a table. Was " .. tostring(target))
  60 + assert(isCallable(easing), "easing must be a function or functable. Was " .. tostring(easing))
  61 + assert(callback==nil or isCallable(callback), "callback must be nil, a function or functable. Was " .. tostring(time))
  62 + checkSubjectAndTargetRecursively(subject, target)
  63 +
  64 +end
  65 +
  66 +local function getEasingFunction(easing)
  67 + easing = easing or "linear"
  68 + if type(easing) == 'string' then
  69 + local name = easing
  70 + easing = tween.easing[name]
  71 + assert(type(easing) == 'function', "The easing function name '" .. name .. "' is invalid")
  72 + end
  73 + return easing
  74 +end
  75 +
  76 +local function newTween(time, subject, target, easing, callback, args)
  77 + local self = {
  78 + time = time,
  79 + subject = subject,
  80 + target = copyTables({},target),
  81 + easing = easing,
  82 + callback = callback,
  83 + args = args,
  84 + initial = copyTables({}, target, subject),
  85 + running = 0
  86 + }
  87 + tweens[self] = self
  88 + return self
  89 +end
  90 +
  91 +local function easeWithTween(self, subject, target, initial)
  92 + local t,b,c,d
  93 + for k,v in pairs(target) do
  94 + if type(v)=='table' then
  95 + easeWithTween(self, subject[k], v, initial[k])
  96 + else
  97 + t,b,c,d = self.running, initial[k], v - initial[k], self.time
  98 + subject[k] = self.easing(t,b,c,d)
  99 + end
  100 + end
  101 +end
  102 +
  103 +local function updateTween(self, dt)
  104 + self.running = self.running + dt
  105 + easeWithTween(self, self.subject, self.target, self.initial)
  106 +end
  107 +
  108 +local function hasExpiredTween(self)
  109 + return self.running >= self.time
  110 +end
  111 +
  112 +local function finishTween(self)
  113 + copyTables(self.subject, self.target)
  114 + if self.callback then self.callback(unpack(self.args)) end
  115 + tween.stop(self)
  116 +end
  117 +
  118 +local function resetTween(self)
  119 + copyTables(self.subject, self.initial)
  120 +end
  121 +
  122 +-- easing
  123 +
  124 +-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.
  125 +-- For all easing functions:
  126 +-- t = time == how much time has to pass for the tweening to complete
  127 +-- b = begin == starting property value
  128 +-- c = change == ending - beginning
  129 +-- d = duration == running time. How much time has passed *right now*
  130 +
  131 +local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin
  132 +
  133 +-- linear
  134 +local function linear(t, b, c, d) return c * t / d + b end
  135 +
  136 +-- quad
  137 +local function inQuad(t, b, c, d) return c * pow(t / d, 2) + b end
  138 +local function outQuad(t, b, c, d)
  139 + t = t / d
  140 + return -c * t * (t - 2) + b
  141 +end
  142 +local function inOutQuad(t, b, c, d)
  143 + t = t / d * 2
  144 + if t < 1 then return c / 2 * pow(t, 2) + b end
  145 + return -c / 2 * ((t - 1) * (t - 3) - 1) + b
  146 +end
  147 +local function outInQuad(t, b, c, d)
  148 + if t < d / 2 then return outQuad(t * 2, b, c / 2, d) end
  149 + return inQuad((t * 2) - d, b + c / 2, c / 2, d)
  150 +end
  151 +
  152 +-- cubic
  153 +local function inCubic (t, b, c, d) return c * pow(t / d, 3) + b end
  154 +local function outCubic(t, b, c, d) return c * (pow(t / d - 1, 3) + 1) + b end
  155 +local function inOutCubic(t, b, c, d)
  156 + t = t / d * 2
  157 + if t < 1 then return c / 2 * t * t * t + b end
  158 + t = t - 2
  159 + return c / 2 * (t * t * t + 2) + b
  160 +end
  161 +local function outInCubic(t, b, c, d)
  162 + if t < d / 2 then return outCubic(t * 2, b, c / 2, d) end
  163 + return inCubic((t * 2) - d, b + c / 2, c / 2, d)
  164 +end
  165 +
  166 +-- quart
  167 +local function inQuart(t, b, c, d) return c * pow(t / d, 4) + b end
  168 +local function outQuart(t, b, c, d) return -c * (pow(t / d - 1, 4) - 1) + b end
  169 +local function inOutQuart(t, b, c, d)
  170 + t = t / d * 2
  171 + if t < 1 then return c / 2 * pow(t, 4) + b end
  172 + return -c / 2 * (pow(t - 2, 4) - 2) + b
  173 +end
  174 +local function outInQuart(t, b, c, d)
  175 + if t < d / 2 then return outQuart(t * 2, b, c / 2, d) end
  176 + return inQuart((t * 2) - d, b + c / 2, c / 2, d)
  177 +end
  178 +
  179 +-- quint
  180 +local function inQuint(t, b, c, d) return c * pow(t / d, 5) + b end
  181 +local function outQuint(t, b, c, d) return c * (pow(t / d - 1, 5) + 1) + b end
  182 +local function inOutQuint(t, b, c, d)
  183 + t = t / d * 2
  184 + if t < 1 then return c / 2 * pow(t, 5) + b end
  185 + return c / 2 * (pow(t - 2, 5) + 2) + b
  186 +end
  187 +local function outInQuint(t, b, c, d)
  188 + if t < d / 2 then return outQuint(t * 2, b, c / 2, d) end
  189 + return inQuint((t * 2) - d, b + c / 2, c / 2, d)
  190 +end
  191 +
  192 +-- sine
  193 +local function inSine(t, b, c, d) return -c * cos(t / d * (pi / 2)) + c + b end
  194 +local function outSine(t, b, c, d) return c * sin(t / d * (pi / 2)) + b end
  195 +local function inOutSine(t, b, c, d) return -c / 2 * (cos(pi * t / d) - 1) + b end
  196 +local function outInSine(t, b, c, d)
  197 + if t < d / 2 then return outSine(t * 2, b, c / 2, d) end
  198 + return inSine((t * 2) -d, b + c / 2, c / 2, d)
  199 +end
  200 +
  201 +-- expo
  202 +local function inExpo(t, b, c, d)
  203 + if t == 0 then return b end
  204 + return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001
  205 +end
  206 +local function outExpo(t, b, c, d)
  207 + if t == d then return b + c end
  208 + return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b
  209 +end
  210 +local function inOutExpo(t, b, c, d)
  211 + if t == 0 then return b end
  212 + if t == d then return b + c end
  213 + t = t / d * 2
  214 + if t < 1 then return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 end
  215 + return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b
  216 +end
  217 +local function outInExpo(t, b, c, d)
  218 + if t < d / 2 then return outExpo(t * 2, b, c / 2, d) end
  219 + return inExpo((t * 2) - d, b + c / 2, c / 2, d)
  220 +end
  221 +
  222 +-- circ
  223 +local function inCirc(t, b, c, d) return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) end
  224 +local function outCirc(t, b, c, d) return(c * sqrt(1 - pow(t / d - 1, 2)) + b) end
  225 +local function inOutCirc(t, b, c, d)
  226 + t = t / d * 2
  227 + if t < 1 then return -c / 2 * (sqrt(1 - t * t) - 1) + b end
  228 + t = t - 2
  229 + return c / 2 * (sqrt(1 - t * t) + 1) + b
  230 +end
  231 +local function outInCirc(t, b, c, d)
  232 + if t < d / 2 then return outCirc(t * 2, b, c / 2, d) end
  233 + return inCirc((t * 2) - d, b + c / 2, c / 2, d)
  234 +end
  235 +
  236 +-- elastic
  237 +local function calculatePAS(p,a,c,d)
  238 + p, a = p or d * 0.3, a or 0
  239 + if a < abs(c) then return p, c, p / 4 end -- p, a, s
  240 + return p, a, p / (2 * pi) * asin(c/a) -- p,a,s
  241 +end
  242 +local function inElastic(t, b, c, d, a, p)
  243 + local s
  244 + if t == 0 then return b end
  245 + t = t / d
  246 + if t == 1 then return b + c end
  247 + p,a,s = calculatePAS(p,a,c,d)
  248 + t = t - 1
  249 + return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
  250 +end
  251 +local function outElastic(t, b, c, d, a, p)
  252 + local s
  253 + if t == 0 then return b end
  254 + t = t / d
  255 + if t == 1 then return b + c end
  256 + p,a,s = calculatePAS(p,a,c,d)
  257 + return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b
  258 +end
  259 +local function inOutElastic(t, b, c, d, a, p)
  260 + local s
  261 + if t == 0 then return b end
  262 + t = t / d * 2
  263 + if t == 2 then return b + c end
  264 + p,a,s = calculatePAS(p,a,c,d)
  265 + t = t - 1
  266 + if t < 0 then return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b end
  267 + return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b
  268 +end
  269 +local function outInElastic(t, b, c, d, a, p)
  270 + if t < d / 2 then return outElastic(t * 2, b, c / 2, d, a, p) end
  271 + return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
  272 +end
  273 +
  274 +-- back
  275 +local function inBack(t, b, c, d, s)
  276 + s = s or 1.70158
  277 + t = t / d
  278 + return c * t * t * ((s + 1) * t - s) + b
  279 +end
  280 +local function outBack(t, b, c, d, s)
  281 + s = s or 1.70158
  282 + t = t / d - 1
  283 + return c * (t * t * ((s + 1) * t + s) + 1) + b
  284 +end
  285 +local function inOutBack(t, b, c, d, s)
  286 + s = (s or 1.70158) * 1.525
  287 + t = t / d * 2
  288 + if t < 1 then return c / 2 * (t * t * ((s + 1) * t - s)) + b end
  289 + t = t - 2
  290 + return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
  291 +end
  292 +local function outInBack(t, b, c, d, s)
  293 + if t < d / 2 then return outBack(t * 2, b, c / 2, d, s) end
  294 + return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
  295 +end
  296 +
  297 +-- bounce
  298 +local function outBounce(t, b, c, d)
  299 + t = t / d
  300 + if t < 1 / 2.75 then return c * (7.5625 * t * t) + b end
  301 + if t < 2 / 2.75 then
  302 + t = t - (1.5 / 2.75)
  303 + return c * (7.5625 * t * t + 0.75) + b
  304 + elseif t < 2.5 / 2.75 then
  305 + t = t - (2.25 / 2.75)
  306 + return c * (7.5625 * t * t + 0.9375) + b
  307 + end
  308 + t = t - (2.625 / 2.75)
  309 + return c * (7.5625 * t * t + 0.984375) + b
  310 +end
  311 +local function inBounce(t, b, c, d) return c - outBounce(d - t, 0, c, d) + b end
  312 +local function inOutBounce(t, b, c, d)
  313 + if t < d / 2 then return inBounce(t * 2, 0, c, d) * 0.5 + b end
  314 + return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b
  315 +end
  316 +local function outInBounce(t, b, c, d)
  317 + if t < d / 2 then return outBounce(t * 2, b, c / 2, d) end
  318 + return inBounce((t * 2) - d, b + c / 2, c / 2, d)
  319 +end
  320 +
  321 +tween.easing = {
  322 + linear = linear,
  323 + inQuad = inQuad, outQuad = outQuad, inOutQuad = inOutQuad, outInQuad = outInQuad,
  324 + inCubic = inCubic, outCubic = outCubic, inOutCubic = inOutCubic, outInCubic = outInCubic,
  325 + inQuart = inQuart, outQuart = outQuart, inOutQuart = inOutQuart, outInQuart = outInQuart,
  326 + inQuint = inQuint, outQuint = outQuint, inOutQuint = inOutQuint, outInQuint = outInQuint,
  327 + inSine = inSine, outSine = outSine, inOutSine = inOutSine, outInSine = outInSine,
  328 + inExpo = inExpo, outExpo = outExpo, inOutExpo = inOutExpo, outInExpo = outInExpo,
  329 + inCirc = inCirc, outCirc = outCirc, inOutCirc = inOutCirc, outInCirc = outInCirc,
  330 + inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,
  331 + inBack = inBack, outBack = outBack, inOutBack = inOutBack, outInBack = outInBack,
  332 + inBounce = inBounce, outBounce = outBounce, inOutBounce = inOutBounce, outInBounce = outInBounce,
  333 +}
  334 +
  335 +
  336 +-- public functions
  337 +
  338 +function tween.start(time, subject, target, easing, callback, ...)
  339 + easing = getEasingFunction(easing)
  340 + checkStartParams(time, subject, target, easing, callback)
  341 + return newTween(time, subject, target, easing, callback, {...})
  342 +end
  343 +
  344 +setmetatable(tween, { __call = function(t, ...) return tween.start(...) end })
  345 +
  346 +function tween.reset(id)
  347 + local tw = tweens[id]
  348 + if tw then
  349 + resetTween(tw)
  350 + tween.stop(tw)
  351 + end
  352 +end
  353 +
  354 +function tween.resetAll(id)
  355 + for _,tw in pairs(tweens) do copyTables(tw.subject, tw.initial) end
  356 + tween.stopAll()
  357 +end
  358 +
  359 +function tween.update(dt)
  360 + assert(type(dt) == 'number' and dt > 0, "dt must be a positive number")
  361 + local expired = {}
  362 + for _,t in pairs(tweens) do
  363 + updateTween(t, dt)
  364 + if hasExpiredTween(t) then table.insert(expired, t) end
  365 + end
  366 + for i=1, #expired do finishTween(expired[i]) end
  367 +end
  368 +
  369 +function tween.stop(id)
  370 + if id~=nil then tweens[id]=nil end
  371 +end
  372 +
  373 +function tween.stopAll()
  374 + tweens = {}
  375 +end
  376 +
  377 +tween.stopAll()
  378 +
  379 +return tween
  380 +
... ...