SDL 2 Lektionen: Lektion 3 - Ereignisse

Hallo allerseits! Dies ist die dritte Lektion in SDL 2. Die Informationen stammen aus dieser Quelle. Die Tutorials zum Thema Lasy Foo haben mir nicht gefallen, deshalb schreibe ich meine eigenen, aber das Material finden Sie hier und hier .

Und wir beginnen, willkommen in der Lektion

Ereignisse


Heute werden wir unser Programm lehren, mit Hilfe von John auf Ereignisse zu reagieren.

Also fangen wir an. Verbinden Sie SDL 2 und erstellen Sie 3 globale Variablen und 2 Konstanten.

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

Als nächstes schreiben wir 3 Funktionen, die bereits aus der letzten Lektion bekannt sind:

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

Laden
 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; } 

Beenden Sie
 int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } 


Achtung (!), Wenn Sie den Code aus der vorherigen Lektion kopieren, vergessen Sie nicht, das Lächeln in John zu ändern.

Alles, was gesagt werden sollte: Ich habe beschlossen, Fehler bei der Initialisierung und beim Laden von Bildern anzuzeigen.

Also, lass uns weitermachen. Öffnen Sie main und rufen Sie die Funktionen Init und Load auf .

 int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } } 

Nun wollen wir sehen, wie jede Anwendung funktioniert. Jedes Programm, das Sie ausführen (Google Chrome, Paint, Minecraft), verfügt über eine Hauptschleife, die sehr oft ausgeführt wird. Dies ist für die Dynamik notwendig. Zuvor haben wir ein Programm geschrieben, das nur 2 Sekunden lang ein Lächeln zeigte. Damit das Programm jedoch lernen kann, wie es auf Benutzeraktionen reagiert (oder das Bild zumindest endlos anzeigt), benötigt es eine While- Schleife.

Es wird ständig wiederholt und darin können wir bereits tun, was wir wollen, zum Beispiel Ereignisse verarbeiten. Bevor Sie jedoch den Eichelzyklus starten, erstellen wir einige Variablen.

  bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; 

Wir werden jetzt alles analysieren. Erstellen Sie zunächst eine Ausführungsvariable vom Typ Boolean . Diese Variable ist für die Ausführung der Schleife verantwortlich: Während das Programm ausgeführt wird, ist es wahr , wenn wir die Ausführung stoppen möchten, setzen Sie diese Variable auf false . Erstellen Sie als Nächstes ein e- Objekt der Klasse SDL_Event . Die Eigenschaften dieses Objekts enthalten die Daten des empfangenen Ereignisses, werden weiter detailliert. Danach erstellen wir ein Objekt r der SDL_Rect- Klasse. Dies ist das Rechteck, das erforderlich ist, um das Objekt mit einigen Koordinaten zu zeichnen, die wir benötigen. Dann erstellen wir die Variablen x und y vom Typ int . Weisen Sie ihre Werte sofort Null zu. Dies werden die Koordinaten unseres Charakters sein. Im nächsten Punkt weisen wir den Variablen rx und ry die Werte x bzw. y zu . rx und ry sind die Koordinaten des Rechtecks r .

Es ist Zeit, den Hauptzyklus zu öffnen.

  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); } 

Lassen Sie uns diesen Code analysieren. Wir haben zwei Zyklen. Die erste Hauptversion ist die Hauptversion, bei der, wie bereits erwähnt, eine Variable ausgeführt wird. Die zweite Schleife ist für die Behandlung von Ereignissen verantwortlich.

Die Funktion SDL_PollEvent () öffnet die Warteschlange der Ereignisse, die in einer Ausführung der Hauptschleife empfangen wurden, löscht das letzte Ereignis und schreibt Daten über dieses Ereignis in die Variablen des Objekts, das wir an diese Funktion übergeben haben. Wir haben dieses e . Diese Funktion gibt 0, NULL oder false zurück, wenn alle Ereignisse aus der Warteschlange gelöscht wurden. Daher schreiben wir die while- Bedingung (SDL_PollEvent (& e)! = NULL) .

Wir schauen weiter: Die erste Überprüfung besteht darin, auf das Kreuz im Fensterrahmen zu klicken. Wenn wir darauf klicken, wird der Typvariablen des Objekts e der Wert SDL_QUIT zugewiesen. In diesem Fall weisen wir der Laufvariablen false zu und die Schleife endet.

Als nächstes schrieb ich einen Tastatur-Tastendruck-Test. Wenn die Taste gedrückt wird, lautet die Variable e.type SDL_KEYDOWN . Überprüfen Sie als Nächstes die Schlüsselwerte. Die Variable e.key.keysym.sym speichert den Wert der Schaltfläche. Wir vergleichen diesen Wert mit dem gewünschten und führen bestimmte Aktionen aus. Wir werden die Koordinate von John ändern. Wenn der Aufwärtspfeil gedrückt wird, verringert sich y um 1, wenn es nach unten geht, nimmt es zu usw. Der Punkt, denke ich, verstehen Sie.

Weisen Sie nach der Verarbeitung der Ereignisse rx und ry neu zu, um die Koordinaten des Mannes zu aktualisieren. Als nächstes schreiben wir die bereits bekannte Funktion SDL_FilRect , sie spielt eine sehr große Rolle. Wenn wir es nicht geschrieben hätten, hätte John eine hässliche Spur in der Bewegung hinterlassen, und so zeichnen wir in jedem Frame einen weißen Hintergrund und ein Sprite darüber. Danach zeichnen wir unseren Helden mit der Funktion SDL_BlitSurface . Hier werden wir unser Rechteck r oder vielmehr seine Variablen x und y verwenden , um nicht nur oben links, sondern mit einigen notwendigen Koordinaten zu zeichnen. Als nächstes aktualisieren Sie einfach das Fenster.

Schreiben Sie nach der Hauptschleife return quit (); um das Programm zu vervollständigen.

Das ist alles, diese Lektion ist vorbei. Hier ist ein solcher 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(); } 


Und ich verabschiede mich von dir, tschüss alle!

<< Vorherige Lektion || Nächste Lektion >>

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


All Articles