CursosCrea tus Juegos con 8BP

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos

4.9
(13)

Hola de nuevo amigo de 8 Bits de poder. En el articulo de esta semana y tras el articulo anterior sobre Sprite flipping, hoy te contamos cómo pintar los sprites tras el fondo y algunos detalles sobre la tabla de atributos.

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.

¡¡¡Vamos con ello!!!

El mismo mecanismo para imprimir sprites por encima del fondo puede servir para pintar sprites por detrás del fondo.

Como ya hemos visto, para imprimir por delante del fondo usamos bits que no se usan en el fondo, de modo que, aunque reducimos el numero de colores, no dañamos el bit o los bits de fondo. Si usamos un bit para el fondo, tendremos que usar dos tintas para representar el mismo color de sprite: una con el bit de fondo a cero y otra con el bit de fondo a 1.

Quizás te preguntas, ¿Por que programar una maquina de 1984?

Ahora bien, si en lugar de asignar el mismo color a estas dos tintas, asignamos el mismo color que el fondo a la que tiene el bit de fondo a 1, entonces ante un solape del sprite con el fondo, se verá el color del fondo, dando la sensación de que el sprite pasa por detrás. Esto funciona tanto en MODE 0 como en MODE 1.

En el siguiente ejemplo se usa un bit para el fondo, el cual consiste en unas letras amarillas sobre un fondo negro. Los sprites son unas “monedas” que como se puede apreciar se han pintado aparentemente detrás del fondo.

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos 1
Sprites impresos “detrás” de las letras

Tabla de atributos de sprites en 8BP

Los sprites se almacenan en una tabla que contiene un total de 32 sprites. Puedes usar los 32 a la vez en pantalla.

Cada entrada de la tabla contiene todos los atributos del sprite y ocupa 16 bytes por razones de rendimiento, ya que 16 es múltiplo de 2 y ello permite acceder a cualquier sprite con una multiplicación muy poco costosa. La tabla se encuentra ubicada en la dirección de memoria 27000, de modo que se puede acceder desde BASIC con PEEK y POKE, aunque también disponemos de comandos RSX para manipular los datos de esta tabla, tales como |SETUPSP o |LOCATESP

Los sprites tienen un conjunto de parámetros, de los que el primero de ellos es el byte de flags de status. En este byte, cada bit representa un flag y cada flag significa una cosa, concretamente representan si el sprite se toma en consideración al ejecutar ciertas funciones. En la siguiente tabla se resume lo que ocurre si están activos (a “1”).

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos 2
flags en el byte de estado

Para entender la potencia de estos flags vamos a ver algunos ejemplos:

  • BIT 0: flag de impresión: nuestro personaje o las naves enemigas lo tendrán activado y en cada ciclo del juego invocaremos a |PRINTSPALL y se imprimirán todos a la vez
  • BIT 1: flag de colisión: una fruta o moneda por ejemplo pueden no tener flag de impresión, pero tener el de colisión. Este flag significa que un sprite “colisionador” se puede colisionar con el sprite que tenga este flag activo.
  • BIT 2: flag de animación automática: se tiene en cuenta en |ANIMALL. En el caso del personaje, recomiendo desactivarlo, ya que si me quedo quieto no hay que cambiar el fotograma.
  • BIT 3: flag de movimiento automático. Se mueve solo al invocar |AUTOALL teniendo en cuenta su velocidad. útil en meteoritos y guardias que van y vienen.
  • BIT 4: flag de movimiento relativo. Todos los sprites que tengan este flag se mueven a la vez al invocar “|MOVERALL, dy, dx” muy útil en naves en formación y llegadas a planetas. También sirve para simular un scroll si dejas tu personaje en el centro y al pulsar los controles se desplazan casas o elementos de alrededor. Parecerá que es tu personaje el que avanza por un territorio.
  • BIT 5: flag de colisionador. Todos los sprites con este flag activo son considerados por la función |COLSPALL, a la hora de detectar su posible colisión con el resto de sprites.
  • BIT 6: flag de sobreescritura: si este flag está activo, el sprite se podrá desplazar por encima de un fondo, restableciéndolo al pasar. Esta es una opción avanzada e implica el uso de una paleta de color especial, de 9 colores. La sobreescritura tiene este “precio”.
  • BIT 7: flag de ruta: si este flag esta activo, el comando |ROUTEALL te permitirá mover un sprite cíclicamente a través de una trayectoria que tu definas, definida por una serie de segmentos. El comando |ROUTEALL sabe en qué segmento y posición se encuentra cada sprite y si llega a un cambio de segmento, modifica la velocidad del sprite de acuerdo a las condiciones del siguiente segmento. |ROUTEALL no mueve al sprite, solo modifica su velocidad. Para moverlo hay que usarlo conjuntamente con |AUTOALL.
