En este nuevo post vamos a ver como controlar eventos. En este caso cerrar la ventana, la pulsación de algunas teclas y con ello mover en pantalla algo.
Para ello he recurrido al típico ejemplo de una nave que movemos en el eje x e y.
Aquí se puede bajar todo el tinglado para seguir el tutorial: teclado.zip
Está vez en este quinto post no voy a repetir el rollo de como compilarlo ni como crear el makefile ya que presupongo que si lees esto es que te interesa y lo mismo ya has visto los anteriores.
Antes de mostrar el código hemos de saber que para usar el tipo bool en C hemos de añadir stdbool.h . Hemos de saber también que vamos a precisar de 2 mapas de bits (uno de una nave y otro del fondo):
5
Pongo el código y tras ello intentaré explicarlo:
#include <SDL.h> #include <stdbool.h> int main(int argc, char ** argv) { SDL_Window * ventana; SDL_Renderer * render; SDL_Event evento; SDL_Surface * imagenNave; // Nave SDL_Texture * texturaNave; // Nave SDL_Surface * imagenFondo; // Fondo Mar SDL_Texture * texturaFondo; // Fondo Mar imagenNave = SDL_LoadBMP("res/nave.bmp"); // Cargamos el mapa de bits de la nave imagenFondo = SDL_LoadBMP("res/mar.bmp"); // Cargamos el bmp del fondo. int anchoNave = 128; // Definimos el ancho de la nave int altoNave = 113; // Definimos el alto de la nave int x = (640/2)-(anchoNave/2); // Eje x - Posición inicial de la nave int y = (480/2)-(altoNave/2); // Eje y - Posición inicial de la nave bool quit = false; SDL_Init(SDL_INIT_VIDEO); ventana = SDL_CreateWindow("Controlando el teclado",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL); if (ventana == NULL) { printf("No se pudo crear la ventana: %s\n", SDL_GetError()); return 1; } render = SDL_CreateRenderer(ventana, -1, 0); texturaFondo = SDL_CreateTextureFromSurface(render, imagenFondo); SDL_RenderCopy(render, texturaFondo, NULL, NULL); SDL_RenderPresent(render); texturaNave = SDL_CreateTextureFromSurface(render, imagenNave); SDL_Rect dstrect = { x, y, altoNave, anchoNave }; SDL_RenderCopy(render, texturaNave, NULL, &dstrect); SDL_RenderPresent(render); while (!quit) { SDL_WaitEvent(&evento); switch (evento.type) { case SDL_QUIT: quit = true; break; case SDL_KEYDOWN: switch (evento.key.keysym.sym) { case SDLK_LEFT: x--; break; case SDLK_RIGHT: x++; break; case SDLK_UP: y--; break; case SDLK_DOWN: y++; break; } break; } SDL_RenderCopy(render, texturaFondo, NULL, NULL); SDL_RenderPresent(render); SDL_Rect dstrect = { x, y, altoNave, anchoNave }; SDL_RenderCopy(render, texturaNave, NULL, &dstrect); SDL_RenderPresent(render); } }
Usando las teclas cursor (arriba, abajo, izquierda, derecha) se moverá la nave, aunque muy lento.
Se puede hacer que en vez de pixel a pixel se mueva de 5 en 5 así:
case SDLK_LEFT: x=x-5; break; case SDLK_RIGHT: x=x+5; break; case SDLK_UP: y=y-5; break; case SDLK_DOWN: y=y+5; break;
SDL_QUIT es el evento cuando el usuario solicita salir (pulsando en la x de la ventana).
Hemos declarado una variable booleana (true/false) llamada quit con el valor false.
Durante todo el tiempo que la ventana esté abierta estará comprobando si eso cambia, en el caso de que solicitemos cerrar la ventana en el evento SDL_QUIT indicaremos que el valor de la variable quit es true y eso servirá para que se salga del bucle while.
En anteriores posts no metíamos ningún bucle, básicamente dejábamos unos segundos lo que queríamos y el programa llegaba a su fin cerrándose la ventana. Ahora que ya sabemos como controlar eventos (al menos algunos) ya no vamos a trabajar así.
La posición de la nave.
La posición de la nave se puede realizar con las variables que hemos declarado: x e y.
int x = (640/2)-(anchoNave/2); // Eje x - Posición inicial de la nave int y = (480/2)-(altoNave/2); // Eje y - Posición inicial de la nave
En vez de poner de valor a «x» el entero 0 y a «y» también 0 podemos realizar algunas restas y divisiones para centrar la nave.
Si analizamos eso simplemente estamos dividiendo el ancho y alto de la ventana y luego a eso restándole la mitad del ancho y alto de la nave.
Aquí SDL_Keycode se puede ver que en vez de los cursores podríamos usar también otras teclas.
No tiene mucho más misterio. En futuras entradas iremos controlando esto un poco más e incluso realizar algunos ejemplos de control de un joystick o el ratón.
Saludos cordiales.