improvement: rework titlescreen
This commit is contained in:
parent
43eade2369
commit
c3a406ad2c
4 changed files with 627 additions and 7 deletions
88
sonic-bluestreak.love/game/modules/tweenmanager/init.lua
Normal file
88
sonic-bluestreak.love/game/modules/tweenmanager/init.lua
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
local TweenManager = Object:extend()
|
||||||
|
|
||||||
|
local tween = require "game.modules.tweenmanager.libs.tween"
|
||||||
|
local Timer = require "core.modules.world.actors.utils.timer"
|
||||||
|
|
||||||
|
function TweenManager:new(subject)
|
||||||
|
self.subject = subject
|
||||||
|
self.time = 0
|
||||||
|
|
||||||
|
self.tweens = {}
|
||||||
|
self.switches = {}
|
||||||
|
|
||||||
|
self.timers = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:newTween(start, duration, target, easing)
|
||||||
|
local newTween = {}
|
||||||
|
-- we add the data into a tween wrapper
|
||||||
|
newTween.tween = tween.new(duration, self.subject, target, easing)
|
||||||
|
newTween.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
|
||||||
|
newTween.clear = newTween.start + duration
|
||||||
|
|
||||||
|
table.insert(self.tweens, newTween)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:newTimer(start, name)
|
||||||
|
self.timers[name] = Timer(self, name, start)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:newSwitch(start, bools)
|
||||||
|
local newSwitch = {}
|
||||||
|
-- we add the data into a tween wrapper
|
||||||
|
newSwitch.bools = bools
|
||||||
|
newSwitch.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
|
||||||
|
newSwitch.clear = newSwitch.start + 1
|
||||||
|
|
||||||
|
table.insert(self.switches, newSwitch)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:update(dt)
|
||||||
|
self.time = self.time + dt
|
||||||
|
|
||||||
|
for i, tweenWrapper in ipairs(self.tweens) do
|
||||||
|
if (self.time > tweenWrapper.start) then
|
||||||
|
tweenWrapper.tween:update(dt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, switch in ipairs(self.switches) do
|
||||||
|
if (self.time > switch.start) then
|
||||||
|
-- We test each boolean in the switch
|
||||||
|
for i, bool in ipairs(switch.bools) do
|
||||||
|
-- if it's nil, we set it to true
|
||||||
|
if self.subject[bool] == nil then
|
||||||
|
self.subject[bool] = true
|
||||||
|
else
|
||||||
|
-- if it's not nil, we reverse the boolean
|
||||||
|
self.subject[bool] = (self.subject[bool] == false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.remove(self.switches, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, timer in pairs(self.timers) do
|
||||||
|
timer:update(dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:clearEndedTweens()
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:timerResponse(timername)
|
||||||
|
if self.subject.timerResponse == nil then
|
||||||
|
core.debug:warning("tweenmanager", "the subject have no timerResponse function")
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
self.subject:timerResponse(timername)
|
||||||
|
end
|
||||||
|
|
||||||
|
function TweenManager:clearEndedTweens(dt)
|
||||||
|
for i, tweenWrapper in ipairs(self.tweens) do
|
||||||
|
if (self.time > tweenWrapper.clear) then
|
||||||
|
table.remove(self.tweens, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TweenManager
|
367
sonic-bluestreak.love/game/modules/tweenmanager/libs/tween.lua
Normal file
367
sonic-bluestreak.love/game/modules/tweenmanager/libs/tween.lua
Normal file
|
@ -0,0 +1,367 @@
|
||||||
|
local tween = {
|
||||||
|
_VERSION = 'tween 2.1.1',
|
||||||
|
_DESCRIPTION = 'tweening for lua',
|
||||||
|
_URL = 'https://github.com/kikito/tween.lua',
|
||||||
|
_LICENSE = [[
|
||||||
|
MIT LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
|
||||||
|
-- easing
|
||||||
|
|
||||||
|
-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.
|
||||||
|
-- For all easing functions:
|
||||||
|
-- t = time == how much time has to pass for the tweening to complete
|
||||||
|
-- b = begin == starting property value
|
||||||
|
-- c = change == ending - beginning
|
||||||
|
-- d = duration == running time. How much time has passed *right now*
|
||||||
|
|
||||||
|
local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin
|
||||||
|
|
||||||
|
-- linear
|
||||||
|
local function linear(t, b, c, d) return c * t / d + b end
|
||||||
|
|
||||||
|
-- quad
|
||||||
|
local function inQuad(t, b, c, d) return c * pow(t / d, 2) + b end
|
||||||
|
local function outQuad(t, b, c, d)
|
||||||
|
t = t / d
|
||||||
|
return -c * t * (t - 2) + b
|
||||||
|
end
|
||||||
|
local function inOutQuad(t, b, c, d)
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * pow(t, 2) + b end
|
||||||
|
return -c / 2 * ((t - 1) * (t - 3) - 1) + b
|
||||||
|
end
|
||||||
|
local function outInQuad(t, b, c, d)
|
||||||
|
if t < d / 2 then return outQuad(t * 2, b, c / 2, d) end
|
||||||
|
return inQuad((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- cubic
|
||||||
|
local function inCubic (t, b, c, d) return c * pow(t / d, 3) + b end
|
||||||
|
local function outCubic(t, b, c, d) return c * (pow(t / d - 1, 3) + 1) + b end
|
||||||
|
local function inOutCubic(t, b, c, d)
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * t * t * t + b end
|
||||||
|
t = t - 2
|
||||||
|
return c / 2 * (t * t * t + 2) + b
|
||||||
|
end
|
||||||
|
local function outInCubic(t, b, c, d)
|
||||||
|
if t < d / 2 then return outCubic(t * 2, b, c / 2, d) end
|
||||||
|
return inCubic((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- quart
|
||||||
|
local function inQuart(t, b, c, d) return c * pow(t / d, 4) + b end
|
||||||
|
local function outQuart(t, b, c, d) return -c * (pow(t / d - 1, 4) - 1) + b end
|
||||||
|
local function inOutQuart(t, b, c, d)
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * pow(t, 4) + b end
|
||||||
|
return -c / 2 * (pow(t - 2, 4) - 2) + b
|
||||||
|
end
|
||||||
|
local function outInQuart(t, b, c, d)
|
||||||
|
if t < d / 2 then return outQuart(t * 2, b, c / 2, d) end
|
||||||
|
return inQuart((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- quint
|
||||||
|
local function inQuint(t, b, c, d) return c * pow(t / d, 5) + b end
|
||||||
|
local function outQuint(t, b, c, d) return c * (pow(t / d - 1, 5) + 1) + b end
|
||||||
|
local function inOutQuint(t, b, c, d)
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * pow(t, 5) + b end
|
||||||
|
return c / 2 * (pow(t - 2, 5) + 2) + b
|
||||||
|
end
|
||||||
|
local function outInQuint(t, b, c, d)
|
||||||
|
if t < d / 2 then return outQuint(t * 2, b, c / 2, d) end
|
||||||
|
return inQuint((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sine
|
||||||
|
local function inSine(t, b, c, d) return -c * cos(t / d * (pi / 2)) + c + b end
|
||||||
|
local function outSine(t, b, c, d) return c * sin(t / d * (pi / 2)) + b end
|
||||||
|
local function inOutSine(t, b, c, d) return -c / 2 * (cos(pi * t / d) - 1) + b end
|
||||||
|
local function outInSine(t, b, c, d)
|
||||||
|
if t < d / 2 then return outSine(t * 2, b, c / 2, d) end
|
||||||
|
return inSine((t * 2) -d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- expo
|
||||||
|
local function inExpo(t, b, c, d)
|
||||||
|
if t == 0 then return b end
|
||||||
|
return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001
|
||||||
|
end
|
||||||
|
local function outExpo(t, b, c, d)
|
||||||
|
if t == d then return b + c end
|
||||||
|
return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b
|
||||||
|
end
|
||||||
|
local function inOutExpo(t, b, c, d)
|
||||||
|
if t == 0 then return b end
|
||||||
|
if t == d then return b + c end
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 end
|
||||||
|
return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b
|
||||||
|
end
|
||||||
|
local function outInExpo(t, b, c, d)
|
||||||
|
if t < d / 2 then return outExpo(t * 2, b, c / 2, d) end
|
||||||
|
return inExpo((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- circ
|
||||||
|
local function inCirc(t, b, c, d) return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) end
|
||||||
|
local function outCirc(t, b, c, d) return(c * sqrt(1 - pow(t / d - 1, 2)) + b) end
|
||||||
|
local function inOutCirc(t, b, c, d)
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return -c / 2 * (sqrt(1 - t * t) - 1) + b end
|
||||||
|
t = t - 2
|
||||||
|
return c / 2 * (sqrt(1 - t * t) + 1) + b
|
||||||
|
end
|
||||||
|
local function outInCirc(t, b, c, d)
|
||||||
|
if t < d / 2 then return outCirc(t * 2, b, c / 2, d) end
|
||||||
|
return inCirc((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- elastic
|
||||||
|
local function calculatePAS(p,a,c,d)
|
||||||
|
p, a = p or d * 0.3, a or 0
|
||||||
|
if a < abs(c) then return p, c, p / 4 end -- p, a, s
|
||||||
|
return p, a, p / (2 * pi) * asin(c/a) -- p,a,s
|
||||||
|
end
|
||||||
|
local function inElastic(t, b, c, d, a, p)
|
||||||
|
local s
|
||||||
|
if t == 0 then return b end
|
||||||
|
t = t / d
|
||||||
|
if t == 1 then return b + c end
|
||||||
|
p,a,s = calculatePAS(p,a,c,d)
|
||||||
|
t = t - 1
|
||||||
|
return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
|
||||||
|
end
|
||||||
|
local function outElastic(t, b, c, d, a, p)
|
||||||
|
local s
|
||||||
|
if t == 0 then return b end
|
||||||
|
t = t / d
|
||||||
|
if t == 1 then return b + c end
|
||||||
|
p,a,s = calculatePAS(p,a,c,d)
|
||||||
|
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b
|
||||||
|
end
|
||||||
|
local function inOutElastic(t, b, c, d, a, p)
|
||||||
|
local s
|
||||||
|
if t == 0 then return b end
|
||||||
|
t = t / d * 2
|
||||||
|
if t == 2 then return b + c end
|
||||||
|
p,a,s = calculatePAS(p,a,c,d)
|
||||||
|
t = t - 1
|
||||||
|
if t < 0 then return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b end
|
||||||
|
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b
|
||||||
|
end
|
||||||
|
local function outInElastic(t, b, c, d, a, p)
|
||||||
|
if t < d / 2 then return outElastic(t * 2, b, c / 2, d, a, p) end
|
||||||
|
return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- back
|
||||||
|
local function inBack(t, b, c, d, s)
|
||||||
|
s = s or 1.70158
|
||||||
|
t = t / d
|
||||||
|
return c * t * t * ((s + 1) * t - s) + b
|
||||||
|
end
|
||||||
|
local function outBack(t, b, c, d, s)
|
||||||
|
s = s or 1.70158
|
||||||
|
t = t / d - 1
|
||||||
|
return c * (t * t * ((s + 1) * t + s) + 1) + b
|
||||||
|
end
|
||||||
|
local function inOutBack(t, b, c, d, s)
|
||||||
|
s = (s or 1.70158) * 1.525
|
||||||
|
t = t / d * 2
|
||||||
|
if t < 1 then return c / 2 * (t * t * ((s + 1) * t - s)) + b end
|
||||||
|
t = t - 2
|
||||||
|
return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
|
||||||
|
end
|
||||||
|
local function outInBack(t, b, c, d, s)
|
||||||
|
if t < d / 2 then return outBack(t * 2, b, c / 2, d, s) end
|
||||||
|
return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- bounce
|
||||||
|
local function outBounce(t, b, c, d)
|
||||||
|
t = t / d
|
||||||
|
if t < 1 / 2.75 then return c * (7.5625 * t * t) + b end
|
||||||
|
if t < 2 / 2.75 then
|
||||||
|
t = t - (1.5 / 2.75)
|
||||||
|
return c * (7.5625 * t * t + 0.75) + b
|
||||||
|
elseif t < 2.5 / 2.75 then
|
||||||
|
t = t - (2.25 / 2.75)
|
||||||
|
return c * (7.5625 * t * t + 0.9375) + b
|
||||||
|
end
|
||||||
|
t = t - (2.625 / 2.75)
|
||||||
|
return c * (7.5625 * t * t + 0.984375) + b
|
||||||
|
end
|
||||||
|
local function inBounce(t, b, c, d) return c - outBounce(d - t, 0, c, d) + b end
|
||||||
|
local function inOutBounce(t, b, c, d)
|
||||||
|
if t < d / 2 then return inBounce(t * 2, 0, c, d) * 0.5 + b end
|
||||||
|
return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b
|
||||||
|
end
|
||||||
|
local function outInBounce(t, b, c, d)
|
||||||
|
if t < d / 2 then return outBounce(t * 2, b, c / 2, d) end
|
||||||
|
return inBounce((t * 2) - d, b + c / 2, c / 2, d)
|
||||||
|
end
|
||||||
|
|
||||||
|
tween.easing = {
|
||||||
|
linear = linear,
|
||||||
|
inQuad = inQuad, outQuad = outQuad, inOutQuad = inOutQuad, outInQuad = outInQuad,
|
||||||
|
inCubic = inCubic, outCubic = outCubic, inOutCubic = inOutCubic, outInCubic = outInCubic,
|
||||||
|
inQuart = inQuart, outQuart = outQuart, inOutQuart = inOutQuart, outInQuart = outInQuart,
|
||||||
|
inQuint = inQuint, outQuint = outQuint, inOutQuint = inOutQuint, outInQuint = outInQuint,
|
||||||
|
inSine = inSine, outSine = outSine, inOutSine = inOutSine, outInSine = outInSine,
|
||||||
|
inExpo = inExpo, outExpo = outExpo, inOutExpo = inOutExpo, outInExpo = outInExpo,
|
||||||
|
inCirc = inCirc, outCirc = outCirc, inOutCirc = inOutCirc, outInCirc = outInCirc,
|
||||||
|
inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,
|
||||||
|
inBack = inBack, outBack = outBack, inOutBack = inOutBack, outInBack = outInBack,
|
||||||
|
inBounce = inBounce, outBounce = outBounce, inOutBounce = inOutBounce, outInBounce = outInBounce
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- private stuff
|
||||||
|
|
||||||
|
local function copyTables(destination, keysTable, valuesTable)
|
||||||
|
valuesTable = valuesTable or keysTable
|
||||||
|
local mt = getmetatable(keysTable)
|
||||||
|
if mt and getmetatable(destination) == nil then
|
||||||
|
setmetatable(destination, mt)
|
||||||
|
end
|
||||||
|
for k,v in pairs(keysTable) do
|
||||||
|
if type(v) == 'table' then
|
||||||
|
destination[k] = copyTables({}, v, valuesTable[k])
|
||||||
|
else
|
||||||
|
destination[k] = valuesTable[k]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return destination
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkSubjectAndTargetRecursively(subject, target, path)
|
||||||
|
path = path or {}
|
||||||
|
local targetType, newPath
|
||||||
|
for k,targetValue in pairs(target) do
|
||||||
|
targetType, newPath = type(targetValue), copyTables({}, path)
|
||||||
|
table.insert(newPath, tostring(k))
|
||||||
|
if targetType == 'number' then
|
||||||
|
assert(type(subject[k]) == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' is missing from subject or isn't a number")
|
||||||
|
elseif targetType == 'table' then
|
||||||
|
checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
|
||||||
|
else
|
||||||
|
assert(targetType == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' must be a number or table of numbers")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkNewParams(duration, subject, target, easing)
|
||||||
|
assert(type(duration) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration))
|
||||||
|
local tsubject = type(subject)
|
||||||
|
assert(tsubject == 'table' or tsubject == 'userdata', "subject must be a table or userdata. Was " .. tostring(subject))
|
||||||
|
assert(type(target)== 'table', "target must be a table. Was " .. tostring(target))
|
||||||
|
assert(type(easing)=='function', "easing must be a function. Was " .. tostring(easing))
|
||||||
|
checkSubjectAndTargetRecursively(subject, target)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getEasingFunction(easing)
|
||||||
|
easing = easing or "linear"
|
||||||
|
if type(easing) == 'string' then
|
||||||
|
local name = easing
|
||||||
|
easing = tween.easing[name]
|
||||||
|
if type(easing) ~= 'function' then
|
||||||
|
error("The easing function name '" .. name .. "' is invalid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return easing
|
||||||
|
end
|
||||||
|
|
||||||
|
local function performEasingOnSubject(subject, target, initial, clock, duration, easing)
|
||||||
|
local t,b,c,d
|
||||||
|
for k,v in pairs(target) do
|
||||||
|
if type(v) == 'table' then
|
||||||
|
performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing)
|
||||||
|
else
|
||||||
|
t,b,c,d = clock, initial[k], v - initial[k], duration
|
||||||
|
subject[k] = easing(t,b,c,d)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Tween methods
|
||||||
|
|
||||||
|
local Tween = {}
|
||||||
|
local Tween_mt = {__index = Tween}
|
||||||
|
|
||||||
|
function Tween:set(clock)
|
||||||
|
assert(type(clock) == 'number', "clock must be a positive number or 0")
|
||||||
|
|
||||||
|
self.initial = self.initial or copyTables({}, self.target, self.subject)
|
||||||
|
self.clock = clock
|
||||||
|
|
||||||
|
if self.clock <= 0 then
|
||||||
|
|
||||||
|
self.clock = 0
|
||||||
|
copyTables(self.subject, self.initial)
|
||||||
|
|
||||||
|
elseif self.clock >= self.duration then -- the tween has expired
|
||||||
|
|
||||||
|
self.clock = self.duration
|
||||||
|
copyTables(self.subject, self.target)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.clock >= self.duration
|
||||||
|
end
|
||||||
|
|
||||||
|
function Tween:reset()
|
||||||
|
return self:set(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Tween:update(dt)
|
||||||
|
assert(type(dt) == 'number', "dt must be a number")
|
||||||
|
return self:set(self.clock + dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Public interface
|
||||||
|
|
||||||
|
function tween.new(duration, subject, target, easing)
|
||||||
|
easing = getEasingFunction(easing)
|
||||||
|
checkNewParams(duration, subject, target, easing)
|
||||||
|
return setmetatable({
|
||||||
|
duration = duration,
|
||||||
|
subject = subject,
|
||||||
|
target = target,
|
||||||
|
easing = easing,
|
||||||
|
clock = 0
|
||||||
|
}, Tween_mt)
|
||||||
|
end
|
||||||
|
|
||||||
|
return tween
|
122
sonic-bluestreak.love/scenes/titlescreen/background.lua
Normal file
122
sonic-bluestreak.love/scenes/titlescreen/background.lua
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
local Background = Object:extend()
|
||||||
|
|
||||||
|
local zoneList = require("datas.gamedata.maps.shoot.zones")
|
||||||
|
|
||||||
|
function Background:new()
|
||||||
|
self.x1 = 0
|
||||||
|
self.x2 = 0
|
||||||
|
self.x3 = 0
|
||||||
|
self.y = 15
|
||||||
|
|
||||||
|
local randomZoneList = {}
|
||||||
|
for k,v in pairs(zoneList) do
|
||||||
|
table.insert(randomZoneList, k)
|
||||||
|
end
|
||||||
|
local id = math.ceil(love.math.random() * #randomZoneList)
|
||||||
|
self.zone = randomZoneList[id]
|
||||||
|
print(self.zone)
|
||||||
|
self:initRessources()
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:initRessources()
|
||||||
|
self.textureId = zoneList[self.zone].tiles
|
||||||
|
self.background = zoneList[self.zone].background
|
||||||
|
|
||||||
|
self.texture = {}
|
||||||
|
self.texture.floor = self:generateFloor(self.textureId)
|
||||||
|
self.texture.border = love.graphics.newImage("assets/backgrounds/borders.png")
|
||||||
|
self.quads = {}
|
||||||
|
local w, h = self.texture.border:getDimensions()
|
||||||
|
self.quads.borders = love.graphics.newQuad(0, self.textureId*10, 80, 10, w, h)
|
||||||
|
self:addParallax(self.background)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:generateFloor(tile)
|
||||||
|
local canvas = love.graphics.newCanvas(31*16, 100)
|
||||||
|
local tile = tile or 1
|
||||||
|
|
||||||
|
local tileTexture = love.graphics.newImage("assets/backgrounds/normaltile.png")
|
||||||
|
local tileQuad = {}
|
||||||
|
local w, h = tileTexture:getDimensions()
|
||||||
|
tileQuad[1] = love.graphics.newQuad( 0, tile*24, 40, 24, w, h)
|
||||||
|
tileQuad[2] = love.graphics.newQuad(40, tile*24, 40, 24, w, h)
|
||||||
|
|
||||||
|
love.graphics.setCanvas( canvas )
|
||||||
|
|
||||||
|
for i=1, 5 do
|
||||||
|
for j=0, 18 do
|
||||||
|
local tiley = (i-1)*20 - 4
|
||||||
|
local tilex = (j-2)*31 + (i-1)*10
|
||||||
|
local variant = 1 + ((i + j) % 2)
|
||||||
|
love.graphics.draw(tileTexture, tileQuad[variant], tilex, tiley)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setCanvas( )
|
||||||
|
|
||||||
|
local imagedata = canvas:newImageData()
|
||||||
|
local texture = love.graphics.newImage( imagedata )
|
||||||
|
imagedata:release()
|
||||||
|
canvas:release()
|
||||||
|
return texture
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:addParallax(filename)
|
||||||
|
local filename = filename or "forest"
|
||||||
|
local backfolder = "assets/backgrounds/parallax/"
|
||||||
|
filename = backfolder .. filename
|
||||||
|
self.texture.back1 = love.graphics.newImage(filename .. "-back.png")
|
||||||
|
self.texture.back2 = love.graphics.newImage(filename .. "-fore.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:update(dt)
|
||||||
|
local w, h = core.screen:getDimensions()
|
||||||
|
self.x1 = (self.x1 + 10*dt)
|
||||||
|
self.x2 = (self.x2 + 20*dt)
|
||||||
|
self.x3 = (self.x3 + 30*dt)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:draw()
|
||||||
|
self:drawTiled(self.texture.back1, self.x1, 0, false)
|
||||||
|
self:drawTiled(self.texture.back2, self.x2, 95, true)
|
||||||
|
self:drawQuadTiled(self.texture.border, self.quads.borders, self.x3, 95, false)
|
||||||
|
self:drawTiled(self.texture.floor, self.x3, 105, false)
|
||||||
|
self:drawQuadTiled(self.texture.border, self.quads.borders, self.x3, 205, false)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:drawTiled(drawable, x, y, fromBottom)
|
||||||
|
local w, h = drawable:getDimensions()
|
||||||
|
local screewn, _ = core.screen:getDimensions()
|
||||||
|
local x = math.floor(x % w)
|
||||||
|
|
||||||
|
local fromBottom = fromBottom or false
|
||||||
|
local oy = 0
|
||||||
|
if (fromBottom) then
|
||||||
|
oy = h
|
||||||
|
end
|
||||||
|
|
||||||
|
local imax = math.ceil(screewn / w) + 1
|
||||||
|
for i=0, imax do
|
||||||
|
love.graphics.draw(drawable, (i*w) - x, self.y + y, 0, 1, 1, 0, oy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Background:drawQuadTiled(drawable, quad, x, y, fromBottom)
|
||||||
|
local w, h = drawable:getDimensions()
|
||||||
|
local screewn, _ = core.screen:getDimensions()
|
||||||
|
local x = math.floor(x % w)
|
||||||
|
|
||||||
|
local fromBottom = fromBottom or false
|
||||||
|
local oy = 0
|
||||||
|
if (fromBottom) then
|
||||||
|
local oy = h
|
||||||
|
end
|
||||||
|
|
||||||
|
local imax = math.ceil(screewn / w) + 1
|
||||||
|
for i=0, imax do
|
||||||
|
love.graphics.draw(drawable, quad, (i*w) - x, self.y + y, 0, 1, 1, 0, oy)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Background
|
|
@ -25,31 +25,74 @@ local Scene = require "core.modules.scenes"
|
||||||
local TitleScreen = Scene:extend()
|
local TitleScreen = Scene:extend()
|
||||||
local gui = require "game.modules.gui"
|
local gui = require "game.modules.gui"
|
||||||
|
|
||||||
|
local TweenManager = require "game.modules.tweenmanager"
|
||||||
|
local Background = require "scenes.titlescreen.background"
|
||||||
|
|
||||||
function TitleScreen:new()
|
function TitleScreen:new()
|
||||||
TitleScreen.super.new(self)
|
TitleScreen.super.new(self)
|
||||||
|
|
||||||
self.borders = gui.newBorder(424, 30, 8)
|
self.borders = gui.newBorder(424, 30, 8)
|
||||||
self.assets:addImage("background", "assets/backgrounds/titlescreen.png")
|
|
||||||
self.assets:addImage("sonic", "assets/artworks/titlescreen_sonic.png")
|
self.assets:addImage("sonic", "assets/artworks/titlescreen_sonic.png")
|
||||||
self.assets:addImage("logo", "assets/artworks/logo.png")
|
self.assets:addImage("logo", "assets/artworks/logo.png")
|
||||||
|
self.assets:addImageFont("menu", "assets/gui/fonts/SA2font")
|
||||||
|
|
||||||
|
self.tweens = TweenManager(self)
|
||||||
|
self.background = Background(self)
|
||||||
|
|
||||||
|
self.borderY = 0
|
||||||
|
self.logoX = 270
|
||||||
|
self.sonicX = -180
|
||||||
|
|
||||||
|
self.darkenOpacity = 1
|
||||||
|
self.flashOpacity = 0
|
||||||
|
self.canShowPressStart = false
|
||||||
|
self.showPressStart = true
|
||||||
|
self.showPressStartTimer = 0.5
|
||||||
|
|
||||||
|
self.tweens:newTween(0.2, 0.5, {borderY = 30}, "inOutQuart")
|
||||||
|
self.tweens:newTween(0.5, 0.4, {darkenOpacity = 0}, "outExpo")
|
||||||
|
self.tweens:newTween(0.7, 0.6, {logoX = 0}, "inOutQuart")
|
||||||
|
self.tweens:newTween(0.7, 0.6, {sonicX = 0}, "inOutQuart")
|
||||||
|
self.tweens:newTween(1.3, 0.03, {flashOpacity = 1}, "inQuart")
|
||||||
|
self.tweens:newTween(1.45, 0.2, {flashOpacity = 0}, "outExpo")
|
||||||
|
self.tweens:newSwitch(1.4, { "canShowPressStart" })
|
||||||
self:register()
|
self:register()
|
||||||
end
|
end
|
||||||
|
|
||||||
function TitleScreen:update(dt)
|
function TitleScreen:update(dt)
|
||||||
|
self.tweens:update(dt)
|
||||||
|
self.background:update(dt)
|
||||||
|
if (self.canShowPressStart) then
|
||||||
|
self.showPressStartTimer = self.showPressStartTimer - dt
|
||||||
|
if self.showPressStartTimer < 0 then
|
||||||
|
self.showPressStart = (self.showPressStart == false)
|
||||||
|
self.showPressStartTimer = 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function TitleScreen:draw()
|
function TitleScreen:draw()
|
||||||
utils.graphics.resetColor()
|
utils.graphics.resetColor()
|
||||||
self.assets:drawImage("background", 0, 0)
|
self.background:draw()
|
||||||
|
|
||||||
love.graphics.draw(self.borders, 0, 25, 0, 1, -1)
|
love.graphics.setColor(0, 0, 0, self.darkenOpacity)
|
||||||
love.graphics.draw(self.borders, 424, 215, 0, -1, 1)
|
love.graphics.rectangle("fill", 0, 0, 424, 240)
|
||||||
|
utils.graphics.resetColor( )
|
||||||
|
|
||||||
self.assets:drawImage("sonic", 90, 128, 0, 1, 1, 92, 106)
|
love.graphics.draw(self.borders, 0, self.borderY, 0, 1, -1)
|
||||||
self.assets:drawImage("logo", 290, 60, 0, 1, 1, 150, 71)
|
love.graphics.draw(self.borders, 424, 240 - self.borderY, 0, -1, 1)
|
||||||
|
|
||||||
|
self.assets:drawImage("sonic", 90 + self.sonicX, 128, 0, 1, 1, 92, 106)
|
||||||
|
self.assets:drawImage("logo", 290 + self.logoX, 60, 0, 1, 1, 150, 71)
|
||||||
|
|
||||||
|
if (self.canShowPressStart) and (self.showPressStart) then
|
||||||
|
local w = self.assets.fonts["menu"]:getWidth("PRESS START")
|
||||||
|
self.assets.fonts["menu"]:print("PRESS START", 424/1.5, 240/1.5, "center", 0, 1, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setColor(1, 1, 1, self.flashOpacity)
|
||||||
|
love.graphics.rectangle("fill", 0, 0, 424, 240)
|
||||||
|
utils.graphics.resetColor( )
|
||||||
end
|
end
|
||||||
|
|
||||||
return TitleScreen
|
return TitleScreen
|
||||||
|
|
Loading…
Reference in a new issue