DX: game over amb typewriter, cuadre de fons i Pepe trist
This commit is contained in:
+89
-14
@@ -69,7 +69,7 @@ keys = {
|
||||
-- Tots en sentence case (Inicial Majuscula, resta minuscula).
|
||||
textos = {
|
||||
title_press_play = "Prem l'espai per a jugar",
|
||||
game_over = "Fi de joc",
|
||||
game_over = "FI DE JOC",
|
||||
new_record = "Nou record !",
|
||||
score_label = "Punts", -- HUD i pantalla de nou record
|
||||
level_label = "Nivell",
|
||||
@@ -96,7 +96,14 @@ NUM_MALOS = 3
|
||||
TEMPS_IA = 30 -- iteracions del malo entre canvis de direccio
|
||||
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
|
||||
-- VIDES_INI = nombre de reserves (convencio arcade: el HUD mostra reserves,
|
||||
-- no compta la vida actual). 2 reserves = 3 vides totals (1 actual + 2).
|
||||
-- L'original arrancava amb 0 (= 1 vida total).
|
||||
-- TEMPORAL DEBUG: posa'l a 0 per a provar la seqüencia de game over rapid.
|
||||
VIDES_INI = 0
|
||||
-- LEVEL_INI = fase per la que arranca la partida nova (1..NUM_FASES).
|
||||
-- Util per a depuracio i per a saltar al mapa que vols provar.
|
||||
LEVEL_INI = 3
|
||||
|
||||
-- Tots els temps i durations de les animacions del DX. Sobreescriuibles
|
||||
-- per config.lua (en frames a 60 fps; 60 = 1 segon).
|
||||
@@ -107,6 +114,9 @@ temps = {
|
||||
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)
|
||||
gameover_delay_frames = 15, -- espera al entrar a game over abans d'engegar el typewriter
|
||||
typewriter_step_frames = 8, -- frames per cada lletra del typewriter de "FI DE JOC"
|
||||
gameover_show_frames = 120, -- frames que el text final queda visible abans de la transicio
|
||||
}
|
||||
|
||||
-- Estats del joc (maquina d'estats global)
|
||||
@@ -297,6 +307,7 @@ function sfx_die() play("l1o4cl0o3bagfed") end
|
||||
function sfx_malo_die() play("l0o3ao4c") end
|
||||
function sfx_level() play("l1o4ceg") end
|
||||
function sfx_gameover() play("l1o3bal0gfedco2c") end
|
||||
function sfx_typewriter() sound(2500, 2) end -- tic agut i molt curt per a cada lletra
|
||||
|
||||
-- Neteja la pantalla amb el color de fons configurat (en lloc de negre).
|
||||
function neteja_fons()
|
||||
@@ -376,16 +387,38 @@ function pintar_pepe()
|
||||
local col = colors.pepe
|
||||
local g = glif[pepe.dibuix]
|
||||
|
||||
-- En game over, Pepe queda visible amb la cara trista alternant A/B
|
||||
-- (parpadeig amb cnt() perque mort_t ja no es decrementa fora de playing).
|
||||
if estat_joc == ESTAT_GAMEOVER then
|
||||
if (cnt() % 12) < 6 then
|
||||
g = glif[PEPE_MORT_A]
|
||||
col = colors.pepe_mort_a
|
||||
else
|
||||
g = glif[PEPE_MORT_B]
|
||||
col = colors.pepe_mort_b
|
||||
end
|
||||
color(col, colors.bg)
|
||||
print(chr(g), pepe.x, pepe.y)
|
||||
return
|
||||
end
|
||||
|
||||
if pepe.mort_t > 0 then
|
||||
-- En l'ultima vida no hi ha respawn_delay: tot el countdown es anim.
|
||||
local mort_t_max
|
||||
if pepe.vides == 0 then
|
||||
mort_t_max = temps.mort_anim_frames
|
||||
else
|
||||
mort_t_max = temps.mort_anim_frames + temps.respawn_delay_frames
|
||||
end
|
||||
|
||||
-- Fase d'espera (Pepe invisible, mapa segueix viu): no pintem res.
|
||||
if pepe.mort_t <= temps.respawn_delay_frames then return end
|
||||
local fase = mort_t_max - pepe.mort_t -- 0..mort_t_max-1
|
||||
if fase >= temps.mort_anim_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: alterna entre els dos sprites de mort de la skin
|
||||
-- (pepe_mort_a / pepe_mort_b), cada un amb el seu color propi.
|
||||
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
|
||||
@@ -500,12 +533,21 @@ 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)
|
||||
-- Si es l'ultima vida (vides==0), saltem el delay: l'animacio termina i
|
||||
-- anem directament a game over, sense pausa invisible.
|
||||
-- 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()
|
||||
if pepe.mort_t > 0 then return end
|
||||
pepe.mort_t = temps.mort_anim_frames + temps.respawn_delay_frames
|
||||
sfx_die()
|
||||
if pepe.vides == 0 then
|
||||
-- Ultima vida: directament sona sfx_gameover (no sfx_die seguit de
|
||||
-- sfx_gameover, eren molt semblants i es solapaven com a doble eco).
|
||||
pepe.mort_t = temps.mort_anim_frames
|
||||
sfx_gameover()
|
||||
else
|
||||
pepe.mort_t = temps.mort_anim_frames + temps.respawn_delay_frames
|
||||
sfx_die()
|
||||
end
|
||||
end
|
||||
|
||||
-- Reposiciona Pepe al spawn i activa la invulnerabilitat.
|
||||
@@ -519,7 +561,7 @@ end
|
||||
|
||||
-- Inicialitza tot per a una nova partida (reset complet)
|
||||
function inicialitzacio()
|
||||
level = 1
|
||||
level = LEVEL_INI
|
||||
score = 0
|
||||
score_display = 0
|
||||
pepe.vides = VIDES_INI
|
||||
@@ -626,20 +668,53 @@ end
|
||||
-- ----- GAME OVER -----
|
||||
function update_gameover()
|
||||
set_music(nil)
|
||||
-- Render congelat: ultim estat del joc + overlay "GAME OVER"
|
||||
-- Render congelat: mapa + malos + Pepe trist (pintar_pepe detecta l'estat)
|
||||
neteja_fons()
|
||||
pintar_mapa()
|
||||
pintar_malos()
|
||||
pintar_pepe()
|
||||
|
||||
color(colors.title, colors.bg)
|
||||
-- Typewriter: les lletres apareixen una a una despres d'un petit delay
|
||||
-- inicial perque no es solapin amb la sonoritat de sfx_gameover().
|
||||
-- Aban apareix un cuadre de fons (strlen+2 × 3) per a aillar el text
|
||||
-- del mapa que queda darrere.
|
||||
local g = textos.game_over
|
||||
print(g, flr((40 - strlen(g)) / 2), 12)
|
||||
local t = temps_estat() - temps.gameover_delay_frames
|
||||
if t >= 0 then
|
||||
local total_chars = strlen(g)
|
||||
local frames_typewriter = total_chars * temps.typewriter_step_frames
|
||||
local text_x = flr((40 - total_chars) / 2)
|
||||
local text_y = 12
|
||||
|
||||
-- Cuadre de fons: una fila per damunt i una per davall del text,
|
||||
-- i una columna a cada costat. Es pinta primer per a que el text
|
||||
-- quede a sobre.
|
||||
local box_w = total_chars + 2
|
||||
color(colors.hud_bg, colors.hud_bg)
|
||||
local blank = string.rep(" ", box_w)
|
||||
for dy = -1, 1 do print(blank, text_x - 1, text_y + dy) end
|
||||
|
||||
-- Lletres del typewriter
|
||||
local nletres = flr(t / temps.typewriter_step_frames) + 1
|
||||
if nletres > total_chars then nletres = total_chars end
|
||||
color(colors.title, colors.hud_bg)
|
||||
print(substr(g, 0, nletres), text_x, text_y)
|
||||
|
||||
-- Tic nomes en el frame en que apareix una lletra nova, i nomes
|
||||
-- mentre el typewriter encara escriu (no en bucle infinit).
|
||||
if t < frames_typewriter and (t % temps.typewriter_step_frames) == 0 then
|
||||
sfx_typewriter()
|
||||
end
|
||||
end
|
||||
|
||||
pintar_hud()
|
||||
|
||||
-- Despres de 2 segons (120 frames), transicio a title o entername
|
||||
if not fade_actiu() and temps_estat() > 120 then
|
||||
-- Quan el typewriter ha acabat i el text ha estat visible un temps,
|
||||
-- transicionem a title o a la pantalla d'entrar nom (si hi ha record).
|
||||
local total = temps.gameover_delay_frames
|
||||
+ strlen(g) * temps.typewriter_step_frames
|
||||
+ temps.gameover_show_frames
|
||||
if not fade_actiu() and temps_estat() > total then
|
||||
if score > hi_score then
|
||||
transicio(function()
|
||||
hi_score = score
|
||||
@@ -708,7 +783,7 @@ function update_playing()
|
||||
if pepe.mort_t == 0 then
|
||||
pepe.vides = pepe.vides - 1
|
||||
if pepe.vides < 0 then
|
||||
sfx_gameover()
|
||||
-- sfx_gameover ja s'ha tocat al inici de l'animacio (mort_pepe)
|
||||
set_estat(ESTAT_GAMEOVER)
|
||||
return
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user