Leçons SDL 2: Leçon 3 - Événements

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 >>

Source: https://habr.com/ru/post/fr455577/


All Articles