fase 6: pantalla de títol, game over, records i nou nom

This commit is contained in:
2026-05-15 10:37:43 +02:00
parent ee60faee40
commit 82896750c1
2 changed files with 182 additions and 30 deletions
+2
View File
@@ -94,6 +94,8 @@ El atributo de color de una celda es 1 byte: nibble bajo = INK (tinta), nibble a
| `mousewheel()` | Delta de la rueda en este frame. |
| `mousebutton(i)` | `true` si el botón `i` está pulsado (1=izq, 2=medio, 3=der; usa `SDL_BUTTON(i)`). |
> **Nota**: `whichbtn()` está declarado en `ascii.h` y existe en C++, pero **no está expuesto a Lua** (no aparece en los `lua_setglobal` de `lua.cpp`). Para detectar qué tecla se ha pulsado en un frame hay que iterar con `btnp()` sobre las constantes `KEY_*`.
Códigos de tecla — todos definidos como globales `KEY_*` en Lua. Lista completa (de `lua.cpp` 502-608):
```
+180 -30
View File
@@ -39,6 +39,12 @@ 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
-- Estats del joc (maquina d'estats global)
ESTAT_TITLE = "title"
ESTAT_PLAYING = "playing"
ESTAT_GAMEOVER = "gameover"
ESTAT_ENTERNAME = "entername"
-- Estat global
mapa = {} -- mapa[x][y] = { tipo=, color=, temps= }
level = 1
@@ -48,7 +54,10 @@ score = 0
diners_pantalla = 0
game_tic = 0
hi_score = 0
nom_hi_score = "..."
nom_hi_score = "AAA"
estat_joc = ESTAT_TITLE
estat_inici = 0
enter_name_idx = 1
function definir_glifs()
setchar(BUIT, 0,0,0,0,0,0,0,0)
@@ -216,10 +225,169 @@ function fase_nova()
init_malos()
end
-- Game over de la Fase 5: simple reset a la inicialitzacio.
-- La pantalla de Game Over i records venen a la Fase 6.
function game_over()
inicialitzacio()
-- ====================================================================
-- ESTATS DEL JOC (title / playing / game over / enter name)
-- ====================================================================
function set_estat(nou)
estat_joc = nou
estat_inici = cnt()
end
function temps_estat() return cnt() - estat_inici end
-- Records I/O. Usem io.open (estandard de Lua) en lloc de filein/fileout
-- per a poder gestionar el cas de fitxer inexistent sense petar.
-- Format: 6 bytes = 3 (centenes, desenes, unitats del score) + 3 (lletres nom)
function carregar_records()
local f = io.open("records", "rb")
if not f then return end
local data = f:read(6)
f:close()
if not data or #data < 6 then return end
local b = { string.byte(data, 1, 6) }
hi_score = b[1]*100 + b[2]*10 + b[3]
-- Validar que les lletres del nom siguen imprimibles
if b[4] >= 32 and b[4] < 127
and b[5] >= 32 and b[5] < 127
and b[6] >= 32 and b[6] < 127 then
nom_hi_score = string.char(b[4], b[5], b[6])
end
end
function guardar_records()
local f = io.open("records", "wb")
if not f then return end
f:write(string.char(
flr(hi_score / 100),
flr((hi_score % 100) / 10),
hi_score % 10,
string.byte(nom_hi_score, 1) or 65,
string.byte(nom_hi_score, 2) or 65,
string.byte(nom_hi_score, 3) or 65
))
f:close()
end
-- Quina lletra A-Z s'ha pulsat este frame (escaneig manual amb btnp,
-- perque ascii no exposa whichbtn() al Lua malgrat estar al ascii.h).
function lletra_pulsada()
for sc = KEY_A, KEY_Z do
if btnp(sc) then
return string.char(65 + sc - KEY_A)
end
end
return nil
end
-- ----- TITLE -----
function init_title()
carregar_mapa(0) -- mapa 0 es l'art del titol
end
function update_title()
if btnp(KEY_SPACE) then
inicialitzacio()
set_estat(ESTAT_PLAYING)
return
end
cls()
pintar_mapa()
-- "PRESS SPACE TO PLAY" parpadejant
if flr(cnt() / 30) % 2 == 0 then
color(COLOR_WHITE, COLOR_BLACK)
print("PRESS SPACE TO PLAY", 10, 22)
end
pintar_hud()
end
-- ----- GAME OVER -----
function update_gameover()
-- Render congelat: ultim estat del joc + overlay "GAME OVER"
cls()
pintar_mapa()
pintar_malos()
pintar_pepe()
color(COLOR_LIGHT_RED, COLOR_BLACK)
print("G A M E O V E R", 11, 12)
pintar_hud()
-- Despres de 2 segons (120 frames), transicio
if temps_estat() > 120 then
if score > hi_score then
hi_score = score
nom_hi_score = "AAA"
enter_name_idx = 1
set_estat(ESTAT_ENTERNAME)
else
init_title()
set_estat(ESTAT_TITLE)
end
end
end
-- ----- ENTER NAME -----
function update_entername()
cls()
color(COLOR_LIGHT_RED, COLOR_BLACK)
print("NOU RECORD!", 14, 10)
color(COLOR_YELLOW, COLOR_BLACK)
print("SCORE "..string.format("%03d", hi_score), 15, 12)
color(COLOR_WHITE, COLOR_BLACK)
print("NOM: "..nom_hi_score, 16, 15)
print("(A-Z)", 17, 17)
pintar_hud()
local lletra = lletra_pulsada()
if lletra then
nom_hi_score = string.sub(nom_hi_score, 1, enter_name_idx-1)
..lletra..
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)
end
end
end
-- ----- PLAYING -----
function update_playing()
-- Cavar es immediat (un sol forat per pulsacio)
if pepe.estat == NORMAL then
if btnp(KEY_SPACE) and pot_cavar(-1) then foradar(pepe.x-1, pepe.y+1) end
if btnp(KEY_M) and pot_cavar( 1) then foradar(pepe.x+1, pepe.y+1) 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()
end
check_mapa()
if pepe.vides < 0 then
set_estat(ESTAT_GAMEOVER)
return
end
end
-- Render
cls()
pintar_mapa()
pintar_malos()
pintar_pepe()
pintar_hud()
end
-- ====================================================================
@@ -439,34 +607,16 @@ function init()
border(COLOR_BLUE)
color(COLOR_LIGHT_GRAY, COLOR_BLACK)
definir_glifs()
inicialitzacio()
carregar_records()
init_title()
set_estat(ESTAT_TITLE)
cls()
end
function update()
-- Cavar es immediat (un sol forat per pulsacio)
if pepe.estat == NORMAL then
if btnp(KEY_SPACE) and pot_cavar(-1) then foradar(pepe.x-1, pepe.y+1) end
if btnp(KEY_M) and pot_cavar( 1) then foradar(pepe.x+1, pepe.y+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
-- 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()
end
check_mapa()
if pepe.vides < 0 then game_over() end
end
-- Render: cada frame
cls()
pintar_mapa()
pintar_malos()
pintar_pepe()
pintar_hud()
end