Crea tus Juegos con 8BPCursos

Hacemos un PACMAN con 8BP

4.8
(10)

¡Hola amigos de 8 Bits de Poder! En el artículo de hoy sobre la librería 8BP, avanzamos un poco más en el uso del comando layout. Para ello, haremos uso de un juego comecocos al estilo PacMan con 8BP, que nos permitirá visualizar claramente esta funcionalidad de la librería.

rutas avanzadas

Pero espera… ¿Es posible que no sepas nada de 8 Bits de Poder? Puedes leer el primer artículo del curso de programación en Amstrad CPC de 8BP.

Ejemplo de juego con layout

Vamos a evolucionar un poco el juego presentado en capítulos anteriores, en lo que respecta al control del personaje. Esta vez vamos a usar a Montoya como ejemplo, el cual tiene 8 secuencias de animación, cada una para moverse en una dirección diferente. A las secuencias de animación les hemos asignado un número que va del 1 al 8.

Hacemos un PACMAN con 8BP 2
Hacemos un PACMAN con 8BP 3
Pacman con 8BP, uso del layout en un juego

En la rutina de control del personaje hemos incluido colisión con el layout. En función de la dirección en la que avanzamos, modificamos las coordenadas “nuevas” (yn , xn) e invocamos a la función de colisión con layout |COLAY,0 para chequear si el sprite 0 (nuestro personaje) ha colisionado. Si ha colisionado, corregimos las coordenadas (una o las dos) para dejarle en una posición sin colisión antes de imprimirle de nuevo.

10 MEMORY 23999
20 MODE 0: DEFINT A-Z: CALL &6B78:' install RSX
25 call &bc02:'restaura paleta por defecto por si acaso
26 ink 0,0:'fondo negro
30 FOR j=0 TO 31:|SETUPSP,j,0,&X0:NEXT:'reset sprites
40 |SETLIMITS,0,80,0,200: ' establecemos los limites de la pantalla de juego
50 dim c$(25):for i=0 to 24:c$(i)=" ":next
100 c$(1)= "ZZZZZZZZZZZZZZZZZZZZ"
110 c$(2)= "Z                  Z"
120 c$(3)= "Z                  Z"
125 c$(4)= "Z                  Z"
130 c$(5)= "Z  ZZZ  ZZZZ  ZZZ  Z"
140 c$(6)= "Z  ZZZ  ZZZZ  ZZZ  Z"
150 c$(7)= "Z  ZZZ  ZZZZ  ZZZ  Z"
160 c$(8)= "Z                  Z"
170 c$(9)= "Z                  Z"
190 c$(10)="Z                  Z"
195 c$(11)="Z  ZZZZZ  ZZZZZZZ  Z"
200 c$(12)="Z  ZZZZZ  ZZZZZZZ  Z"
210 c$(13)="Z                  Z"
220 c$(14)="Z                  Z"
230 c$(15)="Z                  Z"
240 c$(16)="ZZZZZZZZZZZZZZ  ZZZZ"
250 c$(17)="Z                  Z"
260 c$(18)="Z                  Z"
270 c$(19)="Z                  Z"
271 c$(20)="Z                  Z"
272 c$(21)="Z                  Z"
273 c$(22)="Z                  Z"
274 c$(23)="ZZZZZZZZZZZZZZZZZZZZ"
300 gosub 550: ' imprime el layout
310 xa=40:xn=xa:ya=150:yn=ya:' coordenadas del personaje
311|SETUPSP,0,0,&x111:' deteccion de colision con sprites y layout
312|SETUPSP,0,7,1: ' secuencia = 1
320 |LOCATESP,0,ya,xa: 'colocamos al personaje (sin imprimirlo)
325 cl%=0:'declaramos la variable de colision, explicitamente entera (%)

330 '--- – ciclo de juego – --------------------
340 gosub 1500:'rutina de lectura teclado y movimiento de personaje
350|PRINTSPALL,0,0
360 goto 340

