help me to make 8BP better

If you like 8BP, your help is welcome. Help me supporting this initiative (from 1€, whatever you want). Donations will be used for materials and 8BP disemination:
Mostrando entradas con la etiqueta colisiones. Mostrar todas las entradas
Mostrando entradas con la etiqueta colisiones. Mostrar todas las entradas

domingo, 13 de octubre de 2019

Disponible version V37 de la libreria 8BP

hola amigos de 8 bits de poder

Ya esta disponible la versión v37 de 8BP,  disponible para descarga en https://github.com/jjaranda13/8BP la cual incorpora las siguientes mejoras:
  • comando |COLAY mas rápido y con un cambio en su paso de parámetros. ahora acepta 3,2,1 o ningún parámetro y el nuevo orden de los parámetros es |COLAY umbral,@col,sp . En caso de no usarse ningún parámetro, el comando tiene memoria y usa los de la ultima invocación. Esto permite un incremento notable de velocidad, pasando de 3.5 ms a 2.5 ms
  • se han acelerado unos cuantos comandos, (MOVER, MOVERALL y otros). Para ello se han modificado algunas partes de código ensamblador comunes a varios comandos
  • comando |COLSPALL mas potente. ahora puede ser invocado con un parámetro para especificar el colisionador inicial. Esto permite detectar varias colisiones por fotograma si es necesario. luego veremos como.
  • comando |ANIMALL ya solo se puede invocar mediante un parámetro en PRINTSPALL o mediante CALL pues se ha sacado de la lista para ganar algunos bytes de memoria. El comando normalmente solo se usa desde PRINTSPALL, de modo que no supone ningún problema
  • manual: he actualizado el manual reflejando los cambios en la librería y he incluido un apéndice con la correspondencia entre cada comando y su equivalente CALL. Además, el manual ha sido revisado y mejorado al completo, en especial el capítulo de lógicas masivas
La velocidad en general ha aumentado un poco en todos los comandos, los cuales unidos a la técnica de lógicas masivas nos permite hacer juegos en BASIC como el nuevo "Happy Monty". Es un juego aun en construcción que reproduce fielmente el funcionamiento del mítico mutant monty. Alcanza los 25 FPS y permite activar y desactivar la musica on-game. El juego es muy rápido y se mide a si mismo, mostrando los FPS alcanzados dentro de los marcadores del juego. 

Las colisiones funcionan como siempre (mecanismo de logicas masivas dentro del comando COLSPALL) pero se puede invocar usando como parametro el colisionador de la ultima colisión detectada y si se ejecuta hasta que no haya colisiones, puedes detectar todas las colisiones que sucedan en cada fotograma, aunque es algo que debe usarse solo si es necesario. 
Lo que acabo de contar se puede expresar asi:

colisionador=31
while colisionador<32
  COLSPALL, colisionador
  if colisionador <32 then GOSUB RUTINA
wend

Aqui teneis un video donde podéis ver como esta quedando. Pondré una demo del juego en la feria de la RUN" AUA (Rivas, Sábado dia 19) para que puedas probarla.


Cada nivel se ha construido usando 160 caracteres, apenas lo que ocupa un mensaje de twitter. En 4KB se han metido 25 pantallas y en realidad aun caben mas. Puede que le llegue a hacer 40 niveles.

Aprovecho para deciros que estaré en la RUN"" AUA que tendrá lugar en Rivas el sabado 19 de Octubre (en una semana) y alli contaré como usar la libreria 8BP y diversos trucos de programación usados en space phantom, eridu, frogger, happy monty...


