Sprites 2, rotando voy…

En este artículo daremos un pasito más en el tratamiento de los sprites.

 

Antes de empezar

Si es la primera vez que llegas aquí, te recomiendo que consultes antes estos artículos:

 

El objetivo

En este artículo hablaremos sobre algunas capacidades “extra” de los sprites relacionadas con la rotación, espejos horizontales y verticales, y la paleta de colores. En el artículo anterior “Sprites 101” vimos como crear sprites y dibujarlos en la pantalla, hoy vamos a jugar un poco con las posibilidades del método “UpdateSprite” que nos proporciona NextLib.

Vamos a trabajar solo con sprites de 8 bits, ya que me parecen más interesantes, al mismo tiempo que sencillos, al coincidir un pixel con un byte. Podéis encontrar el archivo de sprites dentro del proyecto “NextSprites2.zip”, en la carpeta “data”

 

El proyecto

En la sección “Recursos” del final de este artículo podéis descargar el proyecto completo con todos los ficheros, incluido el fichero de sprites y todo el código .bas

Vamos a crear una carpeta “NextSprites2” dentro de la carpeta “C:\ZXNext\NextBuildv7\Sources\”, y dentro colocaremos el contenido del fichero “NextSprites2.zip”, quedando algo parecido a esto:

 

UpdateSprite

El método UpdateSprite require los siguientes parámetros:

  • x (uinteger): Posición X del Sprite, de 0 a 320
  • y (ubyte): Posición Y del Sprite, de 0 a 256
  • spriteId (ubyte): Identificador del Sprite con el que queremos trabajar, de 0 a 128
  • pattern (ubyte): Patrón/imagen que utilizaremos para el Sprite indicado de 0 a 63 para sprites de 8 bits
  • mflip (ubyte): Atributo 2*
  • anchor (ubyte): Atributo 4*

Como ya explicamos en el artículo anterior, X e Y funcionan a resolución de 320×256, aunque los podemos configurar para que solo sean visibles dentro de la resolución clásica de 256×192. En ese caso, el Sprite empieza a ser visible a partir de la coordenada (32,32), que sería la esquina superior izquierda, y dejan de ser visibles en las coordenadas (287,223), que es la esquina inferior derecha en la resolución clásica de 256×192.

  • spriteId indica el Sprite con el que queremos trabajar. Podemos tener hasta 128 sprites, aunque solo se garantiza la impresión de 100 de ellos en pantalla.
  • pattern indica el número del gráfico, dentro de nuestro archivo de sprites .spr, que utilizaremos para el spriteId que hemos generado. Esto nos permite usar el mismo patrón/imagen para dos sprites diferentes, o cambiar el patrón/imagen de un Sprite, por ejemplo, para simular un movimiento.
  • mflip, que así se etiqueta en NextLib, realmente equivale a parte del atributo 2 de los sprites, y que veremos en detalle un poco más abajo.
  • anchor, representa el atributo 4 de los sprites, que veremos en el siguiente artículo.

 

mflip: Atributo 2

  • PPPP (bits 4 a 7): Son cuatro bits que representan el desplazamiento sobre la paleta de 4 bits, lo que nos permite “jugar” con efectos de paleta que solo afectan a los sprites.
  • XM (bit 3): Controla el espejo horizontal. Si este bit está a 1, el Sprite se refleja horizontalmente, si es 0 se muestra tal como está definido en el patrón/imagen.
  • YM (bit 2): Controla el espejo vertical. De forma similar a XM, cuando está a 1 hace que el Sprite se refleje verticalmente.
  • R (bit 1): Hace que el Sprite se rote 90 grados en el sentido de las agujas del reloj.
  • X8/PR (bit 0): Este bit se machaca con la parte alta de la coordenada X, por lo que su valor es ignorado.

 

Sprites2.bas

El código de ejemplo de este proyecto es similar al que ya hemos visto en el artículo anterior. Este es el código completo:

' -----------------------------------------------------------------------------
' - Sprites2 ------------------------------------------------------------------
' - Licencia MIT (Haz lo que quieras con el código) ---------------------------
' - Gráficos por F3M0 (@Bit_fans -> https://twitter.com/bit_fans) -------------
' -----------------------------------------------------------------------------

' - Includes ------------------------------------------------------------------

#include <NextLib.bas>

' - Inicio --------------------------------------------------------------------

Main()
stop

' - Sub principal -------------------------------------------------------------

sub Main()
  dim contador, paleta as ubyte

' Inicializamos el sistema

  Inicializar()

' Parámetros mflip

  print at 0,0;ink 5;"Parametro mflip"
  print at 1,0;" -- XM YM R "
  UpdateSprite( 40,48,0,0,0,0)            ' Sin atributos
  UpdateSprite( 64,48,1,0,%00001000,0)    ' XM - Espejo horizontal (bit 3)
  UpdateSprite( 88,48,2,0,%00000100,0)    ' YM - Espejo vertical (bit 2)
  UpdateSprite(112,48,3,0,%00000010,0)    ' R - Rotación 90 grados (bit 1)

