Fase 4: gos guardia (despertar, persecucio i mossegada)

This commit is contained in:
2026-05-18 13:45:08 +02:00
parent 83036f9cc9
commit 605966fe25
+107 -7
View File
@@ -40,6 +40,14 @@ RETARDO_STEP = 50
RUIDO_RND = 15
RUIDO_UMBRAL = 10
-- AFTER de BASIC del CPC trabaja en 1/50 s (jiffies de 20 ms). El original
-- programa "AFTER retardo*4, 1 GOSUB 310" → retardo*4 jiffies = retardo*80 ms.
MS_POR_JIFFY = 20
-- Cada cuántos movimientos del jugador avanza el perro (línea 1650: perro
-- alterna 1,2 y solo se mueve cuando == 2 → 1 paso de perro cada 2 del jugador).
PERRO_RATIO = 2
-- ============================================================
-- PALETA (mapeo CPC firmware → CGA disponible)
-- Original: INK 0,0 (negro) / 1,26 (pastel) / 2,15 (blanco) /
@@ -226,6 +234,16 @@ robado = 0 -- joyas recogidas por el ladrón
mensaje_msg = "" -- mensaje de la fila inferior (Choque, etc.)
retardo = RETARDO_INI
-- Perro guardián
perro = {
activo = false, -- perro==1 del original
rm = 0, -- habitación donde se activó
x = 0, y = 0, -- posición
paso = 0, -- alterna 0/1 para PERRO_RATIO (línea 1650)
pendiente = false, -- AFTER programado pero aún no disparado
pend_t = 0, -- time() en que se disparará el AFTER
}
-- ============================================================
-- CONSTRUCCIÓN DEL MAPA LÓGICO
-- Por habitación se construye una matriz [x][y] con el tipo de
@@ -383,6 +401,12 @@ function pintar_habitacion()
end
end
-- Perro (si está activo y comparte habitación con el ladrón)
if perro.activo and perro.rm == rm then
color(COL_PERRO, paper)
print(chr(GL_PERRO), perro.x + off_x, perro.y + off_y)
end
-- El ladrón
color(COL_LADRON, paper)
print(chr(hombre_glifo), xp + off_x, yp + off_y)
@@ -487,7 +511,73 @@ function chocar_obstaculo()
mensaje_msg = "Choque"
if ruido >= RUIDO_UMBRAL and retardo > RETARDO_MIN then
retardo = retardo - RETARDO_STEP
-- La activación del perro en sí la maneja la Fase 4.
-- AFTER retardo*4, 1 GOSUB 310 (línea 2160 del original)
programar_perro(retardo * 4 * MS_POR_JIFFY)
end
end
-- ============================================================
-- PERRO GUARDIÁN (líneas 310-330, 1650, 2560-2670 del original)
-- ============================================================
function programar_perro(ms)
perro.pendiente = true
perro.pend_t = time() + ms
end
-- Rutina 310 del original: activa el perro si no lo estaba ya.
function activar_perro()
if perro.activo then return end
perro.activo = true
perro.rm = rm
perro.x = HABITACIONES[rm].minx
perro.y = HABITACIONES[rm].miny
perro.paso = 0
hombre_glifo = GL_LADRON_M -- línea 2570: hombre$ = chr(225)
end
function hay_perro_en(rm_, x, y)
return perro.activo and perro.rm == rm_ and perro.x == x and perro.y == y
end
-- Rutina 2560 del original: el perro se mueve 1 char hacia el jugador.
function mover_perro()
if not perro.activo then return end
if perro.rm ~= rm then return end -- solo activo en su habitación
-- Si ya está sobre el jugador, mordido (línea 2580)
if perro.x == xp and perro.y == yp then
muerto = true
return
end
if perro.x < xp then perro.x = perro.x + 1
elseif perro.x > xp then perro.x = perro.x - 1 end
if perro.y < yp then perro.y = perro.y + 1
elseif perro.y > yp then perro.y = perro.y - 1 end
if perro.x == xp and perro.y == yp then
muerto = true
return
end
sfx_ladrido()
end
-- Llamada después de cada movimiento exitoso del jugador (línea 1650).
function tick_perro_post_jugador()
if not perro.activo then return end
if perro.rm ~= rm then return end
perro.paso = (perro.paso + 1) % PERRO_RATIO
if perro.paso == 0 then
mover_perro()
end
end
-- Llamada cada frame: dispara la activación si ha vencido el AFTER.
function tick_perro_pendiente()
if perro.pendiente and time() >= perro.pend_t then
perro.pendiente = false
activar_perro()
end
end
@@ -497,6 +587,7 @@ end
function sfx_joya() sound(2000, 6) end
function sfx_obstaculo(r) sound(3000, 5 + r) end
function sfx_conm() sound(800, 3) end
function sfx_ladrido() sound(rnd(40) + 60, 6) end
-- ============================================================
-- MOVIMIENTO Y CAMBIO DE HABITACIÓN
@@ -553,6 +644,13 @@ end
function mover_jugador(xf, yf)
if xf == 0 and yf == 0 then return end
local nx, ny = xp + xf, yp + yf
-- Perro (gol=11): si la celda destino tiene el perro, mordido directo
if hay_perro_en(rm, nx, ny) then
muerto = true
return
end
local t = mapa[rm][nx][ny]
-- Conmutador (gol=1..4): toggle luz, no se mueve
@@ -588,6 +686,7 @@ function mover_jugador(xf, yf)
xp, yp = nx, ny
recoger_joyas_en(nx, ny)
mensaje_msg = ""
tick_perro_post_jugador()
return
end
@@ -597,15 +696,10 @@ function mover_jugador(xf, yf)
return
end
-- Perro (gol=11): mordido (Fase 4 implementa la consecuencia)
if t == T_PERRO then
muerto = true
return
end
-- Vacío: mover
xp, yp = nx, ny
mensaje_msg = ""
tick_perro_post_jugador()
end
-- ============================================================
@@ -625,6 +719,10 @@ function init()
yp = 4
escapado = false
muerto = false
hombre_glifo = GL_LADRON
perro.activo = false
perro.pendiente = false
perro.paso = 0
cls()
end
@@ -638,6 +736,8 @@ function update()
return
end
tick_perro_pendiente()
if (cnt() - ultimo_tic) >= TICS_JUGADOR then
local xf, yf = 0, 0
if btn(KEY_UP) then yf = -1