DX: contador animat, fades, mort animada i escala creixent
This commit is contained in:
+19
@@ -78,3 +78,22 @@ skin = "native"
|
||||
-- textos.record_label = "Record"
|
||||
-- textos.name_label = "Nom:"
|
||||
-- textos.name_help = "(A-Z)"
|
||||
|
||||
-- ====================================================================
|
||||
-- TEMPS I DURACIONS
|
||||
-- ====================================================================
|
||||
-- Tots els valors van en *frames* (a 60 fps, 60 frames = 1 segon).
|
||||
-- Pots ajustar la sensacio del joc sense tocar el .lua.
|
||||
|
||||
-- temps.score_step = 3 -- frames per cada +1 del comptador
|
||||
-- -- animat del HUD. 3 = ~20 punts/segon.
|
||||
-- temps.fade_frames = 18 -- duracio del fade out (i del fade in)
|
||||
-- -- entre pantalles. 18 = 0.3 s per fase.
|
||||
-- temps.mort_anim_frames = 30 -- duracio de l'animacio visual de mort
|
||||
-- -- (Pepe parpadejant + careta trista).
|
||||
-- temps.respawn_delay_frames = 120 -- temps que Pepe queda invisible abans
|
||||
-- -- del respawn (els malos segueixen).
|
||||
-- temps.invuln_frames = 180 -- temps que Pepe es invulnerable al
|
||||
-- -- respawn, parpadejant blanc/groc.
|
||||
-- temps.escala_step_frames = 6 -- frames entre cada cel·la nova de
|
||||
-- -- l'escala lateral quan creix.
|
||||
|
||||
+275
-67
@@ -30,6 +30,10 @@ FRAME_TR = 243
|
||||
FRAME_BL = 244
|
||||
FRAME_BR = 245
|
||||
|
||||
-- Glif dedicat al fade (bloc 100% solid). Definit fora dels SKINS per a que
|
||||
-- funcione igual en custom i native, sense dependre del ROM nadiu.
|
||||
FADE_BLOCK = 246
|
||||
|
||||
-- Skins: cada skin es una taula tile_id → codi_de_glif_a_pintar.
|
||||
-- "custom" usa els mateixos codis CP437 (redibuixats amb setchar).
|
||||
-- "native" remapeja als glifs que ja existeixen al ROM d'ascii
|
||||
@@ -113,6 +117,17 @@ MALO_RATIO = 4 -- els malos van 1/4 del ritme del Pepe (com en RUNNER.PAS)
|
||||
NUM_FASES = 10 -- mapes 1..10 (el 0 esta reservat per al titol)
|
||||
VIDES_INI = 3 -- l'original arrancava amb 0 (1 vida); 3 es mes raonable
|
||||
|
||||
-- Tots els temps i durations de les animacions del DX. Sobreescriuibles
|
||||
-- per config.lua (en frames a 60 fps; 60 = 1 segon).
|
||||
temps = {
|
||||
score_step = 3, -- frames per cada +1 del comptador animat (60/3 = 20 pts/s)
|
||||
fade_frames = 18, -- duracio de cada fase del fade (out i in son simetrics)
|
||||
mort_anim_frames = 30, -- duracio de l'animacio de mort (Pepe visible, 0.5 s)
|
||||
respawn_delay_frames = 120, -- temps que Pepe queda invisible abans del respawn (2 s)
|
||||
invuln_frames = 180, -- temps invulnerable despres del respawn (3 s)
|
||||
escala_step_frames = 6, -- frames entre cada cel·la nova de l'escala lateral (0.1 s)
|
||||
}
|
||||
|
||||
-- Estats del joc (maquina d'estats global)
|
||||
ESTAT_TITLE = "title"
|
||||
ESTAT_PLAYING = "playing"
|
||||
@@ -122,9 +137,11 @@ ESTAT_ENTERNAME = "entername"
|
||||
-- Estat global
|
||||
mapa = {} -- mapa[x][y] = { tipo=, color=, temps= }
|
||||
level = 1
|
||||
pepe = { x=19, y=23, dibuix=PEPE_C, color=colors.pepe, vides=VIDES_INI, estat=NORMAL }
|
||||
pepe = { x=19, y=23, dibuix=PEPE_C, color=colors.pepe, vides=VIDES_INI, estat=NORMAL,
|
||||
mort_t=0, invuln_t=0 }
|
||||
malos = {}
|
||||
score = 0
|
||||
score_display = 0 -- valor pintat al HUD; va alcançant a score animadament
|
||||
diners_pantalla = 0
|
||||
game_tic = 0
|
||||
hi_score = 0
|
||||
@@ -132,6 +149,26 @@ nom_hi_score = "AAA"
|
||||
estat_joc = ESTAT_TITLE
|
||||
estat_inici = 0
|
||||
enter_name_idx = 1
|
||||
fade = nil -- nil = sense transicio; o { phase="out"|"in", t=0, on_mid=... }
|
||||
|
||||
-- Estat de l'animacio de l'escala lateral (apareix quan no queden diners).
|
||||
-- "idle" → encara no s'ha disparat per a este mapa
|
||||
-- "growing" → en curs: cada escala_step_frames apareix una cel·la nova
|
||||
-- "done" → ja arribada al final (col 0 plena fins a pedra o fila 23)
|
||||
escala_state = "idle"
|
||||
escala_y = 1 -- proxima fila a omplir
|
||||
escala_t = 0 -- comptador de frames entre cel·les
|
||||
|
||||
-- Matriu 4x4 de Bayer (0..15). El llindar es la proporcio coberta del fade:
|
||||
-- una cel·la (x,y) es cobrix amb bloc solid bg si bayer[x%4][y%4] < progress (0..16).
|
||||
-- Al ser 4x4 i tindre tots els valors 0..15, dona 16 nivells de cobertura
|
||||
-- amb un patro de dither ordenat (no aleatori), molt mes natural visualment.
|
||||
BAYER4 = {
|
||||
{ 0, 8, 2, 10 },
|
||||
{ 12, 4, 14, 6 },
|
||||
{ 3, 11, 1, 9 },
|
||||
{ 15, 7, 13, 5 },
|
||||
}
|
||||
|
||||
function definir_glifs()
|
||||
-- Char 0 sempre buit (el ROM d'ascii hi te una caixa que taparia el mapa)
|
||||
@@ -160,12 +197,63 @@ function definir_marc()
|
||||
setchar(FRAME_TR, 0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18) -- ┐
|
||||
setchar(FRAME_BL, 0x18,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00) -- └
|
||||
setchar(FRAME_BR, 0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00) -- ┘
|
||||
setchar(FADE_BLOCK, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF) -- █ solid per al fade
|
||||
end
|
||||
|
||||
-- ====================================================================
|
||||
-- TRANSICIONS (fade out + canvi d'estat + fade in)
|
||||
-- ====================================================================
|
||||
-- El "fade" es un dither ordenat (Bayer 4x4) en color de fons: cada cel·la
|
||||
-- es cobrix amb un bloc solid quan el seu llindar es supera. Aixi simula
|
||||
-- un fade out sense necessitar paleta runtime (que ascii no te).
|
||||
|
||||
function fade_actiu() return fade ~= nil end
|
||||
|
||||
-- Inicia una transicio: fade_out → executa on_mid (canvi d'estat) → fade_in.
|
||||
-- Mentre fade_actiu(), els estats no han de processar input ni logica;
|
||||
-- nomes renderitzen el seu frame, i el dither es pinta a sobre.
|
||||
function transicio(on_mid)
|
||||
fade = { phase="out", t=0, on_mid=on_mid }
|
||||
end
|
||||
|
||||
function update_fade()
|
||||
if not fade then return end
|
||||
fade.t = fade.t + 1
|
||||
if fade.phase == "out" and fade.t >= temps.fade_frames then
|
||||
local cb = fade.on_mid
|
||||
fade = { phase="in", t=0 }
|
||||
if cb then cb() end
|
||||
elseif fade.phase == "in" and fade.t >= temps.fade_frames then
|
||||
fade = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Pinta el dither encima del render actual. progress va de 0 (descobert)
|
||||
-- a 16 (totalment cobert). En fade_out puja, en fade_in baixa.
|
||||
function pintar_fade()
|
||||
if not fade then return end
|
||||
local progress
|
||||
if fade.phase == "out" then
|
||||
progress = flr(fade.t * 16 / temps.fade_frames)
|
||||
else
|
||||
progress = 16 - flr(fade.t * 16 / temps.fade_frames)
|
||||
end
|
||||
if progress <= 0 then return end
|
||||
color(colors.bg, colors.bg)
|
||||
for y = 0, 29 do
|
||||
for x = 0, 39 do
|
||||
if BAYER4[(x % 4) + 1][(y % 4) + 1] < progress then
|
||||
print(chr(FADE_BLOCK), x, y)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ====================================================================
|
||||
-- SFX (l'original no tenia so — afegim els minims raonables)
|
||||
-- ====================================================================
|
||||
function sfx_coin() sound(2000, 40) end
|
||||
function sfx_escala_step(y) sound(400 + y * 40, 4) end
|
||||
function sfx_dig() play("l0o2c") end
|
||||
function sfx_die() play("l1o4cl0o3bagfed") end
|
||||
function sfx_malo_die() play("l0o3ao4c") end
|
||||
@@ -204,6 +292,10 @@ function carregar_mapa(num)
|
||||
if tipo == DINERS then diners_pantalla = diners_pantalla + 1 end
|
||||
end
|
||||
end
|
||||
-- Reset de l'animacio de l'escala per al nou mapa
|
||||
escala_state = "idle"
|
||||
escala_y = 1
|
||||
escala_t = 0
|
||||
end
|
||||
|
||||
-- offset_x permet desplacar tot el mapa horitzontalment al pintar
|
||||
@@ -226,8 +318,33 @@ function pintar_mapa(offset_x)
|
||||
end
|
||||
|
||||
function pintar_pepe()
|
||||
color(pepe.color, colors.bg)
|
||||
print(chr(glif[pepe.dibuix]), pepe.x, pepe.y)
|
||||
local col = pepe.color
|
||||
local g = glif[pepe.dibuix]
|
||||
|
||||
if pepe.mort_t > 0 then
|
||||
-- Fase d'espera (Pepe invisible, mapa segueix viu): no pintem res.
|
||||
if pepe.mort_t <= temps.respawn_delay_frames then return end
|
||||
|
||||
-- Animacio visual de mort, en dos trams desproporcionats (1/4 + 3/4):
|
||||
-- tram curt: parpadeja blanc/roig amb la cara normal del Pepe.
|
||||
-- tram llarg: glif passa a la careta trista (codi 225 del ROM
|
||||
-- d'ascii, no redefinit per cap skin) parpadejant roig/bg.
|
||||
local fase = (temps.mort_anim_frames + temps.respawn_delay_frames)
|
||||
- pepe.mort_t -- 0..mort_anim_frames-1
|
||||
local tram_curt = flr(temps.mort_anim_frames / 4)
|
||||
if fase < tram_curt then
|
||||
col = (fase % 6 < 3) and colors.malo or colors.pepe
|
||||
else
|
||||
g = 225
|
||||
col = ((fase - tram_curt) % 12 < 6) and colors.malo or colors.bg
|
||||
end
|
||||
elseif pepe.invuln_t > 0 then
|
||||
-- Invulnerabilitat: parpadeja entre blanc i groc cada 6 frames.
|
||||
col = (pepe.invuln_t % 12 < 6) and colors.pepe or colors.diners
|
||||
end
|
||||
|
||||
color(col, colors.bg)
|
||||
print(chr(g), pepe.x, pepe.y)
|
||||
end
|
||||
|
||||
-- Marca una cel·la com a forat (sols si actualment es pedra)
|
||||
@@ -277,7 +394,8 @@ function tic_pepe()
|
||||
|
||||
-- Final pantalla: si arriba a la fila 1, passa al nivel seguent
|
||||
if pepe.y == 1 then
|
||||
fase_nova()
|
||||
sfx_level()
|
||||
transicio(function() fase_nova() end)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -313,33 +431,47 @@ function tic_pepe()
|
||||
if pepe.y > MAP_H-1 then pepe.y = MAP_H-1 end
|
||||
end
|
||||
|
||||
-- Inicia l'animacio de mort. El timer mort_t cobreix dos trams seguits:
|
||||
-- [delay+1 .. delay+anim] → animacio visual de Pepe morint
|
||||
-- [1 .. delay] → Pepe invisible, mapa segueix viu (pausa)
|
||||
-- Al arribar a 0, update_playing descompta vida i fa el respawn.
|
||||
-- Guarda contra reentrada per a no reiniciar si ja esta morint.
|
||||
function mort_pepe()
|
||||
pepe.vides = pepe.vides - 1
|
||||
if pepe.mort_t > 0 then return end
|
||||
pepe.mort_t = temps.mort_anim_frames + temps.respawn_delay_frames
|
||||
sfx_die()
|
||||
end
|
||||
|
||||
-- Reposiciona Pepe al spawn i activa la invulnerabilitat.
|
||||
function respawn_pepe()
|
||||
pepe.x = 19
|
||||
pepe.y = 23
|
||||
pepe.estat = NORMAL
|
||||
sfx_die()
|
||||
pepe.invuln_t = temps.invuln_frames
|
||||
end
|
||||
|
||||
-- Inicialitza tot per a una nova partida (reset complet)
|
||||
function inicialitzacio()
|
||||
level = 1
|
||||
score = 0
|
||||
score_display = 0
|
||||
pepe.vides = VIDES_INI
|
||||
pepe.x = 19; pepe.y = 23; pepe.estat = NORMAL
|
||||
pepe.mort_t = 0
|
||||
pepe.invuln_t = 0
|
||||
carregar_mapa(level)
|
||||
init_malos()
|
||||
game_tic = 0
|
||||
end
|
||||
|
||||
-- Avanca al nivell seguent (sense reset de score ni vides)
|
||||
-- Avanca al nivell seguent (sense reset de score ni vides).
|
||||
-- sfx_level() es dispara abans de la transicio, no aci dins.
|
||||
function fase_nova()
|
||||
level = level + 1
|
||||
if level > NUM_FASES then level = 1 end
|
||||
pepe.x = 19; pepe.y = 23; pepe.estat = NORMAL
|
||||
carregar_mapa(level)
|
||||
init_malos()
|
||||
sfx_level()
|
||||
end
|
||||
|
||||
-- ====================================================================
|
||||
@@ -403,17 +535,18 @@ function init_title()
|
||||
end
|
||||
|
||||
function update_title()
|
||||
if btnp(KEY_SPACE) then
|
||||
inicialitzacio()
|
||||
set_estat(ESTAT_PLAYING)
|
||||
return
|
||||
if not fade_actiu() and btnp(KEY_SPACE) then
|
||||
transicio(function()
|
||||
inicialitzacio()
|
||||
set_estat(ESTAT_PLAYING)
|
||||
end)
|
||||
end
|
||||
|
||||
neteja_fons()
|
||||
pintar_mapa(1) -- desplacem +1 col per a centrar el logo de map 0
|
||||
|
||||
-- Missatge parpadejant (textos.title_press_play)
|
||||
if flr(cnt() / 30) % 2 == 0 then
|
||||
-- Missatge parpadejant (textos.title_press_play); ocult durant el fade
|
||||
if not fade_actiu() and flr(cnt() / 30) % 2 == 0 then
|
||||
color(COLOR_WHITE, colors.bg)
|
||||
local t = textos.title_press_play
|
||||
print(t, flr((40 - strlen(t)) / 2), 22)
|
||||
@@ -436,16 +569,20 @@ function update_gameover()
|
||||
|
||||
pintar_hud()
|
||||
|
||||
-- Despres de 2 segons (120 frames), transicio
|
||||
if temps_estat() > 120 then
|
||||
-- Despres de 2 segons (120 frames), transicio a title o entername
|
||||
if not fade_actiu() and temps_estat() > 120 then
|
||||
if score > hi_score then
|
||||
hi_score = score
|
||||
nom_hi_score = "AAA"
|
||||
enter_name_idx = 1
|
||||
set_estat(ESTAT_ENTERNAME)
|
||||
transicio(function()
|
||||
hi_score = score
|
||||
nom_hi_score = "AAA"
|
||||
enter_name_idx = 1
|
||||
set_estat(ESTAT_ENTERNAME)
|
||||
end)
|
||||
else
|
||||
init_title()
|
||||
set_estat(ESTAT_TITLE)
|
||||
transicio(function()
|
||||
init_title()
|
||||
set_estat(ESTAT_TITLE)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -466,6 +603,8 @@ function update_entername()
|
||||
|
||||
pintar_hud()
|
||||
|
||||
if fade_actiu() then return end
|
||||
|
||||
local lletra = lletra_pulsada()
|
||||
if lletra then
|
||||
nom_hi_score = string.sub(nom_hi_score, 1, enter_name_idx-1)
|
||||
@@ -473,46 +612,74 @@ function update_entername()
|
||||
string.sub(nom_hi_score, enter_name_idx+1)
|
||||
enter_name_idx = enter_name_idx + 1
|
||||
if enter_name_idx > 3 then
|
||||
guardar_records()
|
||||
init_title()
|
||||
set_estat(ESTAT_TITLE)
|
||||
transicio(function()
|
||||
guardar_records()
|
||||
init_title()
|
||||
set_estat(ESTAT_TITLE)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ----- PLAYING -----
|
||||
function update_playing()
|
||||
-- Abandonar partida → flux de game over (como en el RUNNER.PAS amb ESC)
|
||||
if btnp(keys.quit) then
|
||||
sfx_gameover()
|
||||
set_estat(ESTAT_GAMEOVER)
|
||||
return
|
||||
end
|
||||
-- Durant un fade (cambi de fase), no processem input ni logica del joc:
|
||||
-- nomes render (el dither es pinta a sobre des de update() global).
|
||||
-- Nota: la transicio a game over es directa (sense fade), perque el
|
||||
-- frame d'arribada es el mateix que el de sortida + overlay.
|
||||
if not fade_actiu() then
|
||||
-- Animacio independent de l'escala lateral (per frame, no per tic)
|
||||
tic_escala_creixent()
|
||||
|
||||
-- Cavar es immediat (un sol forat per pulsacio)
|
||||
if pepe.estat == NORMAL then
|
||||
if btnp(keys.dig_left) and pot_cavar(-1) then foradar(pepe.x-1, pepe.y+1); sfx_dig() end
|
||||
if btnp(keys.dig_right) and pot_cavar( 1) then foradar(pepe.x+1, pepe.y+1); sfx_dig() end
|
||||
end
|
||||
|
||||
-- Logica del joc: cada TICS frames
|
||||
if (cnt() % TICS) == 0 then
|
||||
game_tic = game_tic + 1
|
||||
tic_pepe()
|
||||
check_mort_per_malos()
|
||||
if (game_tic % MALO_RATIO) == 0 then
|
||||
tic_malos()
|
||||
check_mort_per_malos()
|
||||
-- Timers per frame (animacio de mort, invulnerabilitat post-respawn)
|
||||
if pepe.mort_t > 0 then
|
||||
pepe.mort_t = pepe.mort_t - 1
|
||||
if pepe.mort_t == 0 then
|
||||
pepe.vides = pepe.vides - 1
|
||||
if pepe.vides < 0 then
|
||||
sfx_gameover()
|
||||
set_estat(ESTAT_GAMEOVER)
|
||||
return
|
||||
end
|
||||
respawn_pepe()
|
||||
end
|
||||
end
|
||||
check_mapa()
|
||||
if pepe.vides < 0 then
|
||||
if pepe.invuln_t > 0 then pepe.invuln_t = pepe.invuln_t - 1 end
|
||||
|
||||
-- Mentre muriguent, ignorem input i logica del joc (pero els malos
|
||||
-- segueixen movent-se per a no congelar l'escena).
|
||||
local muriguent = pepe.mort_t > 0
|
||||
|
||||
if not muriguent and btnp(keys.quit) then
|
||||
-- Abandonar partida → flux de game over (com en RUNNER.PAS amb ESC)
|
||||
sfx_gameover()
|
||||
set_estat(ESTAT_GAMEOVER)
|
||||
return
|
||||
end
|
||||
|
||||
-- Cavar es immediat (un sol forat per pulsacio)
|
||||
if not muriguent and pepe.estat == NORMAL then
|
||||
if btnp(keys.dig_left) and pot_cavar(-1) then foradar(pepe.x-1, pepe.y+1); sfx_dig() end
|
||||
if btnp(keys.dig_right) and pot_cavar( 1) then foradar(pepe.x+1, pepe.y+1); sfx_dig() end
|
||||
end
|
||||
|
||||
-- Logica del joc: cada TICS frames
|
||||
if (cnt() % TICS) == 0 then
|
||||
game_tic = game_tic + 1
|
||||
if not muriguent then
|
||||
tic_pepe()
|
||||
if fade_actiu() then return end -- canvi de fase iniciat
|
||||
check_mort_per_malos()
|
||||
end
|
||||
if (game_tic % MALO_RATIO) == 0 then
|
||||
tic_malos()
|
||||
if not muriguent then check_mort_per_malos() end
|
||||
end
|
||||
check_mapa()
|
||||
end
|
||||
end
|
||||
|
||||
-- Render
|
||||
-- Render (sempre, fins i tot durant el fade — el dither es pinta encima)
|
||||
neteja_fons()
|
||||
pintar_mapa()
|
||||
pintar_malos()
|
||||
@@ -673,6 +840,7 @@ function tic_malos()
|
||||
end
|
||||
|
||||
function check_mort_per_malos()
|
||||
if pepe.invuln_t > 0 or pepe.mort_t > 0 then return end
|
||||
for i = 1, NUM_MALOS do
|
||||
if malos[i].x == pepe.x and malos[i].y == pepe.y then
|
||||
mort_pepe()
|
||||
@@ -681,17 +849,36 @@ function check_mort_per_malos()
|
||||
end
|
||||
end
|
||||
|
||||
-- Si Pepe ha recollit tots els diners, fa apareixer una escala a la columna 0
|
||||
-- des de la fila 1 cap avall, parant si troba pedra. (CheckMapaComplet)
|
||||
-- Quan Pepe ha recollit tots els diners, dispara l'animacio de creixement
|
||||
-- de l'escala a la columna 0 (la posa l'efectua tic_escala_creixent cada
|
||||
-- frame, no aci de cop). Aci nomes activa l'estat la primera vegada.
|
||||
function check_mapa_complet()
|
||||
if diners_pantalla > 0 then return end
|
||||
for j = 1, MAP_H-2 do
|
||||
if mapa[0][j].tipo == PEDRA then break end
|
||||
mapa[0][j].tipo = ESCALA
|
||||
mapa[0][j].color = colors.escala
|
||||
if escala_state == "idle" then
|
||||
escala_state = "growing"
|
||||
escala_y = 1
|
||||
escala_t = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Tic de creixement de l'escala lateral, cridat des de update_playing.
|
||||
-- Cada escala_step_frames afig una cel·la d'escala a (0, escala_y) i sona
|
||||
-- un beep ascendent. Para quan troba pedra o arriba al final del mapa.
|
||||
function tic_escala_creixent()
|
||||
if escala_state ~= "growing" then return end
|
||||
escala_t = escala_t + 1
|
||||
if escala_t < temps.escala_step_frames then return end
|
||||
escala_t = 0
|
||||
if escala_y > MAP_H - 2 or tipo_a(0, escala_y) == PEDRA then
|
||||
escala_state = "done"
|
||||
return
|
||||
end
|
||||
mapa[0][escala_y].tipo = ESCALA
|
||||
mapa[0][escala_y].color = colors.escala
|
||||
sfx_escala_step(escala_y)
|
||||
escala_y = escala_y + 1
|
||||
end
|
||||
|
||||
-- Anima els forats: decrementa temps i cambia el tipus segons la fase
|
||||
-- (idem case statement de CheckMapa al RUNNER.PAS)
|
||||
function check_mapa()
|
||||
@@ -744,7 +931,17 @@ function pintar_hud()
|
||||
|
||||
-- Text dins del marc
|
||||
print(textos.level_label.." "..string.format("%02d", level), 3, 26)
|
||||
print(textos.score_label.." "..string.format("%03d", score), 16, 26)
|
||||
|
||||
-- Punts: etiqueta sempre en hud_text, digits en groc mentre el contador
|
||||
-- animat encara no ha alcançat el valor real (sensació de coin pickup).
|
||||
local score_label = textos.score_label.." "
|
||||
print(score_label, 16, 26)
|
||||
if score_display < score then
|
||||
color(colors.diners, colors.hud_bg)
|
||||
end
|
||||
print(string.format("%03d", score_display), 16 + strlen(score_label), 26)
|
||||
color(colors.hud_text, colors.hud_bg)
|
||||
|
||||
-- max(0, ...) evita que la pantalla mostre "Vides /" en el game over:
|
||||
-- l'implementacio de tostr() d'ascii torna "/" per a -1 (bug intern).
|
||||
print(textos.lives_label.." "..tostr(max(0, pepe.vides)), 29, 26)
|
||||
@@ -757,19 +954,20 @@ end
|
||||
-- camp a camp, hi haura claus que falten. Fem un merge amb les defaults
|
||||
-- guardades per a que no quede res a nil.
|
||||
function carregar_config()
|
||||
local saved_colors, saved_keys, saved_textos = {}, {}, {}
|
||||
for k, v in pairs(colors) do saved_colors[k] = v end
|
||||
for k, v in pairs(keys) do saved_keys[k] = v end
|
||||
for k, v in pairs(textos) do saved_textos[k] = v end
|
||||
-- Accedim per nom (_G) per a que aço seguisca funcionant fins i tot si
|
||||
-- l'usuari reasigna tota la taula en config.lua (ex: `colors = {bg=...}`
|
||||
-- en lloc de mutar camps individuals).
|
||||
local noms = { "colors", "keys", "textos", "temps" }
|
||||
local saved = {}
|
||||
for _, nom in ipairs(noms) do
|
||||
saved[nom] = {}
|
||||
for k, v in pairs(_G[nom]) do saved[nom][k] = v end
|
||||
end
|
||||
pcall(dofile, "config.lua")
|
||||
for k, v in pairs(saved_colors) do
|
||||
if colors[k] == nil then colors[k] = v end
|
||||
end
|
||||
for k, v in pairs(saved_keys) do
|
||||
if keys[k] == nil then keys[k] = v end
|
||||
end
|
||||
for k, v in pairs(saved_textos) do
|
||||
if textos[k] == nil then textos[k] = v end
|
||||
for _, nom in ipairs(noms) do
|
||||
for k, v in pairs(saved[nom]) do
|
||||
if _G[nom][k] == nil then _G[nom][k] = v end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -788,9 +986,19 @@ function init()
|
||||
end
|
||||
|
||||
function update()
|
||||
-- Contador animat del score: independent de l'estat, així segueix pujant
|
||||
-- sobre el overlay del game over (no es queda congelat a meitat camí).
|
||||
if score_display < score and (cnt() % temps.score_step) == 0 then
|
||||
score_display = score_display + 1
|
||||
end
|
||||
|
||||
if estat_joc == ESTAT_TITLE then update_title()
|
||||
elseif estat_joc == ESTAT_PLAYING then update_playing()
|
||||
elseif estat_joc == ESTAT_GAMEOVER then update_gameover()
|
||||
elseif estat_joc == ESTAT_ENTERNAME then update_entername()
|
||||
end
|
||||
|
||||
-- Overlay del fade encima de tot, i avanc del seu temporitzador
|
||||
pintar_fade()
|
||||
update_fade()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user