DX: game over amb typewriter, cuadre de fons i Pepe trist
This commit is contained in:
+8
-1
@@ -44,7 +44,7 @@ skin = "pintor"
|
|||||||
-- (Convencio: Inicial Majuscula, resta minuscula.)
|
-- (Convencio: Inicial Majuscula, resta minuscula.)
|
||||||
|
|
||||||
-- textos.title_press_play = "Prem l'espai per a jugar"
|
-- textos.title_press_play = "Prem l'espai per a jugar"
|
||||||
-- textos.game_over = "Fi de joc"
|
-- textos.game_over = "FI DE JOC"
|
||||||
-- textos.new_record = "Nou record !"
|
-- textos.new_record = "Nou record !"
|
||||||
-- textos.score_label = "Punts"
|
-- textos.score_label = "Punts"
|
||||||
-- textos.level_label = "Nivell"
|
-- textos.level_label = "Nivell"
|
||||||
@@ -71,6 +71,13 @@ skin = "pintor"
|
|||||||
-- -- respawn, parpadejant blanc/groc.
|
-- -- respawn, parpadejant blanc/groc.
|
||||||
-- temps.escala_step_frames = 6 -- frames entre cada cel·la nova de
|
-- temps.escala_step_frames = 6 -- frames entre cada cel·la nova de
|
||||||
-- -- l'escala lateral quan creix.
|
-- -- l'escala lateral quan creix.
|
||||||
|
-- temps.gameover_delay_frames = 80 -- espera abans del typewriter de
|
||||||
|
-- -- "FI DE JOC" (per a que no es
|
||||||
|
-- -- solape amb sfx_gameover).
|
||||||
|
-- temps.typewriter_step_frames = 6 -- frames per cada lletra del
|
||||||
|
-- -- typewriter al game over.
|
||||||
|
-- temps.gameover_show_frames = 60 -- temps que el text final es queda
|
||||||
|
-- -- visible abans de la transicio.
|
||||||
|
|
||||||
-- ====================================================================
|
-- ====================================================================
|
||||||
-- JINGLES
|
-- JINGLES
|
||||||
|
|||||||
+89
-14
@@ -69,7 +69,7 @@ keys = {
|
|||||||
-- Tots en sentence case (Inicial Majuscula, resta minuscula).
|
-- Tots en sentence case (Inicial Majuscula, resta minuscula).
|
||||||
textos = {
|
textos = {
|
||||||
title_press_play = "Prem l'espai per a jugar",
|
title_press_play = "Prem l'espai per a jugar",
|
||||||
game_over = "Fi de joc",
|
game_over = "FI DE JOC",
|
||||||
new_record = "Nou record !",
|
new_record = "Nou record !",
|
||||||
score_label = "Punts", -- HUD i pantalla de nou record
|
score_label = "Punts", -- HUD i pantalla de nou record
|
||||||
level_label = "Nivell",
|
level_label = "Nivell",
|
||||||
@@ -96,7 +96,14 @@ NUM_MALOS = 3
|
|||||||
TEMPS_IA = 30 -- iteracions del malo entre canvis de direccio
|
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)
|
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)
|
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
|
-- Tots els temps i durations de les animacions del DX. Sobreescriuibles
|
||||||
-- per config.lua (en frames a 60 fps; 60 = 1 segon).
|
-- 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)
|
respawn_delay_frames = 120, -- temps que Pepe queda invisible abans del respawn (2 s)
|
||||||
invuln_frames = 180, -- temps invulnerable despres del respawn (3 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)
|
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)
|
-- 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_malo_die() play("l0o3ao4c") end
|
||||||
function sfx_level() play("l1o4ceg") end
|
function sfx_level() play("l1o4ceg") end
|
||||||
function sfx_gameover() play("l1o3bal0gfedco2c") 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).
|
-- Neteja la pantalla amb el color de fons configurat (en lloc de negre).
|
||||||
function neteja_fons()
|
function neteja_fons()
|
||||||
@@ -376,16 +387,38 @@ function pintar_pepe()
|
|||||||
local col = colors.pepe
|
local col = colors.pepe
|
||||||
local g = glif[pepe.dibuix]
|
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
|
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.
|
-- 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):
|
-- Animacio visual de mort, en dos trams desproporcionats (1/4 + 3/4):
|
||||||
-- tram curt: parpadeja blanc/roig amb la cara normal del Pepe.
|
-- tram curt: parpadeja blanc/roig amb la cara normal del Pepe.
|
||||||
-- tram llarg: alterna entre els dos sprites de mort de la skin
|
-- 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.
|
-- (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)
|
local tram_curt = flr(temps.mort_anim_frames / 4)
|
||||||
if fase < tram_curt then
|
if fase < tram_curt then
|
||||||
col = (fase % 6 < 3) and colors.malo or colors.pepe
|
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:
|
-- Inicia l'animacio de mort. El timer mort_t cobreix dos trams seguits:
|
||||||
-- [delay+1 .. delay+anim] → animacio visual de Pepe morint
|
-- [delay+1 .. delay+anim] → animacio visual de Pepe morint
|
||||||
-- [1 .. delay] → Pepe invisible, mapa segueix viu (pausa)
|
-- [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.
|
-- Al arribar a 0, update_playing descompta vida i fa el respawn.
|
||||||
-- Guarda contra reentrada per a no reiniciar si ja esta morint.
|
-- Guarda contra reentrada per a no reiniciar si ja esta morint.
|
||||||
function mort_pepe()
|
function mort_pepe()
|
||||||
if pepe.mort_t > 0 then return end
|
if pepe.mort_t > 0 then return end
|
||||||
pepe.mort_t = temps.mort_anim_frames + temps.respawn_delay_frames
|
if pepe.vides == 0 then
|
||||||
sfx_die()
|
-- 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
|
end
|
||||||
|
|
||||||
-- Reposiciona Pepe al spawn i activa la invulnerabilitat.
|
-- Reposiciona Pepe al spawn i activa la invulnerabilitat.
|
||||||
@@ -519,7 +561,7 @@ end
|
|||||||
|
|
||||||
-- Inicialitza tot per a una nova partida (reset complet)
|
-- Inicialitza tot per a una nova partida (reset complet)
|
||||||
function inicialitzacio()
|
function inicialitzacio()
|
||||||
level = 1
|
level = LEVEL_INI
|
||||||
score = 0
|
score = 0
|
||||||
score_display = 0
|
score_display = 0
|
||||||
pepe.vides = VIDES_INI
|
pepe.vides = VIDES_INI
|
||||||
@@ -626,20 +668,53 @@ end
|
|||||||
-- ----- GAME OVER -----
|
-- ----- GAME OVER -----
|
||||||
function update_gameover()
|
function update_gameover()
|
||||||
set_music(nil)
|
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()
|
neteja_fons()
|
||||||
pintar_mapa()
|
pintar_mapa()
|
||||||
pintar_malos()
|
pintar_malos()
|
||||||
pintar_pepe()
|
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
|
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()
|
pintar_hud()
|
||||||
|
|
||||||
-- Despres de 2 segons (120 frames), transicio a title o entername
|
-- Quan el typewriter ha acabat i el text ha estat visible un temps,
|
||||||
if not fade_actiu() and temps_estat() > 120 then
|
-- 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
|
if score > hi_score then
|
||||||
transicio(function()
|
transicio(function()
|
||||||
hi_score = score
|
hi_score = score
|
||||||
@@ -708,7 +783,7 @@ function update_playing()
|
|||||||
if pepe.mort_t == 0 then
|
if pepe.mort_t == 0 then
|
||||||
pepe.vides = pepe.vides - 1
|
pepe.vides = pepe.vides - 1
|
||||||
if pepe.vides < 0 then
|
if pepe.vides < 0 then
|
||||||
sfx_gameover()
|
-- sfx_gameover ja s'ha tocat al inici de l'animacio (mort_pepe)
|
||||||
set_estat(ESTAT_GAMEOVER)
|
set_estat(ESTAT_GAMEOVER)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user