la RUN"" AUA se celebra en la "casa grande ", un espacio ofrecido por el ayuntamiento de Rivas-Vaciamadrid. Teneis mas informacion en https://auamstrad.es/runaua2019/
el fabuloso emplazamiento donde tendrá lugar la RUN"" AUA
Además podreis ver el DES (Dandanator Entertaiment System" https://auamstrad.es/des/) con el cartucho de 8BP en acción, incluyendo el juego "Eridu", "frogger", "space phantom"... todos!!!





Nos vemos en Rivas el sábado día 19, amigos. Hasta pronto!!








viernes, 23 de diciembre de 2016

Cómo hacer un juego mini-pong en BASIC usando la libreria 8BP

hola amigos de 8BP

Os traigo un pequeño tutorial de introducción para hacer un juego tipo "pong" en unos minutos. El tutorial está disponible en el canal de vídeos de 8BP  https://www.youtube.com/channel/UCThvesOT-jLU_s8a5ZOjBFA


Y el juego "mini-pong" lo encontrareis en la carpeta "Game Examples" del proyecto Github en https://github.com/jjaranda13/8BP

Os adjunto aquí el listado del juego. Como complemento a las explicaciones del video os diré que la barra del oponente (el ordenador) comienza a tomar decisiones cuando la pelota sobrepasa la mitad del campo, por lo que es posible ganarle. Si le ponemos a tomar decisiones antes llega un momento que es imposible ganar.

Algunas pinceladas sobre el juego:
- COLSPALL : para detectar colisiones entre el "colisionador" (la pelota) y los "colisionados" (las barras). En el byte de estado de los sprites se activa el flag de colisionador para la pelota (sprite 29) y se activa el flag de colisionado en el 31 (nuestra barra) y el 30 (barra del oponente)
- Usa sobreescritura en la pelota para respetar la raya blanca del campo y no borrarla al pasar. Para ello se usa una paleta con sobreescritura y se activa el flag de sobreescritura en el byte de estado del sprite de la pelota (el 29)
- solo hay dos imágenes (la pelota=17 y la barra=16) que se asignan a los 2 sprites (a los sprites 30 y 31 se les asigna la imagen 16 y al sprite 29 se le asigna la imagen 17)
- los sprites usan movimiento automático. Para ello tienen activado el flag de movimiento automático y la instruccion AUTOALL los mueve (les cambia sus coordenadas) de acuerdo a su velocidad
- todos los sprites se imprimen con PRINTSPALL en cada ciclo de juego

Sin más, os dejo con el video tutorial y el listado del videojuego

felices fiestas!



10 MEMORY 25999
20 DEFINT A-Z: CALL &6B78:' install RSX
21 |PRINTSPALL,0,0:|AUTOALL,0:mode 0
22 on break gosub 2800
26 CALL &BC02:'restaura paleta por defecto     
27 INK 0,9
28 INK 1,26
29 INK 4,1
30 ink 6,20: ink 7,20
31 puntosplayer=0
32 puntoscomputer=0
33 LOCATE 5,1:PEN 7:PRINT puntosplayer
34 LOCATE 15,1:PEN 1:PRINT puntoscomputer
35 PLOT 320,0,1:DRAW 320,400: plot 0,300:draw 16,300:draw 16,100:draw 0,100:
36 plot 640,300:draw 640-16,300:draw 640-16,100:draw 640,100
37 border 0

40 'barra del jugador
41 |SETUPSP,31,9,16:|SETUPSP,31,0,11:|LOCATESP,31,80,4
50 ' pelota
51 |SETUPSP,29,9,17:|SETUPSP,29,0,41+64:|LOCATESP,29,90,38:vyp=1:vxp=1
52 collided=0:collider=0:|COLSP,32,30,31:|COLSP,34,4,0
53 |COLSPALL,@collider,@collided
60 'barra computer
61 |SETUPSP,30,9,16:|SETUPSP,30,0,11:|LOCATESP,30,80,74:|SETUPSP,30,5,0,0
62 yc=90
80 |PRINTSPALL
81 env 1,1,15,1,15,-1,1:SOUND 1,100,25,15,1:SOUND 1,100,25,15,1:SOUND 1,100,50,15,1
82 IF INKEY(47)<>0 THEN  82
83 SOUND 1,100,7,15

90 'ciclo de juego------------
100 GOSUB 220:'lectura teclado y movimiento barra
110 GOSUB 310:'pelota
120 GOSUB 410:'computer
130 |AUTOALL:|PRINTSPALL
140 GOTO 100

200 ' rutina de movimiento barra
220 IF INKEY(67)=0 THEN vy=-5:GOTO 250
230 IF INKEY(69)=0 THEN vy=5:GOTO 250
240 if vy>0 then vy=vy-1 else if vy<0 then vy=vy+1
250 |SETUPSP,31,5,vy
260 RETURN

300 ' rutina movimiento pelota
310 xp=PEEK(27467)
311 IF xp>6 THEN IF xp<70 THEN 345
320 IF xp>=80 THEN GOSUB 500: CLS:GOTO 33:'vxp=-vxp: REM AQUI HAY QUE HACER GOSUB GOL
321  |COLSPALL: IF collider=32 THEN 345
341 IF collided=31 THEN SOUND 1,200,7,15:IF vxp<0 THEN vxp=-vxp:IF vy>0 THEN IF vyp<4 THEN vyp=vyp+1 ELSE ELSE IF vy<0 THEN IF vyp>-4 THEN vyp=vyp-1
342 IF collided=30 THEN SOUND 1,200,7,15:|SETUPSP,30,5,0:IF vxp>0 THEN vxp=-vxp: IF vyp=0 THEN vyp=1
343 pongs=pongs+1: if pongs=10 then vxp=vxp*2
345 yp=PEEK(27465) 
346 IF yp<=16 THEN vyp=-vyp:SOUND 1,600,7,15 ELSE IF yp>=192 THEN vyp=-vyp: SOUND 1,600,7,15
347 |SETUPSP,29,5,vyp,vxp
350 RETURN

400 ' rutina movimiento computer
410 IF vxp<0 THEN RETURN:'|SETUPSP,30,5,0:return
411 IF xp<40 THEN RETURN 
420 |PEEK,27481,@yc: yc=yc+21
430 IF yc<yp-5 THEN vyc=5: GOTO 450
440 IF yc>yp+5 THEN vyc=-5: goto 450
441 if vyc>0 then vyc=vyc-1 else if vyc<0 then vyc=vyc+1
450 |SETUPSP,30,5,vyc
460 RETURN

500 ' rutina puntos
510 |PEEK,27467,@xp
511 IF xp>40 THEN puntosplayer=puntosplayer+1 ELSE puntoscomputer=puntoscomputer+1
512 pongs=0
520 RETURN

2800 MODE 2: INK 0,0:PEN 1: END

viernes, 15 de julio de 2016

Sobreescritura usando layout en 8BP

hola amigos de 8BP

Aunque últimamente ando trabajando en los comandos de scroll por hardware para 8BP, he hecho una actualización que no está relacionada con el scroll, y que me dí cuenta de que era necesaria para dejar bien atado el tema de la sobreescritura. Se trata de una actualización que afecta al comando |COLAY

La actualización es la versión V23b, disponible en https://github.com/jjaranda13/8BP . Además, en esta actualización ahora veréis un directorio donde se encuentran demos didácticas hechas con 8BP. Poco a poco iré llenando ese directorio de demos interesantes. De momento hay 3 demos, una de las cuales es el objeto de este post.

Como sabéis, el comando |COLAY sirve para detectar colisiones entre un sprite y el layout ( útil en juegos donde se use el layout, claro está). Pues bien, este comando hasta ahora detectaba colisión cuando nuestro sprite colisionaba con cualquier elemento del layout representado por cualquier carácter diferente del espacio en blanco.

Recordemos que el layout es una matriz de caracteres de 20x25, donde cada carácter está asociado a un sprite. Es un concepto similar a lo que en otras herramientas se llama "mapa de tiles", solo que aquí los elementos del layout se representan con letras y cada letra se corresponde con un sprite. Concretamente el carácter "Z" está asociado al sprite 31, el "Y" al sprite 30, el "X" al sprite 29 y asi sucesivamente hasta el ";" que representa al sprite 0. Tras imprimir el layout en pantalla, los sprites asociados pueden reconfigurarse para asociarse a monstruos o soldados, de modo que no se pierde ningún sprite por usar el layout.

El comando |COLAY , sprite_id, @colision detecta la colisión y la almacena en la variable colisión si el sprite_id choca con algo diferente de " ". Si chocas, el resultado es un 1, y si no chocas, el resultado es un 0. Pero ¿y si queremos que haya un fondo en nuestro layout diferente el espacio en blanco?

En el videojuego "mutante montoya" se usaba un layout y el personaje pasaba por los espacios en blanco como podemos ver en la imagen
mutante montoya
pensemos ahora en un juego tipo PACMAN donde el personaje se desplaza sobre un fondo. En ese caso el fondo puede estar asociado a un sprite, y no ser simplemente espacios en blanco.

demo con layout y fondo

matriz del layout



En este caso el layout ha sido construido con una matriz donde los pasillos por los que se desplaza el coco han sido creados con un sprite, el número 30, al que esta asociado el caracter "Y", cuyo código ASCII es el 89. Esto significa que no debería detectarse colisión cuando el personaje choca con dicho elemento.

Para ello si nuestro sprite es el id=0 , simplemente haremos

|COLAY, 89, 0, @colision

Con esto le estamos diciendo a COLAY que considere cualquier carácter con codigo ASCII igual o menor a 89 como fondo y por lo tanto que no considere colisiones en esos casos. El codigo 89 del ejemplo es porque he usado el sprite 30 para el fondo pero si hubiese usado el sprite 20 pues entonces usaría la letra "O", cuyo codigo ASCII es el 79. Es decir, se trata de un parámetro que representa el umbral ASCII a partir del cual debe considerarse colisión. Colisiones con caracteres con valores iguales o menores al que pongamos no producirán colisión (tras la ejecucion del comando COLAY , la variable colision valdrá cero) ,

El comando tiene memoria, de modo que sucesivas invocaciones a |COLAY pueden omitir el parámetro de umbral ASCII y se seguirá usando el mismo. Obviamente por defecto el umbral es 32, que es el código ASCII del espacio en blanco.

a continuación os muestro una demo que encontrareis en https://github.com/jjaranda13/8BP, dentro del directorio de Demos.



Espero que os guste y hasta la vista!


martes, 8 de marzo de 2016

Disponible nueva version v20 de la libreria 8BP (retrocompatible)

hola amigos de 8BP

Ya esta disponible la versión v20 de la libreria 8BP, totalmente retrocompatible

He actualizado el repositorio de github https://github.com/jjaranda13/8BP con los siguientes cambios (coherentes entre la documentación y la librería). Con estas mejoras los juegos arcade ahora funcionan aun más rapido. Se incluye la demo de annunaki donde podéis comprobar el uso de estas mejoras.
Las mejoras son:

  • posibilidad de definir la sensibilidad de la colisión entre sprites
  • nuevo comando COLSPALL que acelera la detección de colisión


Posibilidad de definir la sensibilidad de la colisión entre sprites
COLSP : ahora puedes definir la sensibilidad de la colision (grado de solape entre sprites)

Es posible ajustar la sensibilidad del comando COLSP, decidiendo si el solape entre sprites debe ser de varios pixels o de uno solo, para considerar que ha habido colisión.
Para ello se puede configurar el número de pixels (pixels en dirección Y, bytes en dirección X) de solape necesario tanto en la dirección Y como en la dirección X, usando el comando COLSP y especificando el sprite 34 (que no existe)

|COLSP, 34, dy, dx

La librería 8BP no usa “pixels” en la coordenada X, sino bytes, de modo que debes tener en cuenta que una colisión de 1 byte, en realidad son 2 pixels y esa es la mínima colisión posible cuando ajustas dx=0.
En la coordenada Y, la librería trabaja con líneas de modo que dy=0 significa una colisión de un solo pixel.
Una colisión estricta, útil para disparos sería aquella que no tolera ningún margen, considerando colisión en cuanto hay un mínimo solape entre sprites (1 pixel en dirección Y o un byte en dirección X)

|COLSP, 34, 0, 0: rem colision en cuanto hay un mínimo solape



Sin embargo, si estamos haciendo un juego en MODE 0, donde los pixels son mas anchos que altos, es quizás mas adecuado dar algo de margen en Y y nada en X. Por ejemplo

|COLSP, 34, 2, 0 : rem colision con 3 pix en Y y 1 byte en X

Mi recomendación es que si hay disparos estrechos o pequeños, ajustes la colision con (dy=1, dx=0) mientras que si solo hay personajes grandes puedes dejarla con mas margen (dy=2, dx=1). También debes considerar que si tus sprites tienen un “margen” de borrado alrededor para desplazarse borrándose a si mismos, dicho margen no debería formar parte de la consideración de colisión por lo que tiene sentido que tanto dy como dx no sean cero. En cualquier caso es algo que decidirás en función del tipo de juego que hagas

Nuevo comando COLSPALL que acelera la colisión entre sprites y simplifica tu programa BASIC

Con la funcion COLSP que hemos visto hasta ahora, es posible la detección de colisión de un sprite con todos los demás. Sin embargo si tenemos un disparo múltiple, donde por ejemplo nuestra nave puede disparar hasta 3 disparos simultáneamente, tendríamos que detectar la colisión de cada uno de ellos y adicionalmente la de nuestra nave, resultando en 4 invocaciones a COLSP.
Debemos tener presente que cada invocación atraviesa la capa de análisis sintáctico, por lo que 4 invocaciones resulta costoso. Para ello disponemos de un comando adicional: COLSPALL
Esta funcion funciona en dos pasos, primero debemos especificar que variables van a almacenar el sprite colisionador y el colisionado

|COLSPALL, @colisionador%, @colisionado%

Y posteriormente, en cada ciclo de juego simplemente invocamos la funcion sin parámetros:

|COLSPALL

La función va a considerar como sprites “colisionadores” aquellos que tengan el flag de colisionador a “1” en el byte de estado (es el bit 5), y como “colisionados” aquellos sprites que tengan a “1” el flag de colision (bit 1) del byte de estado. Los sprites colisionadores deberán ser nuestra nave y nuestros disparos




La función COLSPALL empieza comprobando el sprite 31 (si es colisionador) y va descendiendo hasta el sprite 0, invocando internamente a COLSP para cada sprite colisionador. En cuanto detecta una colisión, interrumpe su ejecución y retorna el valor del colisionador y el colisionado. Por ello es importante que nuestra nave tenga un sprite superior a nuestros disparos. De ese modo, si nos alcanzan, lo detectaremos aunque hayamos alcanzado a un enemigo con un disparo en el mismo instante.
En cada ciclo de juego solo se podrá detectar una colisión, pero es suficiente. No es una limitación importante que en cada fotograma solo pueda empezar a “explotar” un enemigo. Si, por ejemplo, tiras una granada y hay un grupo de 5 soldados afectados, cada soldado comenzará a morir en un fotograma distinto, y en 5 fotogramas estarán todos explotando. Usando COLSPALL no explotarán todos a la vez, pero tu juego será más rápido y en un arcade es algo muy importante.


Espero que os gusten estas mejoras. Yo voy a intentar centrarme en avanzar en el videojuego "Annunaki",el cual hace uso de estas mejoras por ser un arcade espacial.   En cuanto lo tenga listo lo compartiré con todos vosotros

  

sábado, 5 de marzo de 2016

Cómo programar un disparo múltiple

Hola amigos de 8 bits de poder

Hoy os voy a contar como programar un disparo múltiple de un modo eficiente.
Lo primero de todo, para evitar el paso de parámetros (es decir, col,<sprite>,@variable%) haremos

col%=0
|COLSP,33,@col%: ' el sprite 33 no existe, se usa para indicar la variable de trabajo

De este modo sucesivas invocaciones a COLSP,<sprite> dejarán el resultado (número de sprite que colisiona) en la variable col%

Primer caso : un personaje que no dispara
Cuando no queremos hacer que nuestro personaje dispare pero simplemente que le puedan matar los enemigos al colisionar, ejecutamos una instrucción como esta en nuestro ciclo de juego

|COLSP,31 : ' suponemos que el sprite 31 es nuestro personaje.

Segundo caso : un personaje que dispara un solo proyectil
En ocasiones queremos que nuestro personaje dispare un solo disparo. En ese caso incorporaremos
una invocación adicional a la colisión del disparo si ha sido lanzado, es decir

|COLSP,7 : ' suponemos que el sprite 7 es nuestro disparo. 

Tercer caso : un personaje que dispara hasta 3 proyectiles a la vez
pero y si queremos colisionar hasta 3 disparos?  vamos a suponer que tenemos hasta 3 disparos con los sprites 7,8 y 9

La solución mas efectiva se basa en uno de los casos más sencillos de aplicación de la técnica de "lógicas masivas". restringiendo a contemplar solo una de las siguientes cosas a la vez:

  • o colisiona uno de los 3 disparos (solo uno), y mata a un enemigo
  • o un disparo sale del área de pantalla (solo uno)


La rutina seria algo así (dentro de cada ciclo de juego haríamos un gosub 750)

744 ' RUTINA DE COLISION DE DISPAROS
745 ' -------------------------------------------------------  

746 ' CASO 1 comprobamos si hay alguna colision
747 '-------------------------------------------
750 if peek(27112)>0 then |colsp,7: if col%<32 then dir=27113:goto 820
760 if peek(27128)>0 then |colsp,8: if col%<32 then dir=27129:goto 820
770 if peek(27144)>0 then |colsp,9: if col<32 then dir=27145:goto 820

780 ' CASO 2 comprobamos si el disparo se ha salido de pantalla
790 ' ----------------------------------------------------------
800 dc=dc mod 3 +1:dir=ddisp(dc):|peek,dir,@yd%: if yd%<-10 then poke dir-1,0: |POKE,dir,200:nd=nd-1
810 return: 

820 ' continuacion del caso 1 en caso de colision
825 ' ------------------------------------------------------------
830 ' desactivo el disparo
840 poke dir-1,0: nd=nd-1:|PRINTSP,6,peek(dir),peek(dir+2): poke dir,255
850 ' ahora proceso al enemigo segun sea duro o blando
860 if col>=duros then return
870 ' alcance de enemigo tipo blando. lo matamos, asignandole una secuencia de muerte y poniendo su estado a no colisionar mas
880 if col>=blandos then |SETUPSP,col,7,4:|SETUPSP,col,0,&x101:return 
890 return


Y aquí tenéis el resultado. En una nueva versión de la librería podréis ajustar la sensibilidad del comando COLSP, decidiendo si el solape entre sprites debe ser de varios pixels o de uno solo, para considerar que ha habido colisión. Y también alguna cosa mas muy interesante relacionada con el comando COLSP. Y como siempre, serán mejoras retrocompatibles.

https://www.youtube.com/watch?v=QDUZmM6AEZ4