Y nos vamos a los eventos en SDL, de Tutorial de libSDL para la programación de videojuegos.
La estructura principal es
typedef union{
Uint8 type;
SDL_ActiveEvent active; //tipo de evento
SDL_KeyboardEvent key;
SDL_MouseMotionEvent motion;
SDL_MouseButtonEvent button;
SDL_JoyAxisEvent jaxis;
SDL_JoyBallEvent jball;
SDL_JoyHatEvent jhat;
SDL_JoyButtonEvent jbutton;
SDL_ResizeEvent resize;
SDL_QuitEvent quit;
SDL_UserEvent user;
SDL_SysWMEvent syswm;
} SDL_Event;
Una breve explicación:
- active: evento de activación. Informa de la situación del foco sobre la ventana.
- key: evento producido por el teclado.
- motion: evento producido por movimiento del ratón.
- button: evento producido por el botón del ratón.
- jaxis: evento de movimiento del eje del joystick.
- jball: evento de movimiento del trackball del joystick.
- jhat: evento de movimiento del minijoystick o hat del dispositivo.
- jbutton: evento por botón del mando.
- resize: evento por redimensionado de ventana.
- quit: evento al cerrar aplicación.
- user: evento definido por el usuario.
- syswm: evento indefinido producido por el gestor de ventanas.
Formas de capturar eventos
Waiting: El programa espera por los eventos que se produzcan. Técnica muy utilizada en sistemas de gestión, donde no hay tareas en segundo plano, pero en juegos es poco útil.
int SDL_WaitEvent(SDL_Event *event);
Cuando se produce un evento, se rellenan los datos de event. Devuelve 1 si se ha copiado correctamente y eliminado de la lista de eventos. Cero al contrario. Si se pasa NULL, devuelve que ha pasado pero sin variar la cola.
Acceso directo al estado de eventos del dispositivo: Podemos acceder simbólicamente al hardware y leer el estado de un dispositivo discriminando la información con la idea de seleccionar sólo la que es relevante para nosotros. En realidad accedemos al sistema de eventos que es una capa superior a la de hardware que nos presenta la información para que podamos manejarla de forma cómoda.
Con éste método se peuden perder eventos. Cada vez que queramos consultar el estado, debemos actualizar primero con
void SDL_PumpEvents(void);
Polling:Técnica muy común, almacenamos los eventos en una cola para consultar en cualquier momento que deseemos (sondeo). SDL proporciona la cola.
Básicamente es comprobar si hay eventos, tratarlos si hay e ir haciendo otras tareas. Muy adecuado para videojuegos.
int SDL_PollEvent(SDL_Event *event);
Devuelve cero si no hay eventos pendientes, uno al contrario. Si le pasamos NULL, el evento no se elimina de la cola.
Teclado
El tipo de evento que muestra el teclado es SDL_KEYUP o SDL_KEYDOWN. Dentro de su estructura tiene un campo state, que resulta redundante, con los valores SDL_PRESSED y SDL_RELEASED.
typedef struct {
Uint8 type;
Uint8 state;
SDL_keysym keysym;
} SDL_KeyboardEvent;
keysym tiene la siguiente estructura:
typedef struct{
Uint8 scancode; //desaconsejado ya que depende del teclado y del sistema
SDL_Key sym; //tecla pulsada. Constantes SDL como SDL_a
SDLMod mod; //teclas especiales pulsadas (Ctrl, Alt, Shift)
Unit16 unicode; //por defecto no es rellenado
} SDL_Keysym;
Para que el campo unicode se rellene, se activa con:
int SDL_EnableUNICODE(int enable);El cual devuelve el estado anterior al cambio.
0-Desactivado
1-Activado
2-sin cambio (para consulta)
En algunas aplicaciones es interesante que si pulsamos cierta tecla durante un tiemp, dicha letra oacción se repita varias veces. Para activar esta opción hemos de llamar a :
int SDL_EnableKeyRepeat(int delay, int interval);
La función devuelve cero si todo ha ido bien o -1 ante errores.
delay: tiempo que deve esperar antes de hacer efectiva la repetición.
interval: cada cuánto tiempo se repite.
Para ambos valores, SDL proporciona lo que a su juicio son valores adecuados. Se pueden obtener con las constantes SDL_DEFAULT_REPEAT_DELAY y SDL_DEFAULT_REPEAT_INTERVAL.
Si queremos acceder de forma directa al teclado y consultar su estado tenemos la función:
Uint8 *SDL_GetKeyState(int *numkeys);
El parámetro que recibe especifica el tamaño del vector que queremos obtener. Es habitual poner NULL como parámetro, lo que produce que la función nos devuelva el valor del estado para todas las teclas. Para consultar en el vector se usan las mismas constantes del campo sym. Si la tecla está pulsada, será 1, cero al contrario.
Para conocer el estado de las teclas modificadoras y forzar el estado de alguna de ellas tenemos
SDLMod SDL_GetModState(void);
void SDL_SetModState(SDLMod modstate);
Y por último, si queremos conocer el nombre de una tecla de forma humana, la siguiente función:
char *SDL_GetKeyName(SDLKey key);
Y hasta aquí hoy, es mucho. Unos cuantos pensaréis que estoy pasando el tutorial del pdf al blog, y en parte es cierto, ya avisé que esto no iba a ser una especie de clase, sino una especie de apuntes/resumen de lo que leo y aprendo. Y que sepáis que hasta aquí es la página 216 del tutorial, con lo que creo que lo resumo bastante jajaja.