Bonjour à tous! Il s'agit de la troisième leçon de SDL 2. Les informations proviennent de
cette source. Je n'aimais pas les tutoriels de gestion des événements de Lasy Foo, donc j'écrirai le mien, mais le matériel peut être trouvé
ici et
ici .
Et nous commençons, bienvenue à la leçon
Les événements
Aujourd'hui, nous enseignerons notre programme pour répondre aux événements avec l'aide de
John .
Commençons donc. connectez SDL 2 et créez 3 variables globales et 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;
Ensuite, nous écrivons 3 fonctions déjà connues de la dernière leçon:
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; }
Charge 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; }
Quitter int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; }
Attention (!), Si vous copiez le code de la leçon précédente, n'oubliez pas de changer le
sourire en
john .
Tout cela doit être dit: j'ai décidé de montrer des erreurs lors de l'initialisation et du chargement de l'image.
Alors continuons. ouvrez
main et appelez les fonctions
Init et
Load .
int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } }
Voyons maintenant comment fonctionne n'importe quelle application. Tout programme que vous exécutez (Google Chrome, Paint, Minecraft) possède une boucle principale qui s'exécute un grand nombre de fois. Cela est nécessaire au dynamisme. Auparavant, nous avons écrit un programme qui a juste montré un sourire pendant 2 secondes, mais pour que le programme apprenne à répondre aux actions de l'utilisateur (ou au moins à afficher l'image à l'infini), il a besoin d'une boucle
While .
Il sera constamment répété et nous pouvons déjà faire ce que nous voulons, par exemple, traiter des événements. Mais avant de commencer le cycle de gland, créons des variables.
bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y;
Nous allons tout analyser maintenant. Créez d'abord une variable d'
exécution de type
booléen . Cette variable est responsable de l'exécution de la boucle: pendant que le programme est en cours d'exécution, il est
vrai , si nous voulons arrêter l'exécution, alors définissez cette variable sur
false . Ensuite, créez un objet
e de classe
SDL_Event . Les propriétés de cet objet contiendront les données de l'événement reçu, plus en détail. Après cela, nous créons un objet
r de la classe
SDL_Rect . Il s'agit du rectangle requis pour dessiner l'objet avec certaines coordonnées dont nous avons besoin. Ensuite, nous créons des variables
x et
y de type
int . Attribuez immédiatement leurs valeurs à zéro. Ce seront les coordonnées de notre personnage. L'élément suivant, nous attribuons les variables
rx et
ry les valeurs
x et
y, respectivement.
rx et
ry sont les coordonnées du rectangle
r .
Il est temps d'ouvrir le cycle 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); }
Analysons ce code. Nous avons deux cycles. Le premier principal est le principal, qui fonctionne en exécutant une variable, comme mentionné précédemment. La deuxième boucle est responsable de la gestion des événements.
La fonction
SDL_PollEvent () ouvre la file d'attente des événements reçus dans une exécution de la boucle principale, supprime le dernier événement et écrit des données sur cet événement dans les variables de l'objet que nous avons passé à cette fonction, nous avons ce
e . Cette fonction renvoie 0,
NULL ou
false si tous les événements de la file d'attente ont été supprimés, nous écrivons donc la condition
while (SDL_PollEvent (& e)! = NULL) .
Nous regardons plus loin: la première vérification que nous avons est de cliquer sur la croix dans le cadre de la fenêtre. Si on clique dessus, alors la variable
type de l'objet
e se voit attribuer la valeur
SDL_QUIT . Si cela se produit, nous attribuons
false à la variable d'
exécution et la boucle se termine.
Ensuite, j'ai écrit un test de frappe au clavier. Si le bouton est enfoncé, la variable
e.type est égale à
SDL_KEYDOWN . Ensuite, vérifiez les valeurs clés. la variable
e.key.keysym.sym stocke la valeur du bouton. Nous comparons cette valeur avec celle souhaitée et effectuons certaines actions. Nous allons changer les coordonnées de John. Si la flèche vers le haut est enfoncée, alors
y diminue de 1, si vers le bas, il augmente, etc. Le point, je pense, vous comprenez.
Après avoir traité les événements, réaffectez
rx et
ry pour mettre à jour les coordonnées de l'Homme. Ensuite, nous écrivons la fonction déjà familière
SDL_FilRect , elle a un rôle très important. Si nous ne l'avions pas écrit, alors John aurait laissé une trace laide lors du déplacement, et ainsi, chaque image nous dessine un fond blanc et dessine un sprite dessus. Après cela, nous
dessinons notre héros avec la fonction
SDL_BlitSurface . Ici, nous utiliserons notre rectangle
r , ou plutôt ses variables
x et
y , pour dessiner non seulement en haut à gauche, mais avec quelques coordonnées nécessaires. Ensuite, mettez simplement à jour la fenêtre.
Après la boucle principale, écrivez
return quit (); pour terminer le programme.
C'est tout, cette leçon est terminée. Voici un tel code:
Code #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(); }
Et je vous dis au revoir, au revoir à tous!
<< Leçon précédente || Prochaine leçon
>>