Fase 1: estructura base i les 5 habitacions
This commit is contained in:
+8
-1
@@ -31,7 +31,7 @@ $RECYCLE.BIN/
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
@@ -67,3 +67,10 @@ Temporary Items
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
# ---> Guante Blanco
|
||||
# Binari de l'intèrpret ascii (es compila a part)
|
||||
/ascii
|
||||
# Fitxer de rècord generat pel joc
|
||||
/records
|
||||
|
||||
|
||||
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
# ASCII — Referencia del intérprete Lua
|
||||
|
||||
Documento extraído del código fuente en `c:/mingw/gitea/ascii/` (principalmente `ascii.cpp`, `lua.cpp`, `play.cpp`, `ascii.h`). Sirve como guía para portar Pepe Runner desde Turbo Pascal a Lua.
|
||||
|
||||
> Versión analizada del intérprete: v0.6.1 aprox (según el mensaje del boot ROM en `lua.cpp`).
|
||||
|
||||
---
|
||||
|
||||
## 1. Modelo de ejecución
|
||||
|
||||
Cada juego/programa es **un solo fichero `.lua`** que define dos funciones globales:
|
||||
|
||||
```lua
|
||||
function init()
|
||||
-- se llama una sola vez al arrancar
|
||||
end
|
||||
|
||||
function update()
|
||||
-- se llama cada frame (~60 FPS, vsync)
|
||||
end
|
||||
```
|
||||
|
||||
- El intérprete se invoca como `ascii.exe nombre_juego.lua`. Si no se pasa argumento, intenta cargar `game.lua`.
|
||||
- También se puede **arrastrar y soltar** un `.lua` sobre la ventana para cargarlo.
|
||||
- **F5** reinicia el juego (re-llama a `init()` y vuelve a empezar el bucle).
|
||||
- **ESC** pausa la ejecución y abre una consola de depuración (`> ` prompt). Los comandos `run` y `cont` la cierran. Comandos prefijados con `?` evalúan e imprimen (ej.: `?1+1`).
|
||||
- Se usa la versión estándar de Lua que está vendorizada en `ascii/lua/` (con `luaL_openlibs`), así que están disponibles `string`, `math`, `table`, etc.
|
||||
|
||||
---
|
||||
|
||||
## 2. Modos de pantalla — `mode(n)`
|
||||
|
||||
| Modo | Resolución carácter | Resolución pixel | Notas |
|
||||
|------|--------------------:|-----------------:|-------|
|
||||
| 0 | 80 × 30 | 640 × 240 | Color único global (no por-carácter) — usado para depuración / texto. `current_color` aplica a toda la pantalla. |
|
||||
| 1 | 40 × 30 | 320 × 240 | **Modo por defecto.** Color por carácter. |
|
||||
| 2 | 20 × 15 | 160 × 120 | Mitad de resolución. Cómodo para tiles grandes (ej.: sokoban). |
|
||||
| 3 | 32 × 24 | 256 × 192 | Estilo "ZX Spectrum" (con bordes anchos). |
|
||||
|
||||
Cada carácter es **8×8 píxeles**. Los gráficos son texto coloreado, no píxeles libres — el "lienzo" es una matriz de celdas (carácter + atributo de color).
|
||||
|
||||
---
|
||||
|
||||
## 3. Paleta de colores (16, CGA/EGA)
|
||||
|
||||
Constantes Lua predefinidas (`lua.cpp` líneas 610-625):
|
||||
|
||||
| Código | Constante | Aprox. |
|
||||
|-------:|------------------------|---------------|
|
||||
| 0 | `COLOR_BLACK` | #000000 |
|
||||
| 1 | `COLOR_BLUE` | #0000AA |
|
||||
| 2 | `COLOR_GREEN` | #00AA00 |
|
||||
| 3 | `COLOR_CYAN` | #00AAAA |
|
||||
| 4 | `COLOR_RED` | #AA0000 |
|
||||
| 5 | `COLOR_MAGENTA` | #AA00AA |
|
||||
| 6 | `COLOR_BROWN` | #AA5500 |
|
||||
| 7 | `COLOR_LIGHT_GRAY` | #AAAAAA |
|
||||
| 8 | `COLOR_DARK_GRAY` | #555555 |
|
||||
| 9 | `COLOR_LIGHT_BLUE` | #5555FF |
|
||||
| 10 | `COLOR_LIGHT_GREEN` | #55FF55 |
|
||||
| 11 | `COLOR_LIGHT_CYAN` | #55FFFF |
|
||||
| 12 | `COLOR_LIGHT_RED` | #FF5555 |
|
||||
| 13 | `COLOR_LIGHT_MAGENTA` | #FF55FF |
|
||||
| 14 | `COLOR_YELLOW` | #FFFF55 |
|
||||
| 15 | `COLOR_WHITE` | #FFFFFF |
|
||||
|
||||
El atributo de color de una celda es 1 byte: nibble bajo = INK (tinta), nibble alto = PAPER (fondo).
|
||||
|
||||
---
|
||||
|
||||
## 4. API — Funciones expuestas a Lua
|
||||
|
||||
### Pantalla y color
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `mode(n)` | Cambia modo de pantalla (0-3) y hace cls. |
|
||||
| `cls([chr=32])` | Limpia con el carácter dado (32 = espacio). En modo ≠0 además rellena el color attr. |
|
||||
| `ink(c)` | Color de tinta (0-15). |
|
||||
| `paper(c)` | Color de fondo (0-15). |
|
||||
| `border(c)` | Color del borde de la ventana. |
|
||||
| `color(ink, paper, [border])` | Combina los tres. |
|
||||
| `locate(x, y)` | Posiciona cursor en celda (x, y). |
|
||||
| `print(str, [x, y])` | Imprime `str` (sin salto de línea). Si se dan x,y, primero hace `locate`. |
|
||||
| `crlf()` | CR + LF (mueve cursor a inicio de siguiente línea). |
|
||||
|
||||
### Entrada
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `btn(k)` | `true` si la tecla `k` está pulsada *en este frame* (estado SDL_GetKeyboardState). |
|
||||
| `btnp(k)` | `true` solo en el frame en que la tecla se pulsa (edge). |
|
||||
| `mousex()` / `mousey()` | Posición del ratón en **coordenadas de carácter** (ya escalado al modo). |
|
||||
| `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_*`.
|
||||
|
||||
> **Bug de `tostr` con negativos**: la implementación de `tostr()` en `lua.cpp` (función `intToStr`) hace `(x % 10) + '0'` que con `x = -1` produce `-1 + 48 = 47`, o sea `'/'`. Por tanto `tostr(-1)` devuelve `"/"`, `tostr(-2)` devuelve `"."`, etc. Si vas a imprimir un número que puede ser negativo, usa `string.format("%d", n)` (que sí maneja signo) o clampa con `max(0, n)` antes de pasar a `tostr`.
|
||||
|
||||
Códigos de tecla — todos definidos como globales `KEY_*` en Lua. Lista completa (de `lua.cpp` 502-608):
|
||||
|
||||
```
|
||||
KEY_A..KEY_Z = 4..29
|
||||
KEY_1..KEY_0 = 30..39 (1=30, 2=31, ..., 9=38, 0=39)
|
||||
KEY_RETURN=40 KEY_ESCAPE=41 KEY_BACKSPACE=42 KEY_TAB=43 KEY_SPACE=44
|
||||
KEY_MINUS=45 KEY_EQUALS=46 KEY_LEFTBRACKET=47 KEY_RIGHTBRACKET=48
|
||||
KEY_BACKSLASH=49 KEY_NONUSHASH=50 KEY_SEMICOLON=51 KEY_APOSTROPHE=52
|
||||
KEY_GRAVE=53 KEY_COMMA=54 KEY_PERIOD=55 KEY_SLASH=56 KEY_CAPSLOCK=57
|
||||
KEY_F1..KEY_F12 = 58..69
|
||||
KEY_PRINTSCREEN=70 KEY_SCROLLLOCK=71 KEY_PAUSE=72
|
||||
KEY_INSERT=73 KEY_HOME=74 KEY_PAGEUP=75 KEY_DELETE=76 KEY_END=77 KEY_PAGEDOWN=78
|
||||
KEY_RIGHT=79 KEY_LEFT=80 KEY_DOWN=81 KEY_UP=82
|
||||
KEY_NUMLOCKCLEAR=83 KEY_KP_DIVIDE=84 KEY_KP_MULTIPLY=85 KEY_KP_MINUS=86 KEY_KP_PLUS=87 KEY_KP_ENTER=88
|
||||
KEY_KP_1..KEY_KP_0 = 89..98 KEY_KP_PERIOD=99
|
||||
KEY_NONUSBACKSLASH=100 KEY_APPLICATION=101
|
||||
KEY_LCTRL=224 KEY_LSHIFT=225 KEY_LALT=226 KEY_LGUI=227
|
||||
KEY_RCTRL=228 KEY_RSHIFT=229 KEY_RALT=230 KEY_RGUI=231
|
||||
```
|
||||
|
||||
(Son los SDL2 scancodes.)
|
||||
|
||||
### Matemáticas
|
||||
|
||||
`abs(x)`, `ceil(x)`, `flr(x)`, `sgn(x)`, `sin(x)`, `cos(x)`, `atan2(dx, dy)`, `sqrt(x)`, `max(a,b)`, `min(a,b)`, `mid(a,b,c)` (devuelve el del medio, equivalente a `clamp`).
|
||||
|
||||
`rnd(n)` devuelve un entero en `[0, n-1]` (`rand()%n`). `srand(seed)` siembra el RNG.
|
||||
|
||||
### Strings
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `tostr(v)` | Convierte valor a string. Soporta nil, function, table (formato `{k=v,...}`), number, boolean, string. |
|
||||
| `strlen(s)` | Longitud en bytes. |
|
||||
| `ascii(s, i)` | Código del byte en índice `i` (0-based). |
|
||||
| `chr(n)` | String de un solo carácter cuyo código es `n`. |
|
||||
| `substr(s, start, length)` | Subcadena. |
|
||||
|
||||
> Nota: Lua estándar también está disponible, así que `string.format`, `string.sub`, etc., funcionan. Pero los demos usan estas helpers.
|
||||
|
||||
### Memoria
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `peek(addr)` | Lee 1 byte de la VRAM/memoria (0..0x1FFF). |
|
||||
| `poke(addr, val)` | Escribe 1 byte. |
|
||||
| `memcpy(dst, src, size)` | Copia bytes en la memoria del fantasy console. |
|
||||
| `setchar(idx, b0..b7)` | Define los 8 bytes del carácter `idx` en el char-ROM (sobrescribe la fuente). |
|
||||
|
||||
**Mapa de memoria** (8 KB total, `mem[8192]`):
|
||||
|
||||
- `0x0000` (0): char_screen (matriz de códigos de carácter por celda)
|
||||
- Tras char_screen viene color_screen (offset = `screen_width * screen_height`)
|
||||
- `0x0A00` (2560 = `MEM_CHAR_OFFSET`): char-ROM (definición de glifos, 8 bytes por carácter, 256 chars = 2048 bytes)
|
||||
- `0x1200` (4608 = `MEM_BOOT_OFFSET`): zona de boot/recursos de ROM
|
||||
|
||||
Para los modos 1 y 2 los color_screen offsets son 1200 y 300 respectivamente; en modo 3 es 768; en modo 0 no hay color_screen por celda (color global).
|
||||
|
||||
### Audio
|
||||
|
||||
**Sonido simple:**
|
||||
- `sound(freq, len)` — onda cuadrada a `freq` Hz durante `len` (en algo similar a centésimas de segundo; `audio_len = len*44.1`).
|
||||
- `nosound()` — silencio inmediato.
|
||||
|
||||
**Mini-lenguaje MML — `play(str)`:**
|
||||
|
||||
Sintaxis tipo BASIC `PLAY` / MML. Tokens (case-sensitive, minúsculas):
|
||||
|
||||
| Token | Significado |
|
||||
|-------|-------------|
|
||||
| `c d e f g a b` | Nota. Acepta sufijo `#` o `+` (sostenido) o `-` (bemol). Luego dígito 0-9 para duración. |
|
||||
| `r` | Silencio. Acepta dígito de duración. |
|
||||
| `o<0-7>` | Octava absoluta. |
|
||||
| `>` `<` | Sube / baja octava. |
|
||||
| `l<0-9>` | Longitud por defecto para notas sin duración. |
|
||||
| `v<0-9>` | Volumen (se traduce a `(d-0)<<4`). |
|
||||
| `t<0-9>` | Tempo. |
|
||||
|
||||
Duraciones: índice 0-9 → tabla `{313,625,938,1250,1875,2500,3750,5000,7500,10000}` (de "redonda" a "trentaidosava", aproximadamente).
|
||||
|
||||
Ejemplo (de `breakout.lua`):
|
||||
|
||||
```lua
|
||||
play("l0o3bagfedc") -- escala descendente como sonido de game-over
|
||||
play("o5l0c") -- pitido agudo (rebote)
|
||||
```
|
||||
|
||||
### Ficheros y portapapeles
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `load([filename])` | Reinicia y carga otro `.lua` (o el mismo si filename=nil). |
|
||||
| `fileout(name, addr, size)` | Vuelca `size` bytes de memoria a un binario. |
|
||||
| `filein(name, addr, size)` | Carga un binario a memoria. |
|
||||
| `toclipboard(str)` | Copia al portapapeles del SO. |
|
||||
| `fromclipboard()` | Lee del portapapeles (máx 1023 chars). |
|
||||
|
||||
### Utilidades de tiempo / frame
|
||||
|
||||
| Función | Descripción |
|
||||
|---------|-------------|
|
||||
| `time()` | Milisegundos desde inicio (`SDL_GetTicks()`). |
|
||||
| `cnt()` | Contador de frames desde el último `rst()`. |
|
||||
| `rst()` | Resetea el contador de frames a 0. |
|
||||
| `log(str)` | Imprime en la consola de debug (no en pantalla). |
|
||||
|
||||
---
|
||||
|
||||
## 5. Caracteres especiales útiles
|
||||
|
||||
Los demos usan códigos > 127 que corresponden a glifos definidos en `rom.c` (el char-ROM por defecto). Algunos vistos:
|
||||
|
||||
- `\003` (3) — un bloque relleno (usado en pong para los compases)
|
||||
- `\016` (16) — cubo de caja (en sokoban)
|
||||
- `\127` (127) — pared en sokoban (redefinido con `setchar(127, ...)`)
|
||||
- `\143`, `\154`, `\150`, `\156`, `\149` — esquinas y trazos de marcos
|
||||
- `\248`, `\250`, `\251` — sprite animado de "OK" en sokoban
|
||||
- `\233` — pelota en breakout
|
||||
- `\131` — pala en breakout
|
||||
- `\001` — cubo de tetromino (redefinido con `setchar(1, 0xff,0x81,...)`)
|
||||
|
||||
Para usarlos siempre se puede hacer `setchar(idx, b0..b7)` con la bitmap deseada y luego imprimirlo con `print(chr(idx), x, y)`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Patrón típico de un juego
|
||||
|
||||
```lua
|
||||
function init()
|
||||
mode(1)
|
||||
cls()
|
||||
-- estado inicial
|
||||
player = {x=10, y=15}
|
||||
score = 0
|
||||
end
|
||||
|
||||
function update()
|
||||
-- input
|
||||
if btnp(KEY_LEFT) then player.x = player.x - 1 end
|
||||
if btnp(KEY_RIGHT) then player.x = player.x + 1 end
|
||||
|
||||
-- lógica
|
||||
-- ...
|
||||
|
||||
-- render (no hay vsync explícito; el bucle ya hace flip al final)
|
||||
cls()
|
||||
color(COLOR_WHITE, COLOR_BLACK)
|
||||
print("\248", player.x, player.y)
|
||||
print("SCORE: "..tostr(score), 0, 0)
|
||||
end
|
||||
```
|
||||
|
||||
**Cosas a recordar:**
|
||||
|
||||
- No se "pintan" píxeles; se imprime un código de carácter en una celda y se le asocia un atributo de color (ink + paper). Para gráficos personalizados, redefinir glifos con `setchar`.
|
||||
- El bucle de render lo hace el motor C++ después de `update()` — no hay que llamar a ningún `flip`.
|
||||
- El `state machine` típico se hace asignando `update = otra_funcion` (ver `demos/sokoban.lua`).
|
||||
- Las coordenadas de pantalla son **enteras y por celda**, no por píxel. (0,0) es esquina superior izquierda.
|
||||
- Para depurar: `log("mensaje")` o pulsar ESC y usar la consola con `?variable`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Cómo compilar el intérprete
|
||||
|
||||
Desde `c:/mingw/gitea/ascii/`:
|
||||
|
||||
```sh
|
||||
make windows
|
||||
```
|
||||
|
||||
Requiere MinGW (g++) y SDL2 para Windows. Produce `ascii.exe`. Para correr Pepe Runner:
|
||||
|
||||
```sh
|
||||
ascii.exe pepe_runner.lua
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@@ -0,0 +1,318 @@
|
||||
10 'GUANTE BLANCO, por David Radisic
|
||||
20 'copyright (c) AMSOFT 1985
|
||||
30 '
|
||||
40 MODE 0:INK 0,0:BORDER 0:INK 1,26:INK 2,15:INK 3,25
|
||||
50 INK 4,14:INK 5,24,12:INK 6,0:INK 7,0:INK 8,0:PAPER #1, 7
|
||||
60 retardo=200
|
||||
70 DIM objx(5,20),objy(5,20),joyax(5,20),joyay(5,20)
|
||||
80 GOSUB 380
|
||||
90 GOSUB 720
|
||||
100 pausa=200:GOSUB 340
|
||||
110 IF joyas=0 THEN GOSUB 980
|
||||
120 PEN 4
|
||||
130 FOR i=10 TO 12
|
||||
140 LOCATE 15,i:PRINT"BOTIN";
|
||||
150 NEXT
|
||||
160 PAPER 0:CLS#2:PAPER 8
|
||||
170 GOSUB 1180
|
||||
180 GOSUB 1240
|
||||
190 GOSUB 1380
|
||||
200 GOSUB 1520
|
||||
210 IF rm=0 THEN GOSUB 1910
|
||||
220 IF muerto=0 THEN 160
|
||||
230 pausa=100:GOSUB 340
|
||||
240 PAPER 0:CLS:PEN 1
|
||||
250 LOCATE 4,3:PRINT"Quiere jugar";
|
||||
260 LOCATE 5,5:PRINT"otra vez?";
|
||||
270 PEN 5:LOCATE 7,7:PRINT"S/N";
|
||||
280 i$=UPPER$(INKEY$):IF i$<>"S" AND i$<>"N" THEN 280
|
||||
290 IF i$="N" THEN MODE 2:PEN 1:STOP
|
||||
300 RUN
|
||||
310 IF perro=1 THEN RETURN
|
||||
320 perro=1:perrox=minx(rm):perroy=miny(rm)
|
||||
330 RETURN
|
||||
340 FOR bucle=1 TO pausa
|
||||
350 FRAME
|
||||
360 NEXT
|
||||
370 RETURN
|
||||
380 rm=1:xp=6:yp=4:hombre$=CHR$(224):perro=0:robado=0
|
||||
390 SYMBOL 240,8,8,8,8,8,8,8,8
|
||||
400 SYMBOL 241,0,0,0,0,255,0,1,0
|
||||
410 SYMBOL 242,0,0,0,0,15,8,8,8
|
||||
420 SYMBOL 243,0,0,0,0,248,8,8,8
|
||||
430 SYMBOL 244,8,8,8,8,248,0,0,0
|
||||
440 SYMBOL 245,8,8,8,8,15,0,0,0
|
||||
450 SYMBOL 246,8,12,13,14,12,12,8,8
|
||||
460 SYMBOL 247,8,12,12,14,13,12,9,8
|
||||
470 SYMBOL 248,8,24,88,56,24,24,8,8
|
||||
480 SYMBOL 249,8,24,24,56,88,24,8,8
|
||||
490 SYMBOL 250,0,0,255,129,129,129,255,0
|
||||
500 SYMBOL 251,28,20,20,20,20,20,20,28
|
||||
510 SYMBOL 252,0,0,255,255,255,255,255,0
|
||||
520 SYMBOL 253,28,28,28,28,28,28,28,28
|
||||
530 SYMBOL 255,195,165,60,126,90,60,36,24
|
||||
540 ENT 1,12,-4,1
|
||||
550 ENT -2,=1000,60,=3000,40
|
||||
560 ENV 1,10,1,5,2,-4,1,2,-1,20
|
||||
570 vent$(1)=STRING$(2,250):vent$(2)=CHR$(251)+CHR$(8)+CHR$(10)+CHR$(251)+CHR$(8)+CHR$(10)+CHR$(251)
|
||||
580 puerta$(1)=STRING$(2,252): puerta$(2)=CHR$(253)+CHR$(8)+CHR$(10)+CHR$(253)+CHR$(8)+CHR$(10)+CHR$(253)
|
||||
590 conm$(1,0)=CHR$(246):conm$(1,1)=CHR$(247)
|
||||
600 conm$(2,0)=CHR$(248):conm$(2,1)=CHR$(249)
|
||||
610 joya$=CHR$(144):obj$=CHR$(233):perro$=CHR$(255)
|
||||
620 gol$=CHR$(246)+CHR$(248)+CHR$(247)+CHR$(249)+CHR$(252)+CHR$(253)+CHR$(250)+CHR$(251)+joya$+obj$+perro$
|
||||
630 RESTORE 3020
|
||||
640 FOR i=1 TO 5
|
||||
650 READ minx(i),miny(i),maxx(i),maxy(i)
|
||||
660 READ dir(i,1),dir(i,2),dir(i,3),dir(i,4)
|
||||
670 NEXT
|
||||
680 WINDOW #1,minx(rm)-1,maxx(rm)+1,miny(rm)-1,maxy(rm)+1
|
||||
690 WINDOW #2,1,14,1,25
|
||||
700 CLS#1:PAPER #0,8
|
||||
710 RETURN
|
||||
720 ORIGIN 50,50
|
||||
730 INK 6,24,12
|
||||
740 RESTORE 3070
|
||||
750 GOSUB 1290
|
||||
760 LOCATE 1,20
|
||||
770 PEN 5:PRINT">";
|
||||
780 PEN 1:PRINT"Puertas y ventanas";
|
||||
790 PEN 5:PRINT"<";:PEN 1
|
||||
800 LOCATE 5,21:PRINT"para escapar";
|
||||
810 LOCATE 9,1:PRINT"PASE":LOCATE 10,2:PRINT CHR$(213)CHR$(212);
|
||||
820 pausa=300:GOSUB 340
|
||||
830 CLS:LOCATE 1,3:INK 6,0
|
||||
840 PEN 1:PRINT hombre$;" Usted, el ladron":PRINT
|
||||
850 PEN 2:PRINT LEFT$(puerta$(1),1);LEFT$(puerta$(2),1);"Puertas":PRINT
|
||||
860 PEN 3:PRINT conm$(1,0);conm$(2,0);" Luces apagadas":PRINT
|
||||
870 PEN 3:PRINT conm$(1,1);conm$(2,1);" Luces encendidas" :PRINT
|
||||
880 PEN 4:PRINT LEFT$(vent$(1),1);LEFT$(vent$(2),1);" Ventanas":PRINT
|
||||
890 PEN 5:PRINT joya$;" Piedras preciosas":PRINT
|
||||
900 PAPER 1:PEN 0:PRINT obj$;" Obstaculos":PEN 1:PAPER 0:PRINT
|
||||
910 PEN 1:PRINT perro$;" El perro"
|
||||
920 PEN 5:PRINT:PRINT:PRINT
|
||||
930 PRINT"Utilice joystick":PRINT"o teclas de cursor"
|
||||
940 aux=REMAIN(1)
|
||||
950 AFTER retardo*4,1 GOSUB 340
|
||||
960 RETURN
|
||||
970 '
|
||||
980 'Generar joyas y obstaculos
|
||||
990 '
|
||||
1000 FOR hab=1 TO 5
|
||||
1010 joyar=INT(RND*8)+2:objr=INT(RND*10)+5
|
||||
1020 minx=minx(hab):miny=miny(hab):maxx=maxx(hab):maxy=maxy(hab)
|
||||
1030 FOR i=1 TO joyar
|
||||
1040 x=INT(RND*(maxx-minx+1))+minx
|
||||
1050 y=INT(RND*(maxy-miny+1))+miny
|
||||
1060 joyax(hab,i)=x:joyay(hab,i)=y
|
||||
1070 joyas=joyas+1
|
||||
1080 NEXT i
|
||||
1090 FOR i=1 TO objr
|
||||
1100 x=INT(RND*(maxx-minx+1))+minx
|
||||
1110 y=INT(RND*(maxy-miny+1))+miny
|
||||
1120 objx(hab,i)=x:objy(hab,i)=y
|
||||
1130 NEXT i
|
||||
1140 joyas(hab)=joyar:obj(hab)=objr
|
||||
1150 NEXT hab
|
||||
1160 CLS
|
||||
1170 RETURN
|
||||
1180 ON rm GOTO 1190,1200,1210,1220,1230
|
||||
1190 RESTORE 2680:RETURN
|
||||
1200 RESTORE 2750:RETURN
|
||||
1210 RESTORE 2820:RETURN
|
||||
1220 RESTORE 2890:RETURN
|
||||
1230 RESTORE 2970:RETURN
|
||||
1240 PAPER 0:READ rm$:PAPER 8
|
||||
1250 WINDOW #1,minx(rm)-1,maxx(rm)+1,miny(rm)-1,maxy(rm)+1:CLS#1
|
||||
1260 PEN 1:LOCATE 1,1:PRINT SPACE$(19);
|
||||
1270 LOCATE 1,1:PRINT"Habitacion: ";rm$;
|
||||
1280 IF luces(rm) THEN INK 7,10:INK 8,10 ELSE INK 7,0:INK 8,0
|
||||
1290 READ a$:IF a$="FIN" THEN RETURN
|
||||
1300 IF a$="D" THEN 2190
|
||||
1310 IF a$="W" THEN 2270
|
||||
1320 IF a$="L" THEN GRAPHICS PEN 1:GOTO 2350
|
||||
1330 IF a$="S" THEN 2430
|
||||
1340 IF a$="F" THEN GRAPHICS PEN 6:GOTO 2350
|
||||
1350 PRINT"***ERROR ***";
|
||||
1360 STOP
|
||||
1370 '
|
||||
1380 'Dibujar joyas/objetos
|
||||
1390 '
|
||||
1400 PEN 6
|
||||
1410 FOR i=1 TO obj(rm)
|
||||
1420 LOCATE objx(rm,i),objy(rm,i)
|
||||
1430 PRINT obj$;
|
||||
1440 NEXT
|
||||
1450 PEN 5
|
||||
1460 FOR i=1 TO joyas(rm)
|
||||
1470 LOCATE joyax(rm,i),joyay(rm,i)
|
||||
1480 PRINT joya$;
|
||||
1490 NEXT
|
||||
1500 PEN 1:LOCATE xp,yp:PRINT hombre$;
|
||||
1510 RETURN
|
||||
1520 xf=0:yf=0:PEN 1
|
||||
1530 IF INKEY(0)<>-1 OR INKEY(72)<>-1 THEN yf=-1
|
||||
1540 IF INKEY(2)<>-1 OR INKEY(73)<>-1 THEN yf=1
|
||||
1550 IF INKEY(8)<>-1 OR INKEY(74)<>-1 THEN xf=-1
|
||||
1560 IF INKEY(1)<>-1 OR INKEY(75)<>-1 THEN xf=1
|
||||
1570 IF xf=0 AND yf=0 THEN 1640
|
||||
1580 LOCATE xp+xf,yp+yf:ht$=COPYCHR$(#0)
|
||||
1590 IF ASC(ht$)>239 AND ASC(ht$)<246 THEN 1520
|
||||
1600 IF ht$<>" " THEN 1670
|
||||
1610 LOCATE xp,yp:PRINT" ";
|
||||
1620 PAPER 0:LOCATE 4,24:PRINT" ";:PAPER 8
|
||||
1630 xp=xp+xf:yp=yp+yf
|
||||
1640 LOCATE xp,yp:PRINT hombre$;
|
||||
1650 IF perro>0 THEN perro=perro MOD 2+1:IF perro=2 THEN 2560
|
||||
1660 GOTO 1520
|
||||
1670 gol=INSTR(gol$,ht$):car=ASC(MID$(gol$,gol,1))
|
||||
1680 ON gol GOTO 1700,1700,1700,1700,1760,1760,1860,1910,1980,2100,2660
|
||||
1690 GOTO 1610
|
||||
1700 IF gol>2 AND gol<5 THEN car=car-1
|
||||
1710 IF gol<3 THEN car=car+1
|
||||
1720 PEN 3:LOCATE xp+xf,yp+yf:PRINT CHR$(car);
|
||||
1730 luces(rm)=luces(rm) XOR 1
|
||||
1740 IF luces(rm) THEN INK 7,10:INK 8,10 ELSE INK 7,0:INK 8,0
|
||||
1750 GOTO 1520
|
||||
1760 IF xf<>0 AND yf<>0 THEN 1640
|
||||
1770 IF xf<0 THEN dir=4 ELSE IF xf>0 THEN dir=3
|
||||
1780 IF yf<0 THEN dir=1 ELSE IF yf>0 THEN dir=2
|
||||
1790 IF dir(rm,dir)=-1 THEN 1640 ELSE rm=dir(rm,dir)
|
||||
1800 IF perro>0 THEN GOSUB 310
|
||||
1810 IF dir=1 THEN xp=6:yp=maxy(rm)
|
||||
1820 IF dir=2 THEN xp=6:yp=miny(rm)
|
||||
1830 IF dir=3 THEN xp=minx(rm):yp=13
|
||||
1840 IF dir=4 THEN xp=maxx(rm):yp=13
|
||||
1850 RETURN
|
||||
1860 IF xp>5 AND xp<8 THEN 1890
|
||||
1870 IF xp<6 THEN dir=4 ELSE dir=3
|
||||
1880 GOTO 1790
|
||||
1890 IF yp>13 THEN dir=2 ELSE dir=1
|
||||
1900 GOTO 1790
|
||||
1910 PAPER 0:CLS:PEN 1
|
||||
1920 LOCATE 3,3:PRINT"Usted ha escapado";
|
||||
1930 LOCATE 8,5:PRINT"con";
|
||||
1940 IF joyas=robado THEN LOCATE 8,7:PRINT"todas las";ELSE LOCATE 8,7
|
||||
1950 PRINT USING" ##";robado;
|
||||
1960 PEN 5:LOCATE 8,9:PRINT"joyas";
|
||||
1970 muerto=1:RETURN
|
||||
1980 LOCATE xp,yp:PRINT" ";:xp=xp+xf:yp=yp+yf
|
||||
1990 i=0
|
||||
2000 i=i+1
|
||||
2010 IF i>joyas(rm) THEN 1520
|
||||
2020 IF joyax(rm,i)<>xp OR joyay(rm,i)<>yp THEN 2000
|
||||
2030 IF i=joyas(rm) THEN 2060
|
||||
2040 joyax(rm,i)=joyax(rm,joyas(rm))
|
||||
2050 joyay(rm,i)=joyay(rm,joyas(rm))
|
||||
2060 joyas(rm)=joyas(rm)-1:robado=robado+1
|
||||
2070 MOVE 400,150+(robado*2),1,1:DRAW 555,150+(robado*2),1,1
|
||||
2080 SOUND 129,248,10,12,0,1
|
||||
2090 GOTO 1990
|
||||
2100 ruido=INT(RND*15)
|
||||
2110 SOUND 1,3000,10,ruido,0,0,10
|
||||
2120 PAPER 0:LOCATE 4,24:PRINT"Choque ";:PAPER 8
|
||||
2130 IF ruido<10 OR retardo=50 THEN 1640
|
||||
2140 retardo=retardo-50
|
||||
2150 aux=REMAIN(1)
|
||||
2160 AFTER retardo*4,1 GOSUB 310
|
||||
2170 GOTO 1640
|
||||
2180 '
|
||||
2190 'Dibujar puertas
|
||||
2200 '
|
||||
2210 READ no,pu$
|
||||
2220 IF pu$="V" THEN pu=2 ELSE pu=1
|
||||
2230 PEN 2
|
||||
2240 pic$=puerta$(pu):GOSUB 2510
|
||||
2250 GOTO 1290
|
||||
2260 '
|
||||
2270 'Dibujar ventanas
|
||||
2280 '
|
||||
2290 READ no,ve$
|
||||
2300 IF ve$="V" THEN ve=2 ELSE ve=1
|
||||
2310 PEN 4
|
||||
2320 pic$=vent$(ve):GOSUB 2510
|
||||
2330 GOTO 1290
|
||||
2340 '
|
||||
2350 'Dibujar rectas
|
||||
2360 '
|
||||
2370 READ x1,y1,x2,y2
|
||||
2380 MOVE x1,y1,0
|
||||
2390 DRAW x1,y2,0:DRAW x2,y2,0
|
||||
2400 DRAW x2,y1,0:DRAW x1,y1,0
|
||||
2410 GOTO 1290
|
||||
2420 '
|
||||
2430 'Dibujar interruptores
|
||||
2440 '
|
||||
2450 READ no,co$
|
||||
2460 IF co$="L" THEN co=1 ELSE co=2
|
||||
2470 PEN 3
|
||||
2480 pic$=conm$(co,0):GOSUB 2510
|
||||
2490 GOTO 1290
|
||||
2500 '
|
||||
2510 'Escribir car
|
||||
2520 '
|
||||
2530 READ x,y:LOCATE x,y:PRINT pic$;
|
||||
2540 no=no-1:IF no>0 THEN 2530
|
||||
2550 RETURN
|
||||
2560 PEN 1:LOCATE perrox,perroy:PRINT" ";
|
||||
2570 hombre$=CHR$(225)
|
||||
2580 IF (perrox=xp AND perroy=yp) OR (perrox=xp+xf AND perroy=yp+yf) THEN 2660
|
||||
2590 IF perrox<xp THEN perrox=perrox+1
|
||||
2600 IF perrox>xp THEN perrox=perrox-1
|
||||
2610 IF perroy<yp THEN perroy=perroy+1
|
||||
2620 IF perroy>yp THEN perroy=perroy-1
|
||||
2630 LOCATE perrox,perroy:PRINT perro$;
|
||||
2640 SOUND 1,0,RND*40,10,1,2,31
|
||||
2650 GOTO 1520
|
||||
2660 PRINT"MORDIDO";
|
||||
2670 muerto=1:RETURN
|
||||
2680 DATA Pasillo
|
||||
2690 DATA L,64,308,226,4
|
||||
2700 DATA D,2,H,6,3,6,22
|
||||
2710 DATA D,2,V,4,12,9,11
|
||||
2720 DATA S,1,L,4,11
|
||||
2730 DATA S,1,R,9,14
|
||||
2740 DATA FIN
|
||||
2750 DATA Sala
|
||||
2760 DATA L,2,308,258,4
|
||||
2770 DATA D,1,V,10,12
|
||||
2780 DATA W,1,H,6,3
|
||||
2790 DATA W,1,V,2,12
|
||||
2800 DATA S,2,R,10,11,10,15
|
||||
2810 DATA FIN
|
||||
2820 DATA Comedor
|
||||
2830 DATA L,2,308,258,4
|
||||
2840 DATA W,1,V,10,12
|
||||
2850 DATA W,1,H,6,3
|
||||
2860 DATA D,1,V,2,12
|
||||
2870 DATA S,2,L,2,11,2,15
|
||||
2880 DATA FIN
|
||||
2890 DATA Cocina
|
||||
2900 DATA L,2,276,384,4
|
||||
2910 DATA D,2,H,6,5,6,22
|
||||
2920 DATA W,1,H,10,22
|
||||
2930 DATA W,1,V,14,13
|
||||
2940 DATA D,1,V,2,13
|
||||
2950 DATA S,1,L,2,16
|
||||
2960 DATA FIN
|
||||
2970 DATA Despensa
|
||||
2980 DATA L,2,276,256,4
|
||||
2990 DATA D,1,V,10,12
|
||||
3000 DATA S,1,R,10,11
|
||||
3010 DATA FIN
|
||||
3020 DATA 5,4,8,21,0,4,3,2
|
||||
3030 DATA 3,4,9,21,-1,-1,1,-1
|
||||
3040 DATA 3,4,9,21,-1,-1,-1,1
|
||||
3050 DATA 3,6,13,21,1,0,-1,5
|
||||
3060 DATA 3,6,9,21,-1,-1,4,-1
|
||||
3070 DATA L,64,308,480,100
|
||||
3080 DATA F,250,98,294,102
|
||||
3090 DATA F,250,306,294,310
|
||||
3100 DATA F,390,94,430,106
|
||||
3110 DATA F,390,302,430,314
|
||||
3120 DATA F,474,240,488,270
|
||||
3130 DATA F,474,124,488,154
|
||||
3140 DATA F,58,240,72,270
|
||||
3150 DATA L,226,308,322,180
|
||||
3160 DATA L,160,180,480,100
|
||||
3170 DATA L,64,180,160,100
|
||||
3180 DATA FIN
|
||||
@@ -0,0 +1,396 @@
|
||||
-- ============================================================
|
||||
-- GUANTE BLANCO — port a la fantasy console "ascii" del original
|
||||
-- de David Radisic para Amstrad CPC (AMSOFT, 1985).
|
||||
-- Sergi Valor, 2026.
|
||||
--
|
||||
-- FASE 1: estructura base. Las 5 habitaciones se dibujan con
|
||||
-- sus paredes, puertas, ventanas y conmutadores. Tecla 1..5
|
||||
-- conmuta la habitación visible para verificar el render.
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- CONFIGURACION
|
||||
-- ============================================================
|
||||
MODO = 3 -- mode(3) = 32x24
|
||||
ANCHO = 32
|
||||
ALTO = 24
|
||||
|
||||
-- Layout (HUD/banners alrededor del área de habitación)
|
||||
FILA_BANNER = 0 -- "Habitacion: X"
|
||||
FILA_MSG = 23 -- mensajes "Choque", "MORDIDO"
|
||||
AREA_Y0 = 1 -- primera fila donde se pinta la habitación
|
||||
AREA_Y1 = 22 -- última fila
|
||||
|
||||
-- ============================================================
|
||||
-- PALETA (mapeo CPC firmware → CGA disponible)
|
||||
-- Original: INK 0,0 (negro) / 1,26 (pastel) / 2,15 (blanco) /
|
||||
-- 3,25 (pastel verde) / 4,14 (amarillo) / 5,24,12 (parpadeo) /
|
||||
-- 6,0 (negro al inicio, luego 24,12) / 7,8 = paper de la habit.
|
||||
-- ============================================================
|
||||
COL_FONDO = COLOR_BLACK
|
||||
COL_LADRON = COLOR_WHITE -- INK 1 pastel
|
||||
COL_PUERTA = COLOR_LIGHT_GRAY -- INK 2 blanco
|
||||
COL_VENTANA = COLOR_YELLOW -- INK 4
|
||||
COL_CONMUT = COLOR_LIGHT_GREEN -- INK 3
|
||||
COL_JOYA = COLOR_LIGHT_RED -- INK 5 (parpadeo en original)
|
||||
COL_OBSTACULO = COLOR_BROWN -- INK 6
|
||||
COL_PERRO = COLOR_WHITE -- INK 1
|
||||
COL_PARED = COLOR_LIGHT_BLUE -- el rectángulo L original era PEN 1 azul
|
||||
COL_PAPER_HAB_ON = COLOR_DARK_GRAY -- paper de la habitación con luz (INK 7,10)
|
||||
COL_PAPER_HAB_OFF = COLOR_BLACK -- paper de la habitación sin luz (INK 7,0)
|
||||
COL_TEXTO = COLOR_LIGHT_GRAY
|
||||
COL_MSG = COLOR_LIGHT_RED
|
||||
|
||||
-- ============================================================
|
||||
-- GLIFOS (códigos que vamos a redefinir con setchar)
|
||||
-- ============================================================
|
||||
GL_LADRON = 224 -- hombre$ = chr(224)
|
||||
GL_LADRON_M = 225 -- ladrón "mordido" (línea 2570 del original)
|
||||
GL_VENT_H = 250 -- ventana horizontal (2 chars)
|
||||
GL_VENT_V = 251 -- ventana vertical (3 chars verticales)
|
||||
GL_PUERTA_H = 252 -- puerta horizontal
|
||||
GL_PUERTA_V = 253 -- puerta vertical
|
||||
GL_PERRO = 255 -- el perro
|
||||
GL_JOYA = 144 -- joya$ = chr(144)
|
||||
GL_OBSTACULO = 233 -- obj$ = chr(233)
|
||||
GL_CONM_L_OFF = 246 -- conm$(1,0)
|
||||
GL_CONM_L_ON = 247 -- conm$(1,1)
|
||||
GL_CONM_R_OFF = 248 -- conm$(2,0)
|
||||
GL_CONM_R_ON = 249 -- conm$(2,1)
|
||||
GL_PARED = 143 -- nuestro char de pared (el original usaba DRAW de líneas)
|
||||
|
||||
-- ============================================================
|
||||
-- TIPOS DE CELDA DEL MAPA
|
||||
-- ============================================================
|
||||
T_VACIO = 0
|
||||
T_PARED = 1
|
||||
T_PUERTA_H = 2
|
||||
T_PUERTA_V = 3
|
||||
T_VENT_H = 4
|
||||
T_VENT_V = 5
|
||||
T_CONM_L = 6
|
||||
T_CONM_R = 7
|
||||
T_JOYA = 8
|
||||
T_OBSTACULO = 9
|
||||
T_PERRO = 10
|
||||
|
||||
-- ============================================================
|
||||
-- DEFINIR GLIFOS (bitmaps idénticos a los SYMBOL del original
|
||||
-- cuando los hay, diseñados a mano cuando vienen del char-ROM
|
||||
-- CPC y no aparecen en el .bas).
|
||||
-- ============================================================
|
||||
function definir_glifos()
|
||||
-- SYMBOL 240..245 del original (partes del sprite del ladrón
|
||||
-- y/o decoración — el código los ignora en colisiones con
|
||||
-- "IF ASC(ht$)>239 AND ASC(ht$)<246 THEN 1520")
|
||||
setchar(240, 8, 8, 8, 8, 8, 8, 8, 8)
|
||||
setchar(241, 0, 0, 0, 0, 255, 0, 1, 0)
|
||||
setchar(242, 0, 0, 0, 0, 15, 8, 8, 8)
|
||||
setchar(243, 0, 0, 0, 0, 248, 8, 8, 8)
|
||||
setchar(244, 8, 8, 8, 8, 248, 0, 0, 0)
|
||||
setchar(245, 8, 8, 8, 8, 15, 0, 0, 0)
|
||||
|
||||
-- SYMBOL 246..249 — conmutadores L/R, on/off (bitmaps literales)
|
||||
setchar(GL_CONM_L_OFF, 8, 12, 13, 14, 12, 12, 8, 8)
|
||||
setchar(GL_CONM_L_ON, 8, 12, 12, 14, 13, 12, 9, 8)
|
||||
setchar(GL_CONM_R_OFF, 8, 24, 88, 56, 24, 24, 8, 8)
|
||||
setchar(GL_CONM_R_ON, 8, 24, 24, 56, 88, 24, 8, 8)
|
||||
|
||||
-- SYMBOL 250..253 — ventanas y puertas (bitmaps literales)
|
||||
setchar(GL_VENT_H, 0, 0, 255, 129, 129, 129, 255, 0)
|
||||
setchar(GL_VENT_V, 28, 20, 20, 20, 20, 20, 20, 28)
|
||||
setchar(GL_PUERTA_H, 0, 0, 255, 255, 255, 255, 255, 0)
|
||||
setchar(GL_PUERTA_V, 28, 28, 28, 28, 28, 28, 28, 28)
|
||||
|
||||
-- SYMBOL 255 — el perro (bitmap literal del original)
|
||||
setchar(GL_PERRO, 195, 165, 60, 126, 90, 60, 36, 24)
|
||||
|
||||
-- chr 224 (ladrón normal) y 225 (ladrón mordido): el original usaba
|
||||
-- las caritas del char-ROM CPC tal cual. En ascii el charset trae
|
||||
-- esas mismas caritas en los mismos códigos, así que no se redefinen.
|
||||
|
||||
-- Pared: bloque sólido para el rectángulo L del original
|
||||
setchar(GL_PARED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- DEFINICIÓN DE LAS 5 HABITACIONES
|
||||
-- Coordenadas tomadas LITERALMENTE de las DATAs del bombardero.bas:
|
||||
-- - minx, miny, maxx, maxy: interior (líneas 3020-3060)
|
||||
-- - puertas D y ventanas W: posición en pared (líneas 2680-3010)
|
||||
-- - conmutadores S: posición en pared, orient L/R
|
||||
-- - dir: N, S, E, O (-1 = bloqueado, 0 = escape, n = id habitación)
|
||||
-- ============================================================
|
||||
HABITACIONES = {
|
||||
[1] = {
|
||||
nombre = "Pasillo",
|
||||
minx = 5, miny = 4, maxx = 8, maxy = 21,
|
||||
elementos = {
|
||||
{ tipo="puerta_h", x=6, y=3 }, -- N: a dir[1]=0 (escape)
|
||||
{ tipo="puerta_h", x=6, y=22 }, -- S: a dir[2]=4 (Cocina)
|
||||
{ tipo="puerta_v", x=4, y=12 }, -- O: a dir[4]=2 (Sala)
|
||||
{ tipo="puerta_v", x=9, y=11 }, -- E: a dir[3]=3 (Comedor)
|
||||
{ tipo="conm", x=4, y=11, orient="L", on=false },
|
||||
{ tipo="conm", x=9, y=14, orient="R", on=false },
|
||||
},
|
||||
dir = { 0, 4, 3, 2 }, -- N, S, E, O
|
||||
luz = false,
|
||||
},
|
||||
[2] = {
|
||||
nombre = "Sala",
|
||||
minx = 3, miny = 4, maxx = 9, maxy = 21,
|
||||
elementos = {
|
||||
{ tipo="puerta_v", x=10, y=12 }, -- E: a dir[3]=1 (Pasillo)
|
||||
{ tipo="vent_h", x=6, y=3 }, -- N (bloqueado, dir[1]=-1)
|
||||
{ tipo="vent_v", x=2, y=12 }, -- O (bloqueado, dir[4]=-1)
|
||||
{ tipo="conm", x=10, y=11, orient="R", on=false },
|
||||
{ tipo="conm", x=10, y=15, orient="R", on=false },
|
||||
},
|
||||
dir = { -1, -1, 1, -1 },
|
||||
luz = false,
|
||||
},
|
||||
[3] = {
|
||||
nombre = "Comedor",
|
||||
minx = 3, miny = 4, maxx = 9, maxy = 21,
|
||||
elementos = {
|
||||
{ tipo="vent_v", x=10, y=12 }, -- E (bloqueado, dir[3]=-1)
|
||||
{ tipo="vent_h", x=6, y=3 }, -- N (bloqueado, dir[1]=-1)
|
||||
{ tipo="puerta_v", x=2, y=12 }, -- O: a dir[4]=1 (Pasillo)
|
||||
{ tipo="conm", x=2, y=11, orient="L", on=false },
|
||||
{ tipo="conm", x=2, y=15, orient="L", on=false },
|
||||
},
|
||||
dir = { -1, -1, -1, 1 },
|
||||
luz = false,
|
||||
},
|
||||
[4] = {
|
||||
nombre = "Cocina",
|
||||
minx = 3, miny = 6, maxx = 13, maxy = 21,
|
||||
elementos = {
|
||||
{ tipo="puerta_h", x=6, y=5 }, -- N: a dir[1]=1 (Pasillo)
|
||||
{ tipo="puerta_h", x=6, y=22 }, -- S: a dir[2]=0 (escape)
|
||||
{ tipo="vent_h", x=10, y=22 }, -- otra ventana en la pared S
|
||||
{ tipo="vent_v", x=14, y=13 }, -- E (bloqueado, dir[3]=-1)
|
||||
{ tipo="puerta_v", x=2, y=13 }, -- O: a dir[4]=5 (Despensa)
|
||||
{ tipo="conm", x=2, y=16, orient="L", on=false },
|
||||
},
|
||||
dir = { 1, 0, -1, 5 },
|
||||
luz = false,
|
||||
},
|
||||
[5] = {
|
||||
nombre = "Despensa",
|
||||
minx = 3, miny = 6, maxx = 9, maxy = 21,
|
||||
elementos = {
|
||||
{ tipo="puerta_v", x=10, y=12 }, -- E: a dir[3]=4 (Cocina)
|
||||
{ tipo="conm", x=10, y=11, orient="R", on=false },
|
||||
},
|
||||
dir = { -1, -1, 4, -1 },
|
||||
luz = false,
|
||||
},
|
||||
}
|
||||
|
||||
-- ============================================================
|
||||
-- ESTADO GLOBAL
|
||||
-- ============================================================
|
||||
rm = 1 -- habitación actual (variable rm del original)
|
||||
xp, yp = 6, 4 -- posición del ladrón
|
||||
hombre_glifo = GL_LADRON
|
||||
mapa = {} -- mapa[hab][x][y] = tipo de celda
|
||||
|
||||
-- ============================================================
|
||||
-- CONSTRUCCIÓN DEL MAPA LÓGICO
|
||||
-- Por habitación se construye una matriz [x][y] con el tipo de
|
||||
-- celda. Las paredes son el contorno (minx-1, maxx+1, miny-1,
|
||||
-- maxy+1). Las puertas, ventanas y conmutadores sobrescriben la
|
||||
-- pared. El interior queda como T_VACIO (se rellenará con joyas
|
||||
-- y obstáculos en la Fase 3).
|
||||
-- ============================================================
|
||||
function init_mapa()
|
||||
for id, hab in pairs(HABITACIONES) do
|
||||
mapa[id] = {}
|
||||
for x = 0, ANCHO-1 do
|
||||
mapa[id][x] = {}
|
||||
for y = 0, ALTO-1 do
|
||||
mapa[id][x][y] = T_VACIO
|
||||
end
|
||||
end
|
||||
|
||||
-- Paredes: contorno del rectángulo interior
|
||||
local x0, y0 = hab.minx - 1, hab.miny - 1
|
||||
local x1, y1 = hab.maxx + 1, hab.maxy + 1
|
||||
for x = x0, x1 do
|
||||
mapa[id][x][y0] = T_PARED
|
||||
mapa[id][x][y1] = T_PARED
|
||||
end
|
||||
for y = y0, y1 do
|
||||
mapa[id][x0][y] = T_PARED
|
||||
mapa[id][x1][y] = T_PARED
|
||||
end
|
||||
|
||||
-- Elementos: sobrescriben la pared
|
||||
for _, e in ipairs(hab.elementos) do
|
||||
if e.tipo == "puerta_h" then
|
||||
mapa[id][e.x ][e.y] = T_PUERTA_H
|
||||
mapa[id][e.x+1][e.y] = T_PUERTA_H
|
||||
elseif e.tipo == "vent_h" then
|
||||
mapa[id][e.x ][e.y] = T_VENT_H
|
||||
mapa[id][e.x+1][e.y] = T_VENT_H
|
||||
elseif e.tipo == "puerta_v" then
|
||||
mapa[id][e.x][e.y ] = T_PUERTA_V
|
||||
mapa[id][e.x][e.y+1] = T_PUERTA_V
|
||||
mapa[id][e.x][e.y+2] = T_PUERTA_V
|
||||
elseif e.tipo == "vent_v" then
|
||||
mapa[id][e.x][e.y ] = T_VENT_V
|
||||
mapa[id][e.x][e.y+1] = T_VENT_V
|
||||
mapa[id][e.x][e.y+2] = T_VENT_V
|
||||
elseif e.tipo == "conm" then
|
||||
mapa[id][e.x][e.y] = (e.orient == "L") and T_CONM_L or T_CONM_R
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- OFFSET DE CENTRADO
|
||||
-- En cada render, calcula el offset (off_x, off_y) para centrar
|
||||
-- el rectángulo de la habitación (paredes incluidas) dentro del
|
||||
-- área de juego.
|
||||
-- ============================================================
|
||||
function offset_centrado()
|
||||
local hab = HABITACIONES[rm]
|
||||
local w = (hab.maxx + 1) - (hab.minx - 1) + 1
|
||||
local h = (hab.maxy + 1) - (hab.miny - 1) + 1
|
||||
local off_x = flr((ANCHO - w) / 2) - (hab.minx - 1)
|
||||
local off_y = flr((AREA_Y0 + AREA_Y1 - h) / 2) - (hab.miny - 1) + 1
|
||||
return off_x, off_y
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- RENDER
|
||||
-- ============================================================
|
||||
function pintar_fondo()
|
||||
color(COL_TEXTO, COL_FONDO)
|
||||
cls()
|
||||
end
|
||||
|
||||
function pintar_banner()
|
||||
color(COL_TEXTO, COL_FONDO)
|
||||
print("Habitacion: "..HABITACIONES[rm].nombre, 1, FILA_BANNER)
|
||||
end
|
||||
|
||||
function glifo_de(tipo, on)
|
||||
if tipo == T_PARED then return GL_PARED end
|
||||
if tipo == T_PUERTA_H then return GL_PUERTA_H end
|
||||
if tipo == T_PUERTA_V then return GL_PUERTA_V end
|
||||
if tipo == T_VENT_H then return GL_VENT_H end
|
||||
if tipo == T_VENT_V then return GL_VENT_V end
|
||||
if tipo == T_CONM_L then return on and GL_CONM_L_ON or GL_CONM_L_OFF end
|
||||
if tipo == T_CONM_R then return on and GL_CONM_R_ON or GL_CONM_R_OFF end
|
||||
if tipo == T_JOYA then return GL_JOYA end
|
||||
if tipo == T_OBSTACULO then return GL_OBSTACULO end
|
||||
if tipo == T_PERRO then return GL_PERRO end
|
||||
return nil
|
||||
end
|
||||
|
||||
function color_de(tipo)
|
||||
if tipo == T_PARED then return COL_PARED end
|
||||
if tipo == T_PUERTA_H then return COL_PUERTA end
|
||||
if tipo == T_PUERTA_V then return COL_PUERTA end
|
||||
if tipo == T_VENT_H then return COL_VENTANA end
|
||||
if tipo == T_VENT_V then return COL_VENTANA end
|
||||
if tipo == T_CONM_L then return COL_CONMUT end
|
||||
if tipo == T_CONM_R then return COL_CONMUT end
|
||||
if tipo == T_JOYA then return COL_JOYA end
|
||||
if tipo == T_OBSTACULO then return COL_OBSTACULO end
|
||||
if tipo == T_PERRO then return COL_PERRO end
|
||||
return COL_TEXTO
|
||||
end
|
||||
|
||||
-- Devuelve el "estado on/off" de un conmutador concreto buscando en
|
||||
-- los elementos de la habitación.
|
||||
function conm_estado(hab, x, y)
|
||||
for _, e in ipairs(hab.elementos) do
|
||||
if e.tipo == "conm" and e.x == x and e.y == y then
|
||||
return e.on
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function pintar_habitacion()
|
||||
local hab = HABITACIONES[rm]
|
||||
local off_x, off_y = offset_centrado()
|
||||
local paper = hab.luz and COL_PAPER_HAB_ON or COL_PAPER_HAB_OFF
|
||||
|
||||
-- Paper del interior
|
||||
color(COL_TEXTO, paper)
|
||||
local blank = " "
|
||||
for y = hab.miny, hab.maxy do
|
||||
for x = hab.minx, hab.maxx do
|
||||
print(blank, x + off_x, y + off_y)
|
||||
end
|
||||
end
|
||||
|
||||
-- Paredes y elementos
|
||||
for y = hab.miny - 1, hab.maxy + 1 do
|
||||
for x = hab.minx - 1, hab.maxx + 1 do
|
||||
local t = mapa[rm][x][y]
|
||||
if t ~= T_VACIO then
|
||||
local on = false
|
||||
if t == T_CONM_L or t == T_CONM_R then
|
||||
on = conm_estado(hab, x, y)
|
||||
end
|
||||
local g = glifo_de(t, on)
|
||||
if g then
|
||||
color(color_de(t), COL_FONDO)
|
||||
print(chr(g), x + off_x, y + off_y)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- El ladrón
|
||||
color(COL_LADRON, paper)
|
||||
print(chr(hombre_glifo), xp + off_x, yp + off_y)
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- BUCLE PRINCIPAL — FASE 1
|
||||
-- Solo render estático. Teclas 1..5 cambian habitación visible.
|
||||
-- ============================================================
|
||||
function init()
|
||||
mode(MODO)
|
||||
border(COL_FONDO)
|
||||
color(COL_TEXTO, COL_FONDO)
|
||||
definir_glifos()
|
||||
init_mapa()
|
||||
rm = 1
|
||||
-- Posición inicial del ladrón en cada habitación (centrada-ish)
|
||||
xp = flr((HABITACIONES[rm].minx + HABITACIONES[rm].maxx) / 2)
|
||||
yp = HABITACIONES[rm].miny + 2
|
||||
cls()
|
||||
end
|
||||
|
||||
function update()
|
||||
-- FASE 1: navegación manual entre habitaciones para verificar
|
||||
if btnp(KEY_1) then rm = 1 end
|
||||
if btnp(KEY_2) then rm = 2 end
|
||||
if btnp(KEY_3) then rm = 3 end
|
||||
if btnp(KEY_4) then rm = 4 end
|
||||
if btnp(KEY_5) then rm = 5 end
|
||||
-- Tecla L para alternar la luz de la habitación actual (debug)
|
||||
if btnp(KEY_L) then HABITACIONES[rm].luz = not HABITACIONES[rm].luz end
|
||||
|
||||
-- Reposicionar al ladrón al cambiar de habitación
|
||||
local hab = HABITACIONES[rm]
|
||||
if xp < hab.minx or xp > hab.maxx or yp < hab.miny or yp > hab.maxy then
|
||||
xp = flr((hab.minx + hab.maxx) / 2)
|
||||
yp = hab.miny + 2
|
||||
end
|
||||
|
||||
pintar_fondo()
|
||||
pintar_banner()
|
||||
pintar_habitacion()
|
||||
|
||||
color(COL_TEXTO, COL_FONDO)
|
||||
print("1..5 hab. L luz", 1, FILA_MSG)
|
||||
end
|
||||
Reference in New Issue
Block a user