-- Pepe Runner — port a ascii/Lua del joc original en Turbo Pascal (JailDesigner, 2000) -- Fase 3: gravetat, escales, cordes, forats -- Codis CP437 dels sprites del joc original (de TIPOS.PAS) BUIT = 0 DINERS = 36 -- $ PEDRA = 219 -- bloc solid ESCALA = 205 -- ═ (linia doble horitzontal, formant graons d'escala) CORDA = 196 -- ─ (linia simple horitzontal) BLOC1 = 176 -- ░ BLOC2 = 177 -- ▒ BLOC3 = 178 -- ▓ PEPE_C = 2 -- sprite del Pepe MALO_C = 88 -- 'X' enemics -- Colors (de TIPOS.PAS, paleta CGA — coincideix amb la d'ascii) COL_PEDRA = COLOR_BROWN -- 6 COL_DINERS = COLOR_YELLOW -- 14 COL_ESCALA = COLOR_LIGHT_GRAY -- 7 COL_CORDA = COLOR_LIGHT_GRAY -- 7 COL_BUIT = COLOR_BLACK -- 0 -- Estats del Pepe (com en TIPOS.PAS) NORMAL = 0 CAENT = 4 -- Constants del joc MAP_W = 40 MAP_H = 25 BLOC_OUT = 100 -- temps que dura un forat obert (de TIPOS.PAS) TICS = 6 -- frames per tick de joc (60fps / 6 = 10 Hz) -- Estat global mapa = {} -- mapa[x][y] = { tipo=, color=, temps= } level = 1 pepe = { x=19, y=23, dibuix=PEPE_C, color=COLOR_WHITE, vides=0, estat=NORMAL } score = 0 diners_pantalla = 0 function definir_glifs() setchar(BUIT, 0,0,0,0,0,0,0,0) setchar(PEDRA, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF) setchar(DINERS, 0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00) setchar(ESCALA, 0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00) setchar(CORDA, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00) setchar(BLOC1, 0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11) setchar(BLOC2, 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55) setchar(BLOC3, 0xBB,0xEE,0xBB,0xEE,0xBB,0xEE,0xBB,0xEE) setchar(PEPE_C, 0x7E,0x81,0xA5,0x81,0xBD,0x99,0x81,0x7E) setchar(MALO_C, 0x00,0xC3,0x66,0x3C,0x18,0x3C,0x66,0xC3) end function color_de(tipo) if tipo == PEDRA then return COL_PEDRA end if tipo == DINERS then return COL_DINERS end if tipo == ESCALA then return COL_ESCALA end if tipo == CORDA then return COL_CORDA end return COL_BUIT end -- Helper segur per llegir el tipus d'una cel·la (fora de mapa = pedra virtual) function tipo_a(x, y) if x < 0 or x >= MAP_W or y < 0 or y >= MAP_H then return PEDRA end return mapa[x][y].tipo end function carregar_mapa(num) filein("maps/"..tostr(num)..".map", 0, MAP_W*MAP_H) diners_pantalla = 0 for x = 0, MAP_W-1 do mapa[x] = {} for y = 0, MAP_H-1 do local tipo = peek(x*MAP_H + y) mapa[x][y] = { tipo=tipo, color=color_de(tipo), temps=-1 } if tipo == DINERS then diners_pantalla = diners_pantalla + 1 end end end 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 ~= BUIT then color(c.color, COL_BUIT) print(chr(c.tipo), x, y) end end end end function pintar_pepe() color(pepe.color, COL_BUIT) print(chr(pepe.dibuix), pepe.x, pepe.y) end -- Marca una cel·la com a forat (sols si actualment es pedra) function foradar(x, y) if tipo_a(x, y) == PEDRA then mapa[x][y].temps = BLOC_OUT end end -- Pot Pepe cavar a esquerra/dreta? Condicions del MouPepe original: -- - la cel·la diagonal-baix ha de ser pedra (per a obrir-hi forat) -- - la cel·la lateral no pot ser pedra (per a que Pepe s'hi puga assomar) -- - Pepe ha d'estar en estat normal (no caent) function pot_cavar(dx) return pepe.estat == NORMAL and tipo_a(pepe.x+dx, pepe.y+1) == PEDRA and tipo_a(pepe.x+dx, pepe.y) ~= PEDRA end -- Tic de joc del Pepe: input de moviment, gravetat, recollir diners, emparedat function tic_pepe() local actual = tipo_a(pepe.x, pepe.y) local sotto = tipo_a(pepe.x, pepe.y+1) -- Moviment vertical: Q/A (com en RUNNER.PAS, son if/else) if btn(KEY_Q) then if actual == ESCALA then pepe.y = pepe.y - 1 end elseif btn(KEY_A) then if sotto == ESCALA or sotto == BUIT or sotto == DINERS then pepe.y = pepe.y + 1 end end -- Moviment horitzontal: O/P (no es pot moure si esta caent) if btn(KEY_O) then if tipo_a(pepe.x-1, pepe.y) ~= PEDRA and pepe.estat ~= CAENT then pepe.x = pepe.x - 1 end elseif btn(KEY_P) then if tipo_a(pepe.x+1, pepe.y) ~= PEDRA and pepe.estat ~= CAENT then pepe.x = pepe.x + 1 end end -- Si no passa res especial, estat = normal (gravetat pot canviar-ho mes avall) pepe.estat = NORMAL -- Emparedat: si la cel·la actual s'ha tornat pedra, Pepe mor if tipo_a(pepe.x, pepe.y) == PEDRA then mort_pepe() return end -- Recollir diners if tipo_a(pepe.x, pepe.y) == DINERS then mapa[pepe.x][pepe.y].tipo = BUIT score = score + 1 diners_pantalla = diners_pantalla - 1 end -- Bordes X if pepe.x < 0 then pepe.x = 0 end if pepe.x > MAP_W-1 then pepe.x = MAP_W-1 end -- Gravetat: si la cel·la actual es buit/diners i la de baix no es escala/pedra → cau actual = tipo_a(pepe.x, pepe.y) sotto = tipo_a(pepe.x, pepe.y+1) if (sotto ~= ESCALA and sotto ~= PEDRA) and (actual == BUIT or actual == DINERS) then pepe.y = pepe.y + 1 pepe.estat = CAENT end -- Bordes Y if pepe.y < 0 then pepe.y = 0 end if pepe.y > MAP_H-1 then pepe.y = MAP_H-1 end end -- De moment, mort = respawn (vides i game over van en la Fase 5) function mort_pepe() pepe.vides = pepe.vides - 1 pepe.x = 19 pepe.y = 23 pepe.estat = NORMAL end -- Anima els forats: decrementa temps i cambia el tipus segons la fase -- (idem case statement de CheckMapa al RUNNER.PAS) function check_mapa() for x = 0, MAP_W-1 do for y = 0, MAP_H-1 do local c = mapa[x][y] local t = c.temps if t == 0 then c.temps = -1 c.tipo = PEDRA c.color = COL_PEDRA elseif t == 1 or t == BLOC_OUT-1 then c.tipo = BLOC3; c.color = COL_PEDRA; c.temps = t - 1 elseif t == 2 or t == BLOC_OUT-2 then c.tipo = BLOC2; c.color = COL_PEDRA; c.temps = t - 1 elseif t == 3 or t == BLOC_OUT-3 then c.tipo = BLOC1; c.color = COL_PEDRA; c.temps = t - 1 elseif t == 4 or t == BLOC_OUT-4 then c.tipo = BUIT; c.color = COL_BUIT; c.temps = t - 1 elseif t > 0 then c.temps = t - 1 end -- t == -1 → idle, no fer res end end end function init() mode(1) border(COLOR_BLUE) color(COLOR_LIGHT_GRAY, COLOR_BLACK) definir_glifs() carregar_mapa(level) 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 end -- Logica del joc: cada TICS frames if (cnt() % TICS) == 0 then tic_pepe() check_mapa() end -- Render: cada frame cls() pintar_mapa() pintar_pepe() end