' Rotaciones

  print at 5,0;ink 6;"Rotaciones"
  print at 6,3;"Norte: Sin parametros"
  UpdateSprite(40, 80,4,0,0,0)            ' Sin parámetros'
  print at 9,3;"Este: R (bit 1)"
  UpdateSprite(40,104,5,0,%00000010,0)    ' Rotar 90 grados (bit 1)
  print at 12,3;"Sur: XM + YM (bits 3+2)"
  UpdateSprite(40,128,6,0,%00001100,0)    ' Espejo horizontal + espejo vertical (bit 3+2)
  print at 15,3;"Oeste: XM + R (bits 3+1)"
  UpdateSprite(40,152,7,0,%00001010,0)    ' Espejo horizontal + rotación 90 (bit 3+1)

' Bucle de rotación de la paleta

  contador=0
  while inkey$=""     ' Repetimos hasta que se pulse una tecla'
    print at 18,0;ink 6;"Paleta ";contador

' El desplazamiento de la paleta se define en los bits 4 a 7

    paleta=contador << 5    ' En este caso desplazaremos el contador x 2, por eso rotamos 5 bytes en vez de 4
    if contador=7 then      ' Contamos de 0 a 7
      contador=0
    else
      contador=contador+1
    end if

' Mostramos 4 sprites con el mismo patrón y paleta

    UpdateSprite(40,184,8,1,paleta,0)
    UpdateSprite(56,184,9,1,paleta,0)
    UpdateSprite(72,184,10,1,paleta,0)
    UpdateSprite(88,184,11,1,paleta,0)

' Pausa para ralentizar la animación

    asm
      halt
    end asm
  wend
end sub

' - Inicializa el sistema -----------------------------------------------------

sub Inicializar()
  NextReg($07,3)          ' Velocidad del procesador a 28MHz

' Inicializamos ULA

  border 0: paper 0: ink 7: cls

' Inicializamos Layer2

  NextReg($15,%00001001)  ' Activamos Sprites y layers como SUL
  ShowLayer2(1)           ' Mostramos la layer 2

' Creamos los sprites

  LoadSD("Sprites2.spr",$c000,$4000,0)   ' Cargamos los sprites en $c000
  InitSprites(2,$c000)                ' Inicializamos 10 sprites
end sub

 

Tenemos una SUB Inicializar, que prepara el sistema, y un método Main que implementa el ejemplo.

 

Rotación y espejo

Para este ejemplo usaremos el patrón/imagen 0:

En la primera parte, después del comentario “Parámetros mflip”, imprimimos 4 sprites (0 a 3) activando los atributos espejo horizontal, espejo vertical y rotación para ver su efecto por separado.

UpdateSprite( 64,48,1,0,%00001000,0)

En este caso imprimimos el Sprite 1 en las coordenadas 64,48 que para la ULA clásica serían las coordenadas 32,16, usando el patrón/imagen 0, con el atributo “Espejo horizontal” (bit 3) activado.

El símbolo % en Boriel ZX Basic significa que el valor se representa en binario. Un byte está compuesto por 8 bits, es decir por ocho ceros o unos, que normalmente se enumeran de izquierda a derecha empezando por el 0, así que el bit 3 es el cuarto dígito empezando por la izquierda.

A partir del comentario “Rotaciones”, imprimimos otros 4 sprites (del 4 al 7) del patrón/imagen 0, mezclando los diferentes atributos de espejo y rotación para conseguir que la bandera apunte hacia los 4 puntos cardinales, tal como vemos en la imagen:

En el siguiente caso estamos haciendo un espejo horizontal (bit 3) y una rotación (bit 1):

UpdateSprite(40,152,7,0,%00001010,0)

 

Paleta

A partir del comentario “Bucle de rotación de la paleta”, podemos ver un ejemplo de rotación de la paleta. Para ello usamos el patrón/imagen 1 de los sprites:

Vamos a imprimir 4 veces seguidas el mismo patrón/imagen usando 4 sprites diferentes, y aplicándole el mismo atributo.

La variable “contador” cuenta de 0 a 7, y la variable “paleta” nos ayuda a crear el atributo adecuado.

El primer factor a tener en cuenta es que para no complicar más el tema, utilizaremos la paleta por defecto del Next, por lo que vamos a utilizar los colores: 0, 32, 64, 96, 128, 160, 192 y 224. Para crear esta secuencia, desplazaremos 5 bits a la izquierda el “contador” con el operador “<<” que sirve para desplazar bits a la izquierda. Normalmente deberíamos desplazar 4 bits el valor del contador, pero para conseguir la secuencia deseada, rotamos 5 bits.

La secuencia se repite de forma indefinida, lo que hace que se produzca un efecto de movimiento, cuando realmente los sprites no se mueven.

 

Conclusiones

Podemos ahorrar memoria definiendo solo parte de los sprites que necesitamos, y además podemos crear efectos chulos con la paleta, pero aún hay más…

En el siguiente artículo seguiremos trabajando con los sprites para intentar desgranar todas, o casi todas, sus posibilidades.

 

Menciones y agradecimientos

Como siempre, a Boriel y a em00K por su labor, y muy especialmente a mis mecenas que me apoyan de forma incondicional.

 

Recursos

 

Deja una respuesta

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