Estructura DX i escena logo JAILGAMES animada
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
-- Escena 'logo' — splash JAILGAMES amb animacio.
|
||||
--
|
||||
-- Tres fases:
|
||||
-- ENTRADA -> les 9 lletres entren des de direccions diferents
|
||||
-- (esquerra, dreta, dalt, baix), esglaonades, amb easings
|
||||
-- variats. Una vegada al lloc, queden quietes.
|
||||
-- ESTABLE -> 4 s totalment quiet, logo blanc ple.
|
||||
-- FADE_OUT -> rampa combinada char+paleta de 8 nivells:
|
||||
-- blanc -> groc -> rosa -> vermell -> magenta -> blau
|
||||
-- -> gris fosc -> negre, mentre el char passa de BLOCK
|
||||
-- -> SHADE_75 -> SHADE_50 -> SHADE_25 -> espai.
|
||||
--
|
||||
-- Premer tecla durant ENTRADA o ESTABLE salta al fade. Quan acaba el
|
||||
-- fade, salta a 'titol'.
|
||||
--
|
||||
-- Notes sobre el fade CGA: no recorrem els 16 indexs en ordre lineal.
|
||||
-- Triem una rampa tematica (warm -> cool -> dark) que es el patro
|
||||
-- classic d'apagada de monitor CRT, combinada amb difuminat del char
|
||||
-- per a mes pasos perceptuals (l'ull veu el conjunt com una rampa
|
||||
-- d'intensitat continua).
|
||||
|
||||
local M = {}
|
||||
|
||||
local logo = dofile("pepe_pintor_dx/data/logo.lua")
|
||||
local easing = dofile("pepe_pintor_dx/lib/easing.lua")
|
||||
|
||||
-- Timings
|
||||
local T_PREVI = 1.0 -- pantalla negra abans que comencin a entrar
|
||||
local T_FALL = 0.65 -- durada de l'entrada d'una lletra
|
||||
local T_DELAY = 0.09 -- delay entre lletres consecutives
|
||||
local T_ESTABLE = 2.0
|
||||
local T_FADE = 0.4
|
||||
local T_POST = 1.0 -- pantalla negra despres del fade, abans de saltar
|
||||
|
||||
local FASE_ENTRADA = 1
|
||||
local FASE_ESTABLE = 2
|
||||
local FASE_FADE_OUT = 3
|
||||
local FASE_POST = 4
|
||||
|
||||
-- Lletres del logo com a rangs de columnes del bitmap 35-wide (1-based).
|
||||
local SEGMENTS = {
|
||||
{ c0 = 1, c1 = 3, nom = "J" },
|
||||
{ c0 = 5, c1 = 7, nom = "A" },
|
||||
{ c0 = 9, c1 = 9, nom = "I" },
|
||||
{ c0 = 11, c1 = 13, nom = "L" },
|
||||
{ c0 = 15, c1 = 17, nom = "G" },
|
||||
{ c0 = 19, c1 = 21, nom = "A" },
|
||||
{ c0 = 23, c1 = 27, nom = "M" },
|
||||
{ c0 = 29, c1 = 31, nom = "E" },
|
||||
{ c0 = 33, c1 = 35, nom = "S" },
|
||||
}
|
||||
|
||||
-- Origen i easing per lletra. (dx, dy) son l'offset inicial respecte
|
||||
-- a la posicio final. fn es l'easing a aplicar al progres [0,1].
|
||||
-- Esquerra del logo (1-3) ve de l'esquerra; centre (4-6) ve vertical;
|
||||
-- dreta (7-9) ve de la dreta. Simetric pero no monoton.
|
||||
local ORIGENS = {}
|
||||
local function inicialitza_origens()
|
||||
ORIGENS = {
|
||||
{ dx = -32, dy = 0, fn = easing.outCubic }, -- J <-
|
||||
{ dx = -28, dy = 0, fn = easing.outCubic }, -- A <-
|
||||
{ dx = -24, dy = 0, fn = easing.outCubic }, -- I <-
|
||||
{ dx = 0, dy = -18, fn = easing.outBounce }, -- L v
|
||||
{ dx = 0, dy = 20, fn = easing.outBack }, -- G ^
|
||||
{ dx = 0, dy = -18, fn = easing.outBounce }, -- A v
|
||||
{ dx = 24, dy = 0, fn = easing.outCubic }, -- M ->
|
||||
{ dx = 28, dy = 0, fn = easing.outCubic }, -- E ->
|
||||
{ dx = 32, dy = 0, fn = easing.outCubic }, -- S ->
|
||||
}
|
||||
end
|
||||
|
||||
-- Rampa de fade: 8 nivells. Construida a entra() perque depen de
|
||||
-- glyphs.* (no disponibles al carregar el modul).
|
||||
local RAMPA
|
||||
local NIVELL_MAX = 7
|
||||
|
||||
local function inicialitza_rampa(glyphs)
|
||||
RAMPA = {
|
||||
[7] = { codi = glyphs.BLOCK, ink = COLOR_WHITE },
|
||||
[6] = { codi = glyphs.BLOCK, ink = COLOR_YELLOW },
|
||||
[5] = { codi = glyphs.SHADE_75, ink = COLOR_LIGHT_RED },
|
||||
[4] = { codi = glyphs.SHADE_75, ink = COLOR_RED },
|
||||
[3] = { codi = glyphs.SHADE_50, ink = COLOR_MAGENTA },
|
||||
[2] = { codi = glyphs.SHADE_50, ink = COLOR_BLUE },
|
||||
[1] = { codi = glyphs.SHADE_25, ink = COLOR_BLUE },
|
||||
[0] = { codi = 32, ink = COLOR_BLACK },
|
||||
}
|
||||
end
|
||||
|
||||
local manager, input, glyphs
|
||||
local lletres = {}
|
||||
local fase = FASE_ENTRADA
|
||||
local temps = 0
|
||||
local nivell_actual = NIVELL_MAX
|
||||
local total_entrada = 0
|
||||
|
||||
local function construeix_lletres()
|
||||
lletres = {}
|
||||
for i, seg in ipairs(SEGMENTS) do
|
||||
local px = {}
|
||||
for r = 1, logo.height do
|
||||
local fila = logo.files[r]
|
||||
for c = seg.c0, seg.c1 do
|
||||
if string.sub(fila, c, c) == "#" then
|
||||
px[#px + 1] = { rx = c - seg.c0, ry = r - 1 }
|
||||
end
|
||||
end
|
||||
end
|
||||
local origen = ORIGENS[i]
|
||||
lletres[i] = {
|
||||
base_x = logo.origen_x + (seg.c0 - 1),
|
||||
base_y = logo.origen_y,
|
||||
pixels = px,
|
||||
ox = origen.dx,
|
||||
oy = origen.dy,
|
||||
dx = origen.dx,
|
||||
dy = origen.dy,
|
||||
fn = origen.fn,
|
||||
delay = T_PREVI + (i - 1) * T_DELAY,
|
||||
arribada = false, -- una vegada true, ja no toquem dx/dy
|
||||
}
|
||||
end
|
||||
total_entrada = T_PREVI + (#SEGMENTS - 1) * T_DELAY + T_FALL
|
||||
end
|
||||
|
||||
function M.entra(servicis, _args)
|
||||
manager = servicis.manager
|
||||
input = servicis.input
|
||||
glyphs = servicis.glyphs
|
||||
|
||||
fase = FASE_ENTRADA
|
||||
temps = 0
|
||||
nivell_actual = NIVELL_MAX
|
||||
|
||||
inicialitza_origens()
|
||||
inicialitza_rampa(glyphs)
|
||||
construeix_lletres()
|
||||
|
||||
color(COLOR_WHITE, COLOR_BLACK)
|
||||
cls()
|
||||
end
|
||||
|
||||
local function salta_a_fade()
|
||||
fase = FASE_FADE_OUT
|
||||
temps = 0
|
||||
-- forcem que totes les lletres estiguin a casa, no es mouen mes
|
||||
for _, l in ipairs(lletres) do
|
||||
l.dx = 0
|
||||
l.dy = 0
|
||||
l.arribada = true
|
||||
end
|
||||
end
|
||||
|
||||
local function update_entrada()
|
||||
local totes_acabades = true
|
||||
for _, l in ipairs(lletres) do
|
||||
if not l.arribada then
|
||||
local tl = temps - l.delay
|
||||
if tl < 0 then
|
||||
l.dx, l.dy = l.ox, l.oy
|
||||
totes_acabades = false
|
||||
elseif tl < T_FALL then
|
||||
local p = tl / T_FALL
|
||||
local e = l.fn(p)
|
||||
l.dx = l.ox * (1 - e)
|
||||
l.dy = l.oy * (1 - e)
|
||||
totes_acabades = false
|
||||
else
|
||||
l.dx, l.dy = 0, 0
|
||||
l.arribada = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if totes_acabades then
|
||||
fase = FASE_ESTABLE
|
||||
temps = 0
|
||||
end
|
||||
end
|
||||
|
||||
local function update_estable()
|
||||
-- intencionadament buit — lletres quietes
|
||||
if temps >= T_ESTABLE then
|
||||
salta_a_fade()
|
||||
end
|
||||
end
|
||||
|
||||
local function update_fade()
|
||||
local p = temps / T_FADE
|
||||
if p >= 1 then
|
||||
nivell_actual = 0
|
||||
fase = FASE_POST
|
||||
temps = 0
|
||||
return
|
||||
end
|
||||
-- Mapa el progres [0,1] al nivell [NIVELL_MAX..0] de la rampa.
|
||||
nivell_actual = math.floor(NIVELL_MAX * (1 - p) + 0.5)
|
||||
if nivell_actual < 0 then nivell_actual = 0 end
|
||||
end
|
||||
|
||||
local function update_post()
|
||||
if temps >= T_POST then
|
||||
manager.canvia("titol")
|
||||
end
|
||||
end
|
||||
|
||||
function M.update(dt)
|
||||
temps = temps + dt
|
||||
|
||||
if (fase == FASE_ENTRADA or fase == FASE_ESTABLE) and input.qualsevol_tecla() then
|
||||
salta_a_fade()
|
||||
return
|
||||
end
|
||||
|
||||
if fase == FASE_ENTRADA then
|
||||
update_entrada()
|
||||
elseif fase == FASE_ESTABLE then
|
||||
update_estable()
|
||||
elseif fase == FASE_FADE_OUT then
|
||||
update_fade()
|
||||
else
|
||||
update_post()
|
||||
end
|
||||
end
|
||||
|
||||
function M.draw()
|
||||
color(COLOR_WHITE, COLOR_BLACK)
|
||||
cls()
|
||||
|
||||
local nivell
|
||||
if fase == FASE_FADE_OUT or fase == FASE_POST then
|
||||
nivell = nivell_actual
|
||||
else
|
||||
nivell = NIVELL_MAX
|
||||
end
|
||||
if nivell <= 0 then return end
|
||||
|
||||
local conf = RAMPA[nivell]
|
||||
color(conf.ink, COLOR_BLACK)
|
||||
|
||||
for _, l in ipairs(lletres) do
|
||||
local ox = math.floor(l.dx + 0.5)
|
||||
local oy = math.floor(l.dy + 0.5)
|
||||
for _, p in ipairs(l.pixels) do
|
||||
local x = l.base_x + p.rx + ox
|
||||
local y = l.base_y + p.ry + oy
|
||||
if x >= 0 and x < 40 and y >= 0 and y < 30 then
|
||||
print(chr(conf.codi), x, y)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user