Lección 9 – Scroll por planos

Aventuras en Megadrive: Scroll por Planos

Datos útiles:

  • MD maneja por HW dos planos de fondo: Planos A y B.
  • Sólo los planos A y B pueden tener scroll.
  • Dicho scroll puede ser por plano, por tile o por línea.
  • Cada plano lo componen tiles de 8×8 píxels. Tile = Patrón = carácter.
  • Por defecto el plano visible son 40×28 tiles (Columnas x Filas)=1120 tiles visibles.
  • Por defecto el plano completo son 64×32 tiles=2048 tiles.
    Esto incluye tiles dentro de pantalla, visibles, y fuera de pantalla, no visibles.
  • Los planos pueden tener otras dimensiones, las combinaciones admitidas son (32×32, 32×64, 32×128, 64×32, 64×64, 128×32). Máx 4096 tiles.
  • A más tamaño de plano = menos VRAM disponible para sprites.
  • Existe un plano opcional llamado window, que no es más que una parte estática del plano A (dicha parte no tendrá scroll). Suele usarse para el marcador.

Por defecto el SGDK configura los planos con un tamaño de 64×32 tiles=512×256 pixels. A 320x224px eso son casi 2 pantallas de ancho y suele ser suficiente para la mayor parte de los juegos.

 

SCROLL SIMPLE: POR PLANO

En primer lugar hemos de configurar el tipo de scroll:

VDP_setScrollingMode( scroll_horizontal, scroll_vertical );

Sólo necesitamos hacerlo una vez indicando tipo de scroll horizontal y vertical (usemos uno o ambos). Importante indicar que se aplica a ambos planos A y B. Por ejemplo:

VDP_setScrollingMode ( HSCROLL_PLANE , VSCROLL_PLANE);

Le indica al SGDK que vamos a mover los planos A y B por plano tanto en la horizontal como en la vertical (y no por tile o línea). De momento vamos a olvidarnos de mezclar distintos tipos de scroll para simplificar.

En segundo lugar, y ya dentro del bucle principal, hemos de decirle al VDP cuánto queremos que se mueva el plano:

VDP_setHorizontalScroll(plano, offset);
VDP_setVerticalScroll(plano,   offset);

Lo que realmente hace la consola es dibujar el plano desde el punto que nosotros le indiquemos. Por defecto es cero, pero si aumentamos el desplazamiento (scroll offset en inglés), el plano se comienza a dibujar desde dicho punto. Variando el desplazamiento, poco a poco, creamos la ilusión de movimiento del plano o scroll.

Captura017

Si el plano es una imagen, y al dibujarla se alcanza el final, se sigue pintando desde el principio de dicha imagen. Es una técnica habitual de la época para simular planos sin fin.

Por supuesto podemos mover un plano y dejar el otro quieto. O mover ambos planos a velocidades distintas, en el mismo sentido o cada uno en una dirección.

Si ponemos un sprite en pantalla éste no se moverá junto con el scroll. Recordemos que el plano de sprites es independiente de los planos de scroll y además es un plano sin scroll. Por tanto mover un sprite a la vez que se hace scroll requiere cierta planificación, lo veremos en una futura entrada. De momento nos centraremos en trabajar con los planos.

Si se nos olvida indicar el tipo de scroll con VDP_setScrollingMode (), los valores por defecto son HSCROLL_PLANE+VSCROLL_PLANE, es decir, por planos.

 

Para muestra el primer ejemplo sobre scroll que puedes encontrar en mi github.

En este ejemplo esto es lo que nos vamos a encontrar:

  • Movemos el plano A (solo horizontalmente), el plano B permanece estático.
    s16 offset_H_PlanoA = 2;
    [..]
    while(1)
      VDP_setHorizontalScroll(PLAN_A, offset_H_PlanoA);

video04

  • Movemos el plano A (en todas direcciones), el plano B permanece estático.
    VDP_setHorizontalScroll(PLAN_A, offset_H_PlanoA);
    VDP_setVerticalScroll(  PLAN_A, offset_V_PlanoA);

     

video05

  • Movemos el plano B (en todas direcciones), el plano A permanece estático.
    s16 offset_H_PlanoB = 1;
    [..]
    while(1){
      //PLANO A
      VDP_setHorizontalScroll(PLAN_A, 0);
      VDP_setVerticalScroll(  PLAN_A, 0);
      //PLANO B
      VDP_setHorizontalScroll(PLAN_B, offset_H_PlanoB);
      VDP_setVerticalScroll(  PLAN_B, offset_V_PlanoB);  }

video06

  • Movemos ambos planos (en todas direcciones), cada uno a una velocidad.
     //PLANO A: scroll horizontal y vertical
    VDP_setHorizontalScroll(PLAN_A, offset_H_PlanoA);
    VDP_setVerticalScroll(  PLAN_A, offset_V_PlanoA);
    
    //PLANO B: scroll horizontal y vertical
    VDP_setHorizontalScroll(PLAN_B, offset_H_PlanoB);
    VDP_setVerticalScroll(  PLAN_B, offset_V_PlanoB);

video09

  • Al ejemplo anterior le añadimos un sprite (estático) en pantalla. Fíjate que no se mueve en absoluto de su posición. En el código añadimos el sprite de Sonic (tal y como hemos hecho tantas veces). En la detección de input del PAD, animamos a Sonic según pulsemos derecha o izquierda (o no pulsemos).

video10

  • Mismo ejemplo pero dejamos que el sprite se mueva por la pantalla, impedimos que salga de la zona visible. En el código añadimos que la posición del sprite se mueva según pulsemos el PAD, pero  sin dejar que salga de la pantalla.

video12

Decir que estos ejemplos con sprite no son para nada ilustrativos, ya que aunque sabemos en qué posición (x,y) respecto a la pantalla visible, no sabemos la posición (x,y) respecto al “mundo” sobre el cual se mueve el personaje. Lo veremos más adelante.

Tampoco hemos hablado aquí del plano WINDOW. Lo veremos también más adelante.

 

CURIOSIDAD:  ¿POR QUÉ SE MUEVE EL TEXTO? Cuando ponemos texto en pantalla, lo que hacemos realmente es pegar el carácter (que es un tile) en el fondo, pasan a formar parte de él. Por eso, al mover el fondo, se mueven también las letras.

 

GITHUB

El código de esta lección, y de todas las demás, lo podrás encontrar en mi github:

https://github.com/danibusvlc/aventuras-en-megadrive