550 'rutina print layout-----------------------------------------
560 FOR i=0 TO 23:|LAYOUT,i,0,@c$(i):NEXT
570 RETURN

1500 ' rutina movimiento personaje – -----------
1510 IF INKEY(27)<0 GOTO 1520
1511 IF INKEY(67)=0 THEN IF dir<>2 THEN |SETUPSP,0,7,2:dir=2:GOTO 1533 ELSE |ANIMA,0:xn=xa+1:yn=ya-2:GOTO 1533
1512 IF INKEY(69)=0 THEN IF dir<>8 THEN |SETUPSP,0,7,8:dir=8:GOTO 1533 ELSE |ANIMA,0:xn=xa+1:yn=ya+2:GOTO 1533 
1513 IF dir<>1 THEN |SETUPSP,0,7,1:dir=1:GOTO 1533 ELSE |ANIMA,0:xn=xa+1:GOTO 1533 
1520 IF INKEY(34)<0 GOTO 1530
1521 IF INKEY(67)=0 THEN IF dir<>4 THEN |SETUPSP,0,7,4:dir=4:GOTO 1533 ELSE |ANIMA,0:xn=xa-1:yn=ya-2:GOTO 1533 
1522 IF INKEY(69)=0 THEN IF dir<>6 THEN |SETUPSP,0,7,6:dir=6:GOTO 1533 ELSE |ANIMA,0:xn=xa-1:yn=ya+2:GOTO 1533 
1523 IF dir<>5 THEN |SETUPSP,0,7,5:dir=5:GOTO 1533 ELSE |ANIMA,0:xn=xa-1:GOTO 1533 
1530 IF INKEY(67)=0 THEN IF dir<>3 THEN |SETUPSP,0,7,3:dir=3:GOTO 1533 ELSE |ANIMA,0:yn=ya-4:GOTO 1533 
1531 IF INKEY(69)=0 THEN IF dir<>7 THEN |SETUPSP,0,7,7:dir=7:GOTO 1533 ELSE |ANIMA,0:yn=ya+4:GOTO 1533 
1532 RETURN
1533 |LOCATESP,0,yn,xn:ynn=yn:|COLAY,@cl%,0:IF cl%=0 THEN 1536 
1534 yn=ya:|POKE, 27001,yn:|COLAY,@cl%,0:IF cl%=0 THEN 1536  
1535 xn=xa: yn=ynn:|POKE, 27001,yn:|POKE, 27003,xn:|COLAY,@cl%,0:IF cl%=1 THEN yn=ya:|POKE,27001,yn 
1536 ya=yn:xa=xn
1537 RETURN

Cómo abrir una compuerta en el layout

Si deseas que tu personaje pueda coger una llave y abrir una compuerta o en general eliminar una parte del layout para permitir el acceso, lo que tienes que hacer son dos cosas:

  • Tener definido un sprite de borrado de 8×8 donde todo sean ceros. Usando |LAYOUT lo imprimes en las posiciones que deseas
  • A continuación, usando nuevamente |LAYOUT, imprimes espacios donde has borrado. Así el map layout quedará con el carácter “ “ en esas posiciones y la función de colisión con el layout resultará cero.

En el juego “mutante montoya” se utiliza esta técnica para abrir la puerta del castillo, así como para abrir las compuertas que conducen a la princesa.

Hacemos un PACMAN con 8BP 4
Pacman con 8BP – Mutante Montoya, modificación del layout al coger la llave.

En el siguiente ejemplo se ilustra el concepto, abriendo una compuerta situada en las coordenadas (10, 12) de un tamaño de 2 bloques, al coger una llave que está definida con el sprite 16.

Nada más coger la llave se abre la compuerta y la llave queda desactivada para no evaluar más veces la colisión con ella, es decir, el comando |COLSP retornará un 32 a partir del momento que cojas la llave si vuelves a colisionar con ella.

Tras abrir la compuerta, si desplazas el personaje hasta el lugar que ocupaba dicha compuerta, la colisión con layout dará como resultado 0.

