10-Sprites

Aventuras en Megadrive: Sprites

 

DATOS TÉCNICOS

  • Los sprites se colocan en el plano de Sprites.
  • La posición en pantalla de un sprite viene dada en píxels y no en tiles.
  • El plano de sprites es un plano fijo, no puede tener scroll.
  • Podemos tener un máximo de 80 sprites en pantalla.
  • Podemos tener hasta 20 sprites por línea horizontal.
  • Por defecto, los sprites creados primero aparecen dibujados sobre los últimos (a igual prioridad).
  • No obstante podemos controlar el orden en el que se dibujan los sprites.
  • Los sprites se almacenan y construyen con tiles, igual que los fondos. Por tanto podemos usar tiles tanto para hacer fondos como para hacer sprites.
  • Un sprite puede ser construido con un solo tile (1×1)=(8×8 píxels), pero también con varios tiles, con un máx de (4×4) tiles=(32×32 píxels).
  • SGDK nos permite utilizar multi-sprites de hasta 16×16 tiles, sprites enormes.
  • Una imagen de un sprite debe, por tanto, ser divisible por 8.

 

La forma de cargar un sprite en VRAM y dibujarlo es muy parecida a lo que hemos hecho con los planos/fondos. Pero hay algunas diferencias.

Para tener acceso a las funciones de manejo de sprites del SGDK añade:

#include "sprite.h"

Has de reservar memoria para guardar los sprites en la VRAM antes de usarlos.

SPR_init(max_num_sprites, tamaño_en_vram, buffer_descompresión);

Recordemos que se guardan como tiles. Si no tenemos claro los parámetros de esta función, escribiremos lo siguiente (equivale a usar los valores por defecto del SGDK):

SPR_init(0,0,0)

Antes de cargar un sprite, deberemos cargar su paleta (igual que hacíamos con los planos). Usaremos SPR_addSprite() para cargar los sprites en memoria. Tal y como hacemos con los planos, usaremos TILE_ATTR() para indicar la paleta, si lo mostramos invertido, etc.

Al contrario que con un fondo, los sprites irán cambiando su posición e incluso su aspecto, ya que pueden estar animados. El VDP de Megadrive por defecto mantiene los sprites frame tras frame, no los borra. Esto es, si un sprite cambia de posición o de animación, esto se hace (calcula) en el lado del procesador (en el famoso Motorola 68000), el VDP no se entera si no se lo decimos explícitamente.

La forma de hacer esto es usar  SPR_update(), normalmente en el bucle principal:

...

while(TRUE)
{
SPR_update();

VDP_waitVSync();
}

...

 

ZONA VISIBLE E INVISIBLE

Internamente para la MD el plano de sprites tiene normalmente 512×512 píxels, siendo el punto sup-izq de la pantalla el (128,128). EL SGDK toma ésta coordenada como (0,0) para facilitarnos la vida. Sabiendo que la resolución habitual es 320x224px, el SGDK nos permite tratar los sprites sabiendo que si su x=[0 .. 320] y su y=[0 .. 224], estos estará en la zona visible de la pantalla:

TV

Por tanto un sprite en (-20,300) no será visible. Tampoco uno situado en (450, 200).

Internamente, la MD no permite valores superiores a 512 para las coordenadas de un sprite. Si el valor la coordenada es superior a 512, es como si volviera a partir de 0. Por tanto un sprite en (300,815) equivale a (300, 815-512 = 303)=(300, 303).

Mucho ojo porque los límites de sprites (80 en total, 20 por línea) se aplican
también a aquellos en la parte no-visible de la pantalla.

 

¿Por qué tener un área superior a la parte visible de la pantalla?

Cargar sprites (que al final son tiles) en VRAM implica gastar tiempo. Normalmente no vamos a mostrar todos los sprites de una fase nada más comenzar. Por ejemplo, habrán enemigos que salgan al principio, otros al final, habrán sprites para el decorado, etc.

Podemos copiar esos tiles al principio de la fase en VRAM, dejando los sprites que no estamos usando fuera de pantalla, a la espera de usarlo en un momento determinado.

Para estos sprites fuera de pantalla se aplica el límite de 20 por línea, pero si nos pasamos, al no ser visibles, no se va a notar el “parpadeo”. No obstante sí cuentan para el máximo total de sprites, 80.

 

ARCHIVO RES

La forma de indicar al SGDK dónde están los sprites es similar, utilizaremos de nuevo un archivo RES aunque los parámetros son diferentes:

SPRITE nombre_variable "recurso.png" tiles_ancho tiles_alto FAST  veloc_ani

nombre variable: variable que usaremos en el main.c
recurso.png: el nombre del archivo (opcional: poner la ruta si está en subcarpetas)
tiles_ancho y tiles_alto: indicaremos aquí cuantos tiles tiene el sprite.
FAST: tipo de compresión, lo dejamos así de momento
veloc_ani: tiempo entre cada frame del sprite

Si el sprite son p.e. 32×16 pixeles, en [tiles_ancho] y [tiles_alto] pondremos 4 y 2 respectivamente ( 32/8 = 4  ,   16/8 = 2).

Para guardar las distintas animaciones de un personaje, normalmente se utilizan  spritesheets (hojas de sprites). Se trata de una imagen con todos los posibles sprites de . Ya sea quieto, corriendo, atacando, explotando… un ejemplo con Sonic

Captura9

En este caso [tiles_ancho] y [tiles_alto] serán respectivamente 6 y 6 (hay que contar los cuadritos que hay dentro del cuadro rojo).

La posición en pantalla de un sprite viene indicada por el punto sup-izq de dicho cuadro.

Es decir, los pies de Sonic estarán en distinta posición, hay que tener esto en cuenta a la hora de situar el sprite en pantalla.

Siguiendo con la explicación, todos los sprites de Sonic estarán en un cuadro 6×6:

Captura10

En realidad, internamente, la MD está manejando más de un sprite, ya que el máximo se supone que es 4×4 tiles por cada sprite. Para ello debemos usar multi-sprites.

El SGDK nos ahorra ese dolor de cabeza. Lo vemos en la siguiente entrada.

 

 

Anuncios