Capítulo 4: Programación controlada por Eventos en SDL 2.
En este tema vamos a aprender como manejar eventos en SDL 2. En los juegos
mostrar gráficos es muy importante, pero también lo es manejar las
entradas del usuario. No creo que a alguien le interese un juego en el que
no se pueda controlar al personaje.
En el código, específicamente en la función
En el código, específicamente en la función
main
, después que se ha
inicializado SDL y cargado los medios, declaramos una bandera o indicador
quitar
de tipo booleano que se usará para registrar el momento en el que el
usuario desea abandonar la aplicación.
//Bandera del bucle principal
bool quitar = false;
//Controlador de Eventos
SDL_Event e;
bool quitar = false;
//Controlador de Eventos
SDL_Event e;
La bandera o indicador
quitar
lo inicializamos en
false
, luego declaramos un controlador de eventos
SDL_Event e;
que se usará para saber qué eventos realizó el usuario, como
presionar una tecla del teclado, un botón del mando de juegos o se hizo clic
con el mouse. En este programa simplemente vamos a esperar por que el usuario presione una tecla del teclado.
Luego de esto, iniciamos un bucle como sigue:
//Bucle principal
while(!quitar){
//Maneja la cola de eventos
while(SDL_PollEvent(&e) != 0){
//Si el usuario solicita salir
if(e.type == SDL_KEYDOWN){
quitar = true;
}
}
//Aplicamos la imagen en la superficie de la ventana
SDL_BlitSurface(bmpImagen, NULL, Superficie, NULL);
//Actualizamos la superficie de la ventana
SDL_UpdateWindowSurface(Ventana);
}
while(!quitar){
//Maneja la cola de eventos
while(SDL_PollEvent(&e) != 0){
//Si el usuario solicita salir
if(e.type == SDL_KEYDOWN){
quitar = true;
}
}
//Aplicamos la imagen en la superficie de la ventana
SDL_BlitSurface(bmpImagen, NULL, Superficie, NULL);
//Actualizamos la superficie de la ventana
SDL_UpdateWindowSurface(Ventana);
}
El bucle principal se ejecutará una y otra vez hasta que
Luego de esto, existe otro bucle dentro del bucle principal, este bucle de eventos procesa la cola de eventos hasta que esté vacía. Cuando nosotros presionamos una tecla del teclado o un botón, estos eventos se van colocando en orden secuencial en la cola de eventos. La función
Luego tenemos un
Luego de esto, nos queda el procesamiento del resto del código, en este caso las funciones
NOTA: Observe que esta parte del código es ineficiente, ya que se procesará código de forma repetida que sólo es necesario procesar una vez, pero aquí lo hacemos así de modo de mostrar cómo funciona el bucle principal, que es el alma de un programa de juegos.
El código fuente debe quedar de la siguiente forma:
quitar
sea true
,
en tutoriales anteriores, esperabamos algunos segundos mientras se mostraba
una imagen, esta vez esperaremos hasta que el usuario decida quitar el
programa.Luego de esto, existe otro bucle dentro del bucle principal, este bucle de eventos procesa la cola de eventos hasta que esté vacía. Cuando nosotros presionamos una tecla del teclado o un botón, estos eventos se van colocando en orden secuencial en la cola de eventos. La función
SDL_PollEvent
lo que hace
es colocar los eventos de la cola de eventos al parámetro que le hemos
pasado, es decir en "e
" para que podamos procesarlo, cuando la
cola de eventos está vacía SDL_PollEvent
retorna 0.Luego tenemos un
if
que
verifica el tipo de evento, si el evento es de tipo SDL_KEYDOWN
, es decir,
que se ha presionado alguna tecla del teclado,
entonces el indicador o bandera cambia a true
, si no, no se modifica.Luego de esto, nos queda el procesamiento del resto del código, en este caso las funciones
SDL_BlitSurface
y SDL_UpdateWindowSurface
.NOTA: Observe que esta parte del código es ineficiente, ya que se procesará código de forma repetida que sólo es necesario procesar una vez, pero aquí lo hacemos así de modo de mostrar cómo funciona el bucle principal, que es el alma de un programa de juegos.
El código fuente debe quedar de la siguiente forma:
//Encabezados de inclusión utilizado en
nuestros programas
#include <SDL.h>
#include <stdio.h>
//Declaración de la funciones
bool Inicializar(); // Inicialización de SDL y creación de Ventanas
bool cargarMedios(); // Carga los medios
void cerrar(); // Libera los medios y cierra SDL
//Inicialización de la ventana, la superficie y la imagen
SDL_Window* Ventana = NULL; //La ventana donde se renderizará la imagen
SDL_Surface* Superficie = NULL; //La superficie que contendrá la ventana
SDL_Surface* bmpImagen = NULL; //La imagen que se mostrará en la superficie
bool Inicializar(){
//Bandera de inicialización es correcta
bool correcto = true;
//Inicializa el subsistema de Video
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("ERROR: No se pudo inicializar SDL, Error SDL: %s\n", SDL_GetError());
correcto = false;
}
else{
//Se crea la ventana principal
Ventana = SDL_CreateWindow("Tutorial SDL 2", 50, 50, 640, 480, SDL_WINDOW_SHOWN);
if(Ventana == NULL){
printf("ERROR: No se pudo crear la ventana, SDL_Error: %s\n", SDL_GetError());
correcto = false;
}
else{
//Se crea la superficie para la ventana principal
Superficie = SDL_GetWindowSurface(Ventana);
}
}
//Salimos de la función
return correcto;
}
bool cargarMedios(){
//Bandera de carga correcta
bool correcto = true;
//Carga la imagen que se mostrará
bmpImagen = SDL_LoadBMP("mapaBits.bmp");
if( bmpImagen == NULL){
printf("No se pudo cargar la imagen %s SDL Error: %s\n", "mapaBits.bmp", SDL_GetError());
correcto = false;
}
//Salimos de la función
return correcto;
}
void cerrar(){
//Liberamos la superficie utilizada
SDL_FreeSurface(bmpImagen);
bmpImagen = NULL;
//Destruimos la Ventana para liberar recursos.
SDL_DestroyWindow(Ventana);
//Quitamos el subsistema de SDL.
SDL_Quit();
}
int main(int argc, char* args[]){
//Inicializa SDL y crea las ventanas
if(!Inicializar()){
printf("No se pudo inicializar\n");
}
else{
//Carga los medios
if(!cargarMedios()){
printf("No se pudo cargar los medios\n");
}
else{
//Bandera del bucle principal
bool quitar = false;
//Controlador de Eventos
SDL_Event e;
//Bucle principal
while(!quitar){
//Maneja la cola de eventos
while(SDL_PollEvent(&e) != 0){
//Si el usuario solicita salir
if(e.type == SDL_KEYDOWN){
quitar = true;
}
}
//Aplicamos la imagen en la superficie de la ventana
SDL_BlitSurface(bmpImagen, NULL, Superficie, NULL);
//Actualizamos la superficie de la ventana
SDL_UpdateWindowSurface(Ventana);
}
}
}
//Liberamos los recursos y cerramos SDL
cerrar();
//Salimos de main
return 0;
}
#include <SDL.h>
#include <stdio.h>
//Declaración de la funciones
bool Inicializar(); // Inicialización de SDL y creación de Ventanas
bool cargarMedios(); // Carga los medios
void cerrar(); // Libera los medios y cierra SDL
//Inicialización de la ventana, la superficie y la imagen
SDL_Window* Ventana = NULL; //La ventana donde se renderizará la imagen
SDL_Surface* Superficie = NULL; //La superficie que contendrá la ventana
SDL_Surface* bmpImagen = NULL; //La imagen que se mostrará en la superficie
bool Inicializar(){
//Bandera de inicialización es correcta
bool correcto = true;
//Inicializa el subsistema de Video
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("ERROR: No se pudo inicializar SDL, Error SDL: %s\n", SDL_GetError());
correcto = false;
}
else{
//Se crea la ventana principal
Ventana = SDL_CreateWindow("Tutorial SDL 2", 50, 50, 640, 480, SDL_WINDOW_SHOWN);
if(Ventana == NULL){
printf("ERROR: No se pudo crear la ventana, SDL_Error: %s\n", SDL_GetError());
correcto = false;
}
else{
//Se crea la superficie para la ventana principal
Superficie = SDL_GetWindowSurface(Ventana);
}
}
//Salimos de la función
return correcto;
}
bool cargarMedios(){
//Bandera de carga correcta
bool correcto = true;
//Carga la imagen que se mostrará
bmpImagen = SDL_LoadBMP("mapaBits.bmp");
if( bmpImagen == NULL){
printf("No se pudo cargar la imagen %s SDL Error: %s\n", "mapaBits.bmp", SDL_GetError());
correcto = false;
}
//Salimos de la función
return correcto;
}
void cerrar(){
//Liberamos la superficie utilizada
SDL_FreeSurface(bmpImagen);
bmpImagen = NULL;
//Destruimos la Ventana para liberar recursos.
SDL_DestroyWindow(Ventana);
//Quitamos el subsistema de SDL.
SDL_Quit();
}
int main(int argc, char* args[]){
//Inicializa SDL y crea las ventanas
if(!Inicializar()){
printf("No se pudo inicializar\n");
}
else{
//Carga los medios
if(!cargarMedios()){
printf("No se pudo cargar los medios\n");
}
else{
//Bandera del bucle principal
bool quitar = false;
//Controlador de Eventos
SDL_Event e;
//Bucle principal
while(!quitar){
//Maneja la cola de eventos
while(SDL_PollEvent(&e) != 0){
//Si el usuario solicita salir
if(e.type == SDL_KEYDOWN){
quitar = true;
}
}
//Aplicamos la imagen en la superficie de la ventana
SDL_BlitSurface(bmpImagen, NULL, Superficie, NULL);
//Actualizamos la superficie de la ventana
SDL_UpdateWindowSurface(Ventana);
}
}
}
//Liberamos los recursos y cerramos SDL
cerrar();
//Salimos de main
return 0;
}
Hasta aquí hemos visto como manejar eventos con SDL 2 y también vimos como se procesa la cola
de eventos. Puedes descargar
el código fuente completo aquí.
No hay comentarios:
Publicar un comentario