8BP

Ejemplos de asignación del valor del byte de status:

Típico enemigo: un sprite que se debe imprimir en cada ciclo, con detección de colisión con otros sprites y animación debe tener:

status = 1(bit 0) + 2 (bit1) + 4 (bit 2) =7 =&x0111

Una casa que se desplaza al movernos: un sprite que se imprime en cada ciclo, pero sin detección de colisión con otros y movimiento relativo

status = 1(bit 0) + 0 (bit1) + 0 (bit 2) + 0 (bit 3) + 16 (bit 4) =17 =&x10001

Una fruta que nos da bonus: es un sprite que no se imprime en cada ciclo, pero tiene detección de colisión

status = 0(bit 0) + 2 (bit1) = 2 =&x10

Una nave que va a seguir una trayectoria predefinida. Va a requerir del flag de ruta, el de movimiento automático, el de animación, el de colisión y el de impresión. Esta vez te lo voy a poner en binario directamente. Como ves el bit 7 lo he puesto a 1, después hay 3 ceros porque no he puesto el de sobreescritura ni el de colisionador ni el de movimiento relativo y por último he puesto 4 flags activos correspondientes respectivamente a los de movimiento automático, animación, colisión e impresión

status=10001111

La tabla de atributos de sprites se compone de 32 entradas de 16 bytes cada una, comenzando en la dirección 27000.

El motivo de tener 16 bytes no es otro que el del rendimiento, ya que calcular la dirección del sprite N implica multiplicar por 16, lo cual, al ser un múltiplo de 2, se puede hacer con un desplazamiento. Esto es útil en operaciones que involucran un único sprite. Para operaciones que recorren la tabla de sprites (como |PRINTSPALL o |COLSP), internamente se recorre la tabla con un índice al que se le suma 16 para pasar de un sprite al siguiente. La suma es lo más rápido en ese caso.

Los atributos que tiene cada sprite son:

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos 3

La dirección de memoria donde se almacenan las coordenadas de cada sprite se pueden calcular así:

Dirección coordenada Y =27000 + 16*N +1

Dirección coordenada X =27000 + 16*N +3

Accediendo con POKE a esas direcciones podemos modificar su valor, aunque también dispones de |LOCATESP.

La librería 8BP no usa “pixels” en la coordenada X, sino bytes, de modo que la coordenada X que cae dentro de la pantalla se encuentra en el rango [0..79]. La coordenada Y se representa en líneas de modo que el rango representable en pantalla es [0..200]. si ubicas un sprite fuera de esos rangos, pero parte del sprite se encuentra en la pantalla, la librería hará el “clipping” y pintará el trozo que se tenga que ver.

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos 4

Las direcciones de los atributos de los 32 sprites se pueden manejar con PEEK y POKE, aunque la asignación de secuencia de animación y de ruta implican más operaciones y si quieres cambiarlas no basta con un POKE, sino que hay que usar |SETUPSP. Aquí tienes la lista de direcciones de todos los atributos de los 32 sprites:

8BP: Cómo pintar SPRITES tras el fondo y la tabla de atributos 5
Direcciones de atributos de los 32 sprites

El espacio ocupado por cada sprite en la tabla es de 16 bytes. Como ves las coordenadas X e Y son números de 2bytes. Los sprites aceptan coordenadas negativas por lo que puedes imprimir parcialmente un sprite en la pantalla, dando la sensación de que va entrando poco a poco. No podrás establecer coordenadas negativas con POKE, pero si podrás hacerlo con |LOCATESP y también con |POKE, que es una versión del comando POKE de BASIC pero que acepta números negativos (y números de 16 bit).

Es una buena práctica ubicar al personaje o nave espacial en la posición 31 (hay 32 sprites numerados del 0 al 31). Si tu nave tiene la posición 31 se imprimirá la última, encima del resto de sprites en caso de solape.

¿Estas programando un juego para Amstrad CPC?

En la próxima semana tendremos un nuevo artículo sobre esta fantástica librería con la puedes programar juegos para tu Amstrad CPC.

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

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