fase 6: pantalla de títol, game over, records i nou nom
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user