655 lines
21 KiB
Lua
655 lines
21 KiB
Lua
-- Pepe el Pintor — port a ascii/Lua del joc original en Turbo Pascal
|
||
-- (Sergi Valor Martínez, 1999). Base: PINTOR3.PAS.
|
||
--
|
||
-- ITER 3: multifase. 3 mapes (rect xicotet, creu+rombe, rect gran) amb
|
||
-- transició "ENHORABONA!" entre fases. En acabar la fase 3, loop a la fase 1
|
||
-- mantenint el flux infinit del Pascal original.
|
||
|
||
-- ====================================================================
|
||
-- CONSTANTS
|
||
-- ====================================================================
|
||
MAP_W, MAP_H = 40, 25
|
||
HUD_Y0 = 25
|
||
|
||
-- Glifs (codis CP437). Els redefinim amb setchar per a fidelitat.
|
||
PEPE_PLE = 2 -- ☻ Pepe amb pintura
|
||
PEPE_BUIT = 1 -- ☺ Pepe sense pintura
|
||
PARED = 0xB1 -- ▒ paret
|
||
FONS = 0xDB -- █ fons (sense pintar / pintat = distingit per `pintat`)
|
||
POT_GLIF = 232 -- ◘ marca visual del pot
|
||
MALO_GLIF = 88 -- 'X' enemic
|
||
NETEJA_GLIF = 176 -- ░ char de neteja_pantalla del Pascal
|
||
-- Fletxes (CP437) per al diagrama de tecles del HUD
|
||
ARR_UP = 30 -- ▲
|
||
ARR_DOWN = 31 -- ▼
|
||
ARR_LEFT = 17 -- ◄
|
||
ARR_RIGHT = 16 -- ►
|
||
|
||
-- Constants del joc
|
||
POT_MAX = 90
|
||
PEPE_INI_X = 37 -- cambra del pot (sortint 1 cel·la del marc a la dreta)
|
||
PEPE_INI_Y = 11
|
||
TICS_MOVIMENT = 5 -- frames per tic de moviment (60/5 = 12 Hz)
|
||
TICS_OMPLIR = 3 -- frames entre +1 de pot al recarregar
|
||
|
||
NUM_MALOS = 3
|
||
VIDES_INI = 5
|
||
NUM_FASES = 3
|
||
|
||
-- Llindars d'aparició dels enemics expressats com a *fracció* del total
|
||
-- inicial de la fase. PINTOR3 tenia 1000/700/500 blocs sobre ~1320 → 76% /
|
||
-- 53% / 38%. Apareixen quan total_blocs baixa per sota.
|
||
SPAWN_FRAC = { 0.76, 0.53, 0.38 }
|
||
|
||
-- Animació de mort: 10000 Hz → 1000 Hz, restant 250 cada pas
|
||
MORT_FREQ_INI = 10000
|
||
MORT_FREQ_END = 1000
|
||
MORT_FREQ_STEP = 250
|
||
MORT_FRAMES = 36 -- ~600 ms d'animació de mort
|
||
|
||
-- Estats
|
||
ESTAT_AVIS = "avis" -- pantalla inicial "AVÍS — Aquest joc encara..."
|
||
ESTAT_PLAYING = "playing"
|
||
ESTAT_MURIGUENT = "muriguent"
|
||
ESTAT_GAMEOVER = "gameover"
|
||
ESTAT_INTERFASE = "interfase" -- "ENHORABONA!" entre fases (fidel al Pascal)
|
||
INTERFASE_FRAMES = 240 -- ~4 segons (l'original feia delay(5000) = 5s)
|
||
NETEJA_FRAMES = 60 -- duració del sweep de neteja al final del interfase
|
||
|
||
-- ====================================================================
|
||
-- ESTAT GLOBAL
|
||
-- ====================================================================
|
||
mapa = {}
|
||
pepe = { x=PEPE_INI_X, y=PEPE_INI_Y, pinta=true }
|
||
pot = POT_MAX
|
||
total_blocs = 0
|
||
omplint = false
|
||
omplir_i = 0
|
||
omplir_max = 0
|
||
|
||
malos = {} -- { {x, y, viu=bool, aparegut=bool}, ... }
|
||
vides = VIDES_INI
|
||
fase = 1 -- 1..NUM_FASES, loop al final
|
||
total_inicial = 0 -- valor de total_blocs al començar la fase (per als llindars)
|
||
truco = false -- invulnerabilitat (mode debug, l'original ho tenia comentat amb tecla I)
|
||
|
||
estat_joc = ESTAT_PLAYING
|
||
estat_t = 0 -- contador de frames dins de l'estat actual
|
||
|
||
-- Buffer d'edges d'input direccional (vore explicació a l'iter 1).
|
||
input_buf = { up=false, down=false, left=false, right=false }
|
||
|
||
function sample_input()
|
||
if btnp(KEY_Q) then input_buf.up = true end
|
||
if btnp(KEY_A) then input_buf.down = true end
|
||
if btnp(KEY_O) then input_buf.left = true end
|
||
if btnp(KEY_P) then input_buf.right = true end
|
||
end
|
||
|
||
function reset_input()
|
||
input_buf.up, input_buf.down, input_buf.left, input_buf.right = false, false, false, false
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- GLIFS CUSTOM (bitmaps CP437)
|
||
-- ====================================================================
|
||
function definir_glifs()
|
||
setchar(PEPE_PLE, 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E)
|
||
setchar(PEPE_BUIT, 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E)
|
||
setchar(PARED, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11)
|
||
setchar(FONS, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)
|
||
setchar(POT_GLIF, 0x00, 0x7E, 0x7E, 0x42, 0x66, 0x7E, 0x3C, 0x00)
|
||
setchar(MALO_GLIF, 0x00, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3)
|
||
-- Char de la neteja_pantalla del Pascal (chr 176 — ░ tinta clara)
|
||
setchar(NETEJA_GLIF, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44)
|
||
-- Fletxes triangulars per al diagrama del HUD
|
||
setchar(ARR_UP, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0x00, 0x00, 0x00)
|
||
setchar(ARR_DOWN, 0x00, 0x00, 0x00, 0xFF, 0x7E, 0x3C, 0x18, 0x00)
|
||
setchar(ARR_LEFT, 0x00, 0x10, 0x30, 0x70, 0xF0, 0x70, 0x30, 0x10)
|
||
setchar(ARR_RIGHT, 0x00, 0x08, 0x0C, 0x0E, 0x0F, 0x0E, 0x0C, 0x08)
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- MAPA
|
||
-- ====================================================================
|
||
function tipo_a(x, y)
|
||
if x < 0 or x >= MAP_W or y < 0 or y >= MAP_H then return PARED end
|
||
return mapa[x][y].tipo
|
||
end
|
||
|
||
-- Una cel·la és "pintada" si Pepe o un malo hi han passat. Els malos només
|
||
-- es poden moure per cel·les pintades (fidel al Pascal: a_v(destí) == bg).
|
||
function pintat_a(x, y)
|
||
if x < 0 or x >= MAP_W or y < 0 or y >= MAP_H then return false end
|
||
return mapa[x][y].pintat
|
||
end
|
||
|
||
function hi_ha_malo(x, y)
|
||
for i = 1, NUM_MALOS do
|
||
local m = malos[i]
|
||
if m.viu and m.x == x and m.y == y then return true end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function carregar_mapa(num)
|
||
filein("maps/"..tostr(num)..".map", 0, MAP_W*MAP_H)
|
||
total_blocs = 0
|
||
for x = 0, MAP_W-1 do
|
||
mapa[x] = {}
|
||
for y = 0, MAP_H-1 do
|
||
local b = peek(x*MAP_H + y)
|
||
mapa[x][y] = { tipo=b, pintat=false }
|
||
if b == FONS then total_blocs = total_blocs + 1 end
|
||
end
|
||
end
|
||
-- La cel·la del pot no es pinta: ja "pintada" per a la condició de victòria
|
||
mapa[PEPE_INI_X][PEPE_INI_Y].pintat = true
|
||
total_blocs = total_blocs - 1
|
||
total_inicial = total_blocs -- per a calcular llindars d'spawn
|
||
end
|
||
|
||
function pintar_mapa()
|
||
for x = 0, MAP_W-1 do
|
||
for y = 0, MAP_H-1 do
|
||
local c = mapa[x][y]
|
||
if c.tipo == PARED then
|
||
color(COLOR_RED, COLOR_BLACK)
|
||
print(chr(PARED), x, y)
|
||
elseif c.tipo == FONS and c.pintat then
|
||
color(COLOR_BROWN, COLOR_BLACK)
|
||
print(chr(FONS), x, y)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function pintar_pot()
|
||
if not (pepe.x == PEPE_INI_X and pepe.y == PEPE_INI_Y) then
|
||
color(COLOR_YELLOW, COLOR_BROWN)
|
||
print(chr(POT_GLIF), PEPE_INI_X, PEPE_INI_Y)
|
||
end
|
||
end
|
||
|
||
function pintar_pepe()
|
||
local glif = pepe.pinta and PEPE_PLE or PEPE_BUIT
|
||
local fons_color
|
||
if pepe.x == PEPE_INI_X and pepe.y == PEPE_INI_Y then
|
||
fons_color = COLOR_BROWN -- damunt del pot
|
||
elseif mapa[pepe.x][pepe.y].pintat then
|
||
fons_color = COLOR_BROWN
|
||
else
|
||
fons_color = COLOR_BLACK
|
||
end
|
||
color(COLOR_YELLOW, fons_color)
|
||
print(chr(glif), pepe.x, pepe.y)
|
||
end
|
||
|
||
function pintar_malos()
|
||
for i = 1, NUM_MALOS do
|
||
local m = malos[i]
|
||
if m.viu then
|
||
-- Color enemic: cian clar (107 = 0x6B → bg 6 marró + fg 11 cian)
|
||
color(COLOR_LIGHT_CYAN, COLOR_BROWN)
|
||
print(chr(MALO_GLIF), m.x, m.y)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- HUD: pintura, blocs, fase, vides + diagrama de tecles al lateral dret
|
||
-- (fidel a l'original que dibuixava les fletxes Q/A/O/P amb chars 30,31,16,17)
|
||
function pintar_hud()
|
||
color(COLOR_LIGHT_GRAY, COLOR_BLUE)
|
||
local blank = " "
|
||
for i = HUD_Y0, 29 do print(blank, 0, i) end
|
||
|
||
-- Columna esquerra: dades del joc
|
||
color(COLOR_WHITE, COLOR_BLUE)
|
||
print("PINTURA "..string.format("%02d", pot).."/"..tostr(POT_MAX), 1, 25)
|
||
color(COLOR_YELLOW, COLOR_BLUE)
|
||
print("BLOCS "..string.format("%04d", total_blocs), 1, 26)
|
||
color(COLOR_LIGHT_GREEN, COLOR_BLUE)
|
||
print("FASE "..tostr(fase), 1, 27)
|
||
color(COLOR_LIGHT_RED, COLOR_BLUE)
|
||
for i = 1, vides do
|
||
print(chr(PEPE_PLE), 9 + i, 27)
|
||
end
|
||
|
||
-- Diagrama de tecles (fidel al PINTOR original)
|
||
-- Q
|
||
-- ▲
|
||
-- O ◄ ► P
|
||
-- ▼
|
||
-- A
|
||
color(COLOR_LIGHT_CYAN, COLOR_BLUE)
|
||
print("Q", 30, 25)
|
||
print(chr(ARR_UP), 30, 26)
|
||
print("O", 28, 27)
|
||
print(chr(ARR_LEFT), 29, 27)
|
||
print(chr(ARR_RIGHT), 31, 27)
|
||
print("P", 32, 27)
|
||
print(chr(ARR_DOWN), 30, 28)
|
||
print("A", 30, 29)
|
||
|
||
if truco then
|
||
color(COLOR_WHITE, COLOR_RED)
|
||
print("INVULN", 1, 29)
|
||
end
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- LÒGICA DEL PEPE
|
||
-- ====================================================================
|
||
function intent_moviment(dx, dy)
|
||
local nx, ny = pepe.x + dx, pepe.y + dy
|
||
local t = tipo_a(nx, ny)
|
||
if t == PARED then return end
|
||
if t ~= FONS then return end
|
||
|
||
-- Detecció de mort: si la cel·la destí té un malo (fidel a "a_v=bicho")
|
||
if hi_ha_malo(nx, ny) then
|
||
mort_pepe()
|
||
return
|
||
end
|
||
|
||
pepe.x, pepe.y = nx, ny
|
||
local c = mapa[nx][ny]
|
||
|
||
-- El pot no es pinta
|
||
if nx == PEPE_INI_X and ny == PEPE_INI_Y then
|
||
sound(2000, 3)
|
||
return
|
||
end
|
||
|
||
if not c.pintat then
|
||
if pot > 0 then
|
||
c.pintat = true
|
||
pot = pot - 1
|
||
total_blocs = total_blocs - 1
|
||
sound(5000, 3)
|
||
pepe.pinta = (pot > 0)
|
||
else
|
||
sound(1000, 3) -- so més greu quan no hi ha pintura (fidel: nota=1000)
|
||
end
|
||
else
|
||
sound(5000, 3)
|
||
end
|
||
end
|
||
|
||
function tic_pepe()
|
||
if omplint then return end
|
||
if input_buf.up or btn(KEY_Q) then intent_moviment( 0, -1)
|
||
elseif input_buf.down or btn(KEY_A) then intent_moviment( 0, 1)
|
||
elseif input_buf.left or btn(KEY_O) then intent_moviment(-1, 0)
|
||
elseif input_buf.right or btn(KEY_P) then intent_moviment( 1, 0)
|
||
end
|
||
|
||
if pepe.x == PEPE_INI_X and pepe.y == PEPE_INI_Y and pot < POT_MAX then
|
||
omplint = true
|
||
omplir_i = 0
|
||
omplir_max = POT_MAX - pot
|
||
end
|
||
end
|
||
|
||
-- Fidel al Pascal: sound(i*10) on i és el comptador del bucle
|
||
function tic_omplir()
|
||
if not omplint then return end
|
||
sound(omplir_i * 10, 2)
|
||
pot = pot + 1
|
||
omplir_i = omplir_i + 1
|
||
if omplir_i > omplir_max then
|
||
if pot > POT_MAX then pot = POT_MAX end
|
||
omplint = false
|
||
nosound()
|
||
end
|
||
pepe.pinta = true
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- ENEMICS — moure_malos del PINTOR3.PAS
|
||
-- ====================================================================
|
||
function init_malos()
|
||
malos = {}
|
||
for i = 1, NUM_MALOS do
|
||
malos[i] = { x=0, y=0, viu=false, aparegut=false }
|
||
end
|
||
end
|
||
|
||
-- naiximent: busca totes les cel·les pintades (= chr 219 en el Pascal) i
|
||
-- en tria una aleatòria. Reservem el pot perquè no naixi el malo damunt.
|
||
function naiximent()
|
||
local llocs = {}
|
||
for x = 0, MAP_W-1 do
|
||
for y = 0, MAP_H-1 do
|
||
if mapa[x][y].pintat
|
||
and not (x == PEPE_INI_X and y == PEPE_INI_Y)
|
||
and not (x == pepe.x and y == pepe.y) then
|
||
llocs[#llocs+1] = { x=x, y=y }
|
||
end
|
||
end
|
||
end
|
||
if #llocs == 0 then return PEPE_INI_X, PEPE_INI_Y end -- fallback (impossible si jugues)
|
||
local pick = llocs[rnd(#llocs) + 1]
|
||
return pick.x, pick.y
|
||
end
|
||
|
||
-- "Música malos" del Pascal: el bucle for de 6 vegades × 41 sounds de 0 a
|
||
-- 8000 Hz creixent ràpidament. Aproximem amb una pujada cromàtica que
|
||
-- recorre 4-5 octaves en una passada (un sol play, asincron a l'engine).
|
||
function jingle_malo()
|
||
play("l0o2cdefgab>cdefgab>cdefgab>cdefgab>cdefg")
|
||
end
|
||
|
||
-- Check spawn: si total_blocs ha baixat per sota del llindar proporcional al
|
||
-- total inicial de la fase, i el malo encara no ha aparegut, el fem aparèixer.
|
||
function check_spawn()
|
||
for i = 1, NUM_MALOS do
|
||
local m = malos[i]
|
||
local llindar = flr(total_inicial * SPAWN_FRAC[i])
|
||
if not m.aparegut and total_blocs <= llindar then
|
||
m.x, m.y = naiximent()
|
||
m.viu = true
|
||
m.aparegut = true
|
||
jingle_malo()
|
||
end
|
||
end
|
||
end
|
||
|
||
-- Decisió de direcció del malo (fidel a moure_malos del Pascal):
|
||
-- random(2): 0 = perseguir en eix X, 1 = perseguir en eix Y. La direcció és:
|
||
-- meneja=0 esquerra, 1 dreta, 2 dalt, 3 baix.
|
||
-- Retorna una de les 4 direccions (o nil si no s'aplica cap).
|
||
function decidir_direccio(m)
|
||
local meneja = nil
|
||
if rnd(2) == 0 then
|
||
if pepe.x - m.x > 0 then meneja = 1 -- pepe a la dreta del malo
|
||
elseif pepe.x - m.x < 0 then meneja = 0 -- pepe a l'esquerra
|
||
end
|
||
else
|
||
if pepe.y - m.y > 0 then meneja = 3 -- pepe avall
|
||
elseif pepe.y - m.y < 0 then meneja = 2 -- pepe amunt
|
||
end
|
||
end
|
||
return meneja
|
||
end
|
||
|
||
-- Intenta moure un malo en la direcció `meneja`. Fidel al Pascal:
|
||
-- requereix que la cel·la destí (a) no siga paret, (b) no tinga un altre
|
||
-- malo, i (c) siga "bg" (= cel·la pintada). Aquesta tercera condició limita
|
||
-- els malos a la zona ja pintada pel Pepe.
|
||
function moure_malo(m, meneja)
|
||
if meneja == nil then return end
|
||
local dx, dy = 0, 0
|
||
if meneja == 0 then dx = -1
|
||
elseif meneja == 1 then dx = 1
|
||
elseif meneja == 2 then dy = -1
|
||
elseif meneja == 3 then dy = 1
|
||
end
|
||
local nx, ny = m.x + dx, m.y + dy
|
||
if tipo_a(nx, ny) == PARED then return end
|
||
if hi_ha_malo(nx, ny) then return end
|
||
if not pintat_a(nx, ny) then return end
|
||
m.x, m.y = nx, ny
|
||
end
|
||
|
||
function tic_malos()
|
||
for i = 1, NUM_MALOS do
|
||
local m = malos[i]
|
||
if m.viu then
|
||
moure_malo(m, decidir_direccio(m))
|
||
end
|
||
end
|
||
end
|
||
|
||
function check_mort_per_malo()
|
||
for i = 1, NUM_MALOS do
|
||
local m = malos[i]
|
||
if m.viu and m.x == pepe.x and m.y == pepe.y then
|
||
mort_pepe()
|
||
return
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- MORT + ESTATS DE TRANSICIÓ
|
||
-- ====================================================================
|
||
function set_estat(nou)
|
||
estat_joc = nou
|
||
estat_t = 0
|
||
end
|
||
|
||
function mort_pepe()
|
||
if truco then return end -- invulnerabilitat de debug
|
||
vides = vides - 1
|
||
set_estat(ESTAT_MURIGUENT)
|
||
end
|
||
|
||
function reset_partida()
|
||
pot = POT_MAX
|
||
total_blocs = 0
|
||
vides = VIDES_INI
|
||
fase = 1
|
||
omplint = false
|
||
pepe.x, pepe.y = PEPE_INI_X, PEPE_INI_Y
|
||
pepe.pinta = true
|
||
init_malos()
|
||
carregar_mapa(fase)
|
||
reset_input()
|
||
set_estat(ESTAT_PLAYING)
|
||
end
|
||
|
||
-- Carrega una fase concreta (reinicia vides i pot, ja siga per la transició
|
||
-- normal o per l'atall de debug). Si n > NUM_FASES, loop a 1.
|
||
function anar_a_fase(n)
|
||
if n > NUM_FASES then n = 1 end
|
||
if n < 1 then n = NUM_FASES end
|
||
fase = n
|
||
vides = VIDES_INI
|
||
pot = POT_MAX
|
||
omplint = false
|
||
pepe.x, pepe.y = PEPE_INI_X, PEPE_INI_Y
|
||
pepe.pinta = true
|
||
init_malos()
|
||
carregar_mapa(fase)
|
||
reset_input()
|
||
set_estat(ESTAT_PLAYING)
|
||
end
|
||
|
||
-- Avança a la fase següent (fidel al PINTOR3: nfase++ i si > 3, loop a 1).
|
||
function avancar_fase()
|
||
anar_a_fase(fase + 1)
|
||
end
|
||
|
||
-- Respawn després de mort (sense reset complet, sols Pepe a casa i pot ple)
|
||
function respawn_pepe()
|
||
pepe.x, pepe.y = PEPE_INI_X, PEPE_INI_Y
|
||
pepe.pinta = true
|
||
pot = POT_MAX
|
||
omplint = false
|
||
reset_input()
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- LÒGICA PER ESTAT
|
||
-- ====================================================================
|
||
function update_playing()
|
||
sample_input()
|
||
|
||
-- Atalls de debug: 1/2/3 = salta a fase, I = toggle invulnerable
|
||
if btnp(KEY_1) then anar_a_fase(1); return
|
||
elseif btnp(KEY_2) then anar_a_fase(2); return
|
||
elseif btnp(KEY_3) then anar_a_fase(3); return
|
||
end
|
||
if btnp(KEY_I) then truco = not truco end
|
||
|
||
if omplint and (cnt() % TICS_OMPLIR) == 0 then tic_omplir() end
|
||
|
||
if not omplint and (cnt() % TICS_MOVIMENT) == 0 then
|
||
tic_pepe()
|
||
check_mort_per_malo()
|
||
if estat_joc ~= ESTAT_PLAYING then reset_input(); return end
|
||
tic_malos()
|
||
check_mort_per_malo()
|
||
check_spawn()
|
||
reset_input()
|
||
|
||
if total_blocs <= 0 then
|
||
set_estat(ESTAT_INTERFASE)
|
||
play("l3o4ceg>c")
|
||
return
|
||
end
|
||
end
|
||
|
||
cls()
|
||
pintar_mapa()
|
||
pintar_pot()
|
||
pintar_malos()
|
||
pintar_pepe()
|
||
pintar_hud()
|
||
end
|
||
|
||
function update_muriguent()
|
||
-- Animació de mort: so descendent + parpadeig del Pepe
|
||
local pas = flr(estat_t / 3)
|
||
local freq = MORT_FREQ_INI - pas * MORT_FREQ_STEP
|
||
if freq < MORT_FREQ_END then freq = MORT_FREQ_END end
|
||
sound(freq, 2)
|
||
|
||
cls()
|
||
pintar_mapa()
|
||
pintar_pot()
|
||
pintar_malos()
|
||
if (estat_t // 4) % 2 == 0 then pintar_pepe() end
|
||
pintar_hud()
|
||
|
||
if estat_t >= MORT_FRAMES then
|
||
nosound()
|
||
if vides <= 0 then
|
||
set_estat(ESTAT_GAMEOVER)
|
||
else
|
||
respawn_pepe()
|
||
set_estat(ESTAT_PLAYING)
|
||
end
|
||
end
|
||
end
|
||
|
||
function update_gameover()
|
||
cls()
|
||
pintar_mapa()
|
||
pintar_pot()
|
||
pintar_malos()
|
||
pintar_hud()
|
||
color(COLOR_WHITE, COLOR_RED)
|
||
print(" A D E U ", 15, 11)
|
||
|
||
if estat_t > 120 and btnp(KEY_SPACE) then
|
||
reset_partida()
|
||
end
|
||
end
|
||
|
||
-- Transició entre fases: ENHORABONA! parpadejant, sweep de neteja per
|
||
-- columnes (fidel al `neteja_pantalla` del Pascal) i salt a la fase següent.
|
||
function update_interfase()
|
||
cls()
|
||
pintar_mapa()
|
||
pintar_pot()
|
||
pintar_pepe()
|
||
pintar_hud()
|
||
|
||
-- ENHORABONA! parpadejant durant la primera part
|
||
if estat_t < INTERFASE_FRAMES - NETEJA_FRAMES and (estat_t // 12) % 2 == 0 then
|
||
color(COLOR_LIGHT_GREEN, COLOR_BLACK)
|
||
print("ENHORABONA!", 14, 11)
|
||
end
|
||
|
||
-- Sweep de neteja (últims NETEJA_FRAMES frames). Omplim columnes
|
||
-- progressivament amb chr(176) = ░ negre sobre negre.
|
||
if estat_t >= INTERFASE_FRAMES - NETEJA_FRAMES then
|
||
local progr = estat_t - (INTERFASE_FRAMES - NETEJA_FRAMES)
|
||
local cols = flr(progr * MAP_W / NETEJA_FRAMES)
|
||
if cols > MAP_W then cols = MAP_W end
|
||
color(COLOR_DARK_GRAY, COLOR_BLACK)
|
||
for x = 0, cols - 1 do
|
||
for y = 0, MAP_H - 1 do
|
||
print(chr(NETEJA_GLIF), x, y)
|
||
end
|
||
end
|
||
end
|
||
|
||
if estat_t >= INTERFASE_FRAMES then
|
||
avancar_fase()
|
||
end
|
||
end
|
||
|
||
-- Pantalla AVÍS inicial (fidel a beta_version del PINTOR2/PEPEDIEG).
|
||
-- Mostra una caixa amb el text, després va apuntant "Prem una tecla per a
|
||
-- continuar" cap amunt fins una posició final, i espera una tecla.
|
||
function update_avis()
|
||
cls()
|
||
|
||
color(COLOR_WHITE, COLOR_BLACK)
|
||
print("- AVIS -", 16, 3)
|
||
|
||
color(COLOR_WHITE, COLOR_BLACK)
|
||
print("+------------------------------+", 3, 6)
|
||
print("| |", 3, 7)
|
||
print("| Port a la fantasy console |", 3, 8)
|
||
print("| ascii del joc original en |", 3, 9)
|
||
print("| Turbo Pascal de 1999, fet |", 3, 10)
|
||
print("| per Sergi Valor Martinez. |", 3, 11)
|
||
print("| |", 3, 12)
|
||
print("| Que sapigues que les tres |", 3, 13)
|
||
print("| fases son en bucle infinit. |", 3, 14)
|
||
print("| |", 3, 15)
|
||
print("+------------------------------+", 3, 16)
|
||
|
||
-- Animació del missatge pujant des de fila 24 fins fila 19 (5 fil)
|
||
local fila_final = 19
|
||
local pas = estat_t // 8
|
||
local fila = 24 - pas
|
||
if fila < fila_final then fila = fila_final end
|
||
|
||
if (estat_t // 6) % 2 == 0 then
|
||
color(COLOR_LIGHT_CYAN, COLOR_BLACK)
|
||
print("- Prem una tecla per a continuar -", 3, fila)
|
||
end
|
||
|
||
-- Quan el missatge ja ha arribat a la posició final, accepta tecles
|
||
if fila == fila_final then
|
||
if btnp(KEY_SPACE) or btnp(KEY_RETURN) then
|
||
anar_a_fase(1)
|
||
return
|
||
end
|
||
for k = KEY_A, KEY_Z do
|
||
if btnp(k) then anar_a_fase(1); return end
|
||
end
|
||
end
|
||
end
|
||
|
||
-- ====================================================================
|
||
-- BUCLE PRINCIPAL
|
||
-- ====================================================================
|
||
function init()
|
||
wintitle("© 1999 Pepe el pintor — JailDesigner")
|
||
mode(1)
|
||
border(COLOR_BLUE)
|
||
definir_glifs()
|
||
init_malos()
|
||
fase = 1
|
||
carregar_mapa(fase)
|
||
set_estat(ESTAT_AVIS)
|
||
cls()
|
||
end
|
||
|
||
function update()
|
||
if btnp(KEY_ESCAPE) then os.exit(0) end
|
||
estat_t = estat_t + 1
|
||
if estat_joc == ESTAT_AVIS then update_avis()
|
||
elseif estat_joc == ESTAT_PLAYING then update_playing()
|
||
elseif estat_joc == ESTAT_MURIGUENT then update_muriguent()
|
||
elseif estat_joc == ESTAT_GAMEOVER then update_gameover()
|
||
elseif estat_joc == ESTAT_INTERFASE then update_interfase()
|
||
end
|
||
end
|