'--- – esta parte esta dentro del bucle de logica – --
6410 |PRINTSPALL,1,0
6411 |COLSP,@cs%,0:IF cs%<32 THEN IF cs%>=15 then gosub 6500
(... mas instrucciones . . .)

'------ – rutina de apertura de compuerta-----------------
6499 ' comprueba que tu colision sea con la llave, que es el sprite 16
6500 borra$="MM":spaces$="  ":' el sprite de borrado se ha definido como "M" (M es el sprite 18 en el "idioma" del comando |LAYOUT)
6501 if cs%=16 then|LAYOUT,10,12,@borra$ : |LAYOUT,10,12,@spaces$: |SETUPSP,16,0,0
6502 return

Un pacman con 8bp: LAYOUT con fondo

A continuación, vamos a ver un ejemplo que usa layout y sobrescritura, para lo cual establece un umbral ASCII que permite que el comando |COLAY no considere colisión con los elementos de fondo. Concretamente como elemento de fondo se usa la letra “Y”, la cual se corresponde con el sprite id= 30, y el ASCII de la “Y” es el 89.

pacman con 8bp
Pacman con 8BP, layout con un patrón de fondo y sobrescritura.

Como puedes ver en el ejemplo, tan solo hace falta invocar a COLAY con el parámetro de umbral una vez, ya que las sucesivas invocaciones tienen ya en cuenta dicho umbral

Otro de los aspectos interesantes es la gestión del teclado de este ejemplo. Es óptima para ejecutar el menor número de operaciones |COLAY y a la vez da una sensación muy agradable al avanzar por un pasillo y conectar con otro teniendo dos teclas pulsadas a la vez.

10 MEMORY 23999
20 MODE 0: DEFINT A-Z: CALL &6B78:' install RSX
21 on break gosub 5000
25 call &bc02:'restaura paleta por defecto por si acaso
26 gosub 2300:' paleta con sobreescritura
30 FOR j=0 TO 31:|SETUPSP,j,0,&X0:NEXT:'reset sprites
40 |SETLIMITS,0,80,0,200: ' limites de la pantalla de juego
45 |SETUPSP,30,9,&84d0:' rejilla de fondo ("Y")
46 |SETUPSP,31,9,&84f2:' ladrillo ("Z")
50 dim c$(25):for i=0 to 24:c$(i)=" ":next
100 c$(1)= "ZZZZZZZZZZZZZZZZZZZZ"
110 c$(2)= "ZYYYYYYYYYYYYYYYYYYZ"
120 c$(3)= "ZYYYYYYYYYYYYYYYYYYZ"
125 c$(4)= "ZYZZZYZZZZZZZZYZZZYZ"
130 c$(5)= "ZYZZZYZZZZZZZZYZZZYZ"
140 c$(6)= "ZYYYYYYYYYYYYYYYYYYZ"
150 c$(7)= "ZYYYYYYYYYYYYYYYYYYZ"
160 c$(8)= "ZYZZZZZZZYZZZZZZZZYZ"
170 c$(9)= "ZYZ     ZYZ      ZYZ"
190 c$(10)="ZYZ     ZYZ      ZYZ"
195 c$(11)="ZYZZZZZZZYZZZZZZZZYZ"
200 c$(12)="ZYYYYYYYYYYYYYYYYYYZ"
210 c$(13)="ZYYYYYYYYYYYYYYYYYYZ"
220 c$(14)="ZYZZZYZZZZZZZYZZZZYZ"
230 c$(15)="ZYYYYYYYZ ZYYYYYYYYZ"
240 c$(16)="ZYYYYYYYZ ZYYYYYYYYZ"
250 c$(17)="ZYZZZZZYZZZYZZZZZZYZ"
260 c$(18)="ZYYYYYYYYYYYYYYYYYYZ" 
270 c$(19)="ZYYYYYYYYYYYYYYYYYYZ"
271 c$(20)="ZZZZZZZZZZZZZZZZZZZZ"
272 c$(21)=""
273 c$(22)=""
274 c$(23)=""
300 'imprimimos el layout
310 FOR i=0 TO 20:|LAYOUT,i,0,@c$(i):NEXT
311 locate 1,1:pen 9:print "DEMO SOBREESCRITURA"
312 locate 3,23:pen 11:print "BASIC usando 8BP"
320 |SETUPSP,0,0,&x01000111:' deteccion colision con sprites y layout
330 |SETUPSP,0,7,1:dir=1: ' secuencia = 1 (coco derecha)
340 xa=20*2:xn=xa:ya=12*8:yn=ya:' coordenadas del personaje 
350 |LOCATESP,0,ya,xa: 'colocamos al personaje (sin imprimirlo)
360 |PRINTSPALL,0,1,0:' imprime sprites
361 cl%=0:' variable colision
362 |COLAY,89,cl%,0:'umbral chr$("Y") es 89
400 ' COMIENZA EL JUEGO
401 |MUSIC,0,5
402 ' lectura teclado y colisiones. si vamos en direccion H (o p), primero chequeamos si hay pulsada tecla direccion V (q a) y viceversa
404 if dirn <3 then gosub 450: gosub 410 else gosub 410:gosub 450
405 |LOCATESP,0,yn,xn:|PRINTSPALL
406 ya=yn:xa=xn
407 goto 404

