05-Controles

Aventuras en Megadrive: Controles

icono

Controles

Vamos a aprender como detectar los controles de la consola.

Lo primero es llamar a JOY_init() al principio del main(). Esta función resetea los controles y mira qué controles están conectados. Podemos tener un mando, dos o más (multitap). No obstante para detectar mandos estándar *creo* que no es necesario, a ver si alguien me confirma este punto.

Dos formas de manejar los controles. Una síncrona (se ejecutará cada frame) y otra asíncrona (se ejecutará sólo cuando se pulse un botón).

Cual elegir dependerá de cómo se controle nuestro juego. Incluso ambas.

 

FORMA SÍNCRONA

Es una simple función que es llamada en cada ciclo del bucle principal.

//declaración al principio del main.c
static void handleInput(); 
...
...
...
//Bucle principal 
while(TRUE) { 
...
 //recoje la entrada de los mandos 
 handleInput(); 
 ...
}

Aparte ponemos nuestra función, simplemente comprobamos qué estamos pulsando:

static void handleInput()
{
  //variable donde se guarda la entrada del mando
  u16 value = JOY_readJoypad(JOY_1);

  //si pulsamos izquierda...
  if (value & BUTTON_LEFT)
      //mover personaje a la izquierda

  //si pulsamos derecha...
  if (value & BUTTON_RIGHT)
      //mover personaje a la derecha

  //etc
}

Ten en cuenta que esto se ejecuta cada frame. Por tanto  si metemos mucho código en esta función, podría afectar al juego.

 

FORMA ASÍNCRONA

La función asíncrona detecta cuando hay un cambio en el estado de algún botón.
Se define al inicio del programa.

static void joyEvent(u16 joy, u16 changed, u16 state);

Después, justo antes del bucle principal del main ponemos:

JOY_setEventHandler(joyEvent);

Esto activa un callback: Cuando se detecte un cambio en el estado de algún botón se ejecutará automáticamente joyEvent().

No necesitamos poner nada en el bucle principal del main. Será el SGDK el que ejecutará la función cuando corresponda. En esa función debemos comprobar qué botón se ha pulsado y actuar en consecuencia.

Un ejemplo:

static void joyEvent(u16 joy, u16 changed, u16 state)
{
  // botón START
  if (state & BUTTON_START)
  {
     //hemos pulsado el botón START
  }
  else if (changed & BUTTON_START)
       {
       //hemos soltado el botón START
       }

  if (changed & (BUTTON_A | BUTTON_B | BUTTON_C))
  {
   //hemos soltado A, B o C
  }
}

 

Esta forma de detectar pulsaciones funcionan porque detectamos cambios. Pero si dejamos pulsado el botón constantemente, no detectará una segunda pulsación hasta que soltemos y volvamos a pulsar, ya que tener apretado un botón no es un cambio, hasta que se suelta.

Por ejemplo, imaginemos el juego de Sonic, con este código podríamos usar ‘A’ para hacer un salto. Sonic hará el salto y hasta que no soltemos el botón ‘A’ no podremos hacer otro. Perfecto.

Pero… ¿y el auto-disparo en un matamarcianos? No funcionaría.

 

 

CONSTANTES

Estas son las constantes que nos interesará chequear:

JOY_1 / JOY_2: Pad Jugadores 1 y 2.
BUTTON_START, BUTTON_A, BUTTON_B, BUTTON_C: Botones mando de 3 botones.
BUTTON_X, BUTTON_Y, BUTTON_Z, BUTTON_MODE:  Botones mando de 6 botones.
BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT: El D-PAD.
if (state & XXXX):   Hemos pulsado el botón XXXX
if (changed & XXXX): Hemos soltado el botón XXXX

Hay más cosas que contar pero en principio no las voy a usar, os remito a la Wiki del SGDK. Pero si comentaré JOY_waitPressBtn(), que servirá para pasar las pantallas de la Intro y las pantallas entre fases.

JOY_waitPressBtn(): Espera a que se pulse un botón cualquiera (A,B ó C)

 

OTROS CONTROLES

Hay otros tipos de controles diferentes a los mandos de siempre. El Menacer, el ratón, un trackball, etc. No voy a entrar en ese terreno pues no les voy a dar uso.

 

EJEMPLO PRÁCTICO

En el SGDK hay una carpeta llamada Samples. Copy+Paste a tu carpeta de proyectos.
En esta carpeta hay ejemplos y tutoriales. Abre el proyecto JOYTEST, curiosea un poco.

 

Anuncios