Hola a todos! Esta es la tercera lección en SDL 2. La información se toma de
esta fuente. No me gustaron los tutoriales de manejo de eventos de Lasy Foo, así que escribiré los míos, pero el material se puede encontrar
aquí y
aquí .
Y comenzamos, bienvenidos a la lección.
Eventos
Hoy enseñaremos nuestro programa para responder a eventos con la ayuda de
John .
Entonces comencemos. conecta SDL 2 y crea 3 variables globales y 2 constantes.
#include <SDL2/SDL.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL;
A continuación, escribimos 3 funciones ya conocidas de la última lección:
Init int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; }
Carga int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; }
Salir int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; }
Atención (!), Si copia el código de la lección anterior, no olvide cambiar la
sonrisa a
John .
Todo lo que debería decirse: decidí mostrar errores en la etapa de inicialización y carga de imágenes.
Entonces, continuemos. abra
main y llame a las funciones
Init y
Load .
int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } }
Ahora veamos cómo funciona cualquier aplicación. Cualquier programa que ejecute (Google Chrome, Paint, Minecraft) tiene un bucle principal que se ejecuta una gran cantidad de veces. Esto es necesario para el dinamismo. Anteriormente, escribimos un programa que solo mostraba una sonrisa durante 2 segundos, pero para que el programa aprenda a responder a las acciones del usuario (o al menos muestre la imagen sin cesar), necesita un bucle
While .
Se repetirá constantemente y en él ya podemos hacer lo que queramos, por ejemplo, procesar eventos. Pero antes de comenzar el ciclo de glan, creemos algunas variables.
bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y;
Analizaremos todo ahora. Primero, cree una variable de
ejecución de tipo
boolean . Esta variable es responsable de la ejecución del bucle: mientras el programa se está ejecutando, es
cierto , si queremos detener la ejecución, establezca esta variable en
falso . A continuación, cree un objeto
e de la clase
SDL_Event . Las propiedades de este objeto contendrán los datos del evento recibido, además serán más detallados. Después de eso creamos un objeto
r de la clase
SDL_Rect . Este es el rectángulo requerido para dibujar el objeto con algunas coordenadas que necesitamos. Luego creamos variables
x e
y de tipo
int . Asigne inmediatamente sus valores a cero. Estas serán las coordenadas de nuestro personaje. Al siguiente elemento, asignamos las variables
rx y
ry los valores
x e
y, respectivamente.
rx y
ry son las coordenadas del rectángulo
r .
Es hora de abrir el ciclo principal.
while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); }
Analicemos este código. Tenemos dos ciclos El primero principal es el principal, que funciona ejecutando variable, como se mencionó anteriormente. El segundo ciclo es responsable de manejar los eventos.
La función
SDL_PollEvent () abre la cola de eventos recibidos en una ejecución del bucle principal, elimina el último evento y escribe datos sobre este evento en las variables del objeto que pasamos a esta función, tenemos esta
e . Esta función devuelve 0,
NULL o
false si todos los eventos de la cola se han eliminado, por lo que escribimos la condición
while (SDL_PollEvent (& e)! = NULL) .
Miramos más allá: la primera comprobación que tenemos es hacer clic en la cruz en el marco de la ventana. Si hacemos clic en él, a la variable
tipo del objeto
e se le asigna el valor
SDL_QUIT . Si esto sucede, asignamos
falso a la variable de
ejecución y el ciclo termina.
Luego, escribí una prueba de teclado. Si se presiona el botón, la variable
e.type es igual a
SDL_KEYDOWN . A continuación, verifique los valores clave. La variable
e.key.keysym.sym almacena el valor del botón. Comparamos este valor con el deseado y realizamos ciertas acciones. Vamos a cambiar la coordenada de John. Si se presiona la flecha hacia arriba,
y disminuye en 1, si hacia abajo, aumenta, etc. Creo que entiendes el punto.
Después de procesar los eventos, reasigne
rx y
ry para actualizar las coordenadas del Hombre. A continuación, escribimos la función ya conocida
SDL_FilRect , tiene un papel muy importante. Si no lo hubiéramos escrito, John habría dejado una marca fea en el movimiento, y así, cada cuadro dibujamos un fondo blanco y dibujamos un sprite encima. Después de eso, dibujamos a nuestro héroe con la función
SDL_BlitSurface . Aquí usaremos nuestro rectángulo
r , o más bien sus variables
x e
y , para dibujar no solo en la parte superior izquierda, sino con algunas coordenadas necesarias. A continuación, solo actualice la ventana.
Después del bucle principal, escriba
return quit (); para completar el programa
Eso es todo, esta lección ha terminado. Aquí hay un código de este tipo:
Código #include <SDL2/SDL.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; while (run) { while(SDL_PollEvent(&e) != NULL) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } return quit(); }
Y les digo adiós, ¡adiós a todos!
<< Lección anterior || Próxima lección
>>