409 ' teclado direccion horizontal – -
410 if INKEY(27)<0 then 430 
420 xn=xa+1:poke 27003,xn:|COLAY: IF cl%=0 then if dir<>1 then |SETUPSP,0,7,1:DIR=1:xn=xa:return else dirn=1:return
421 xn=xa:poke 27003,xn:return:'hay colision
430 if INKEY(34)<0 then return
440 xn=xa-1:poke 27003,xn:|COLAY: IF cl%=0 then if dir<>2 then |SETUPSP,0,7,2:DIR=2:xn=xa:return else dirn=2:return
441 xn=xa:poke 27003,xn:'hay colision
442 return
449 'teclado direccion vertical
450 if INKEY(67)<0 then 480
460 yn=ya-2:poke 27001,yn:|COLAY: IF cl%=0 then if dir<>3 then |SETUPSP,0,7,3:DIR=3:yn=ya:return else dirn=3:return
461 yn=ya:poke 27001,yn:'hay colision
480 if INKEY(69)<0 then return
490 yn=ya+2:poke 27001,yn:|COLAY: IF cl%=0 then if dir<>4 then |SETUPSP,0,7,4:DIR=4:yn=ya:return else dirn=4:return
491 yn=ya:poke 27001,yn:'hay colision
492 return

2300 REM – ------ – PALETA sprites transparentes MODE 0------------
2301 INK 0,11: REM azul claro
2302 INK 1,15: REM naranja
2303 INK 2,0 : INK 3,0:  REM negro
2305 INK 4,26: INK 5,26: REM blanco
2307 INK 6,6: INK 7,6: REM rojo
2309 INK 8,18: INK 9,18: REM verde
2311 INK 10,24: INK 11,24: REM amarillo
2313 INK 12,4: INK 13,4 :REM magenta
2315 INK 14,16 : INK 15, 16:REM naranja
2317 AMARILLO=10
2420 RETURN
5000 |musicoff
5010 end

En el siguiente artículo de esta serie veremos como ahorrar memoria haciendo uso del comando layout de 8 Bits de Poder. Si tu juego tiene muchas pantallas, será necesario ahorrar memoria.

Hasta aquí hemos llegado por hoy con el curso de programación en Amstrad CPC de 8 bits de poder Si tienes alguna duda puedes escribir en comentarios y te contestaré lo antes posible.

Todos los recursos, como manuales, ejemplos y juegos compilados de este curso los puedes encontrar en el repositorio Github de 8BP.

Hasta la semana que viene amigos 😄

¿Te ha Resultado útil este artículo?

Ayúdanos a mejorar y danos tu opinión:

Mostrar más

Un comentario

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicaciones relacionadas

Mira también
Cerrar
Botón volver arriba