SDL 2.0-Unterrichtszyklus: Lektion 3 - SDL-Erweiterungsbibliotheken

SDL2

Vom Übersetzer:

Ich setze die verlassene Reihe von Übersetzungen von Tutorials von Twinklebear fort, die ursprünglich hier verfügbar waren , mit Genehmigung des Übersetzers der vorherigen Lektionen der InvalidPointer- Reihe. Die ersten beiden Lektionen einer Reihe von Übersetzungen in der Liste sind seine Urheberschaft. Die Übersetzung ist teilweise kostenlos und kann geringfügige Änderungen oder Ergänzungen des Übersetzers enthalten.

Liste der Lektionen:


SDL-Erweiterungsbibliotheken


Bis zu diesem Moment haben wir nur BMP-Bilder verwendet, da dies der einzige Bildtyp ist, der von der SDL 2-Kernbibliothek unterstützt wird, und er ist nicht sehr praktisch. Glücklicherweise gibt es viele SDL-Erweiterungsbibliotheken, die nützliche Funktionen hinzufügen. Mit SDL_image können Sie beispielsweise viele Arten von Bildern laden. SDL_ttf bietet Unterstützung für das Rendern von Text mit TTF-Schriftarten, SDL_net für die Netzwerkunterstützung auf niedriger Ebene und SDL_mixer für die Mehrkanal-Audioausgabe.

Erweiterung installieren


In diesem Tutorial wird nur SDL_image verwendet. Der Installationsprozess für die anderen Erweiterungen ist jedoch nicht anders und stimmt im Allgemeinen fast mit dem für die Installation von SDL2 selbst überein.

  • Windows (MinGW oder Visual Studio): Legen Sie die von der Erweiterungsprojektseite heruntergeladenen Erweiterungsdateien in einem Ordner mit SDL2 ab. Außerdem müssen Sie SDL2_image-, zlib- und andere DLL-Dateien (z. B. libpng) in den Ordner mit Ihrer ausführbaren Datei (oder in C: \ Windows \ system32 - ca. Per. ) Kopieren, damit sie beim Start der Anwendung geladen werden.
  • Linux : Installieren Sie die Erweiterung mit Ihrem internen Paketmanager oder erstellen Sie sie aus dem Quellcode. Wenn Sie Linux haben - wahrscheinlich wissen Sie bereits, wie es geht ©.
  • Mac : Laden Sie .dmg von der offiziellen Website herunter und folgen Sie den Anweisungen in der Readme-Datei.

Um die Erweiterung verwenden zu können, müssen Sie außerdem die Liste der verwendeten Header-Dateien und Plug-In-Bibliotheken aktualisieren, genau wie dies für SDL2 selbst getan wurde.

Bevor Sie mit der Erweiterung arbeiten können, müssen Sie die Datei <SDL2 / SDL_image.h> oder die Datei, die dem Namen der gewünschten Erweiterung entspricht, nach der Header-Datei der SDL selbst mit den .c- und .cpp-Dateien verbinden, die sie verwenden.

SDL_image initialisieren (optional)


Beim ersten Laden des Bildes jedes Typs initialisiert SDL_image automatisch das für diesen Typ erforderliche Subsystem. Dies führt jedoch zu einer leichten Verzögerung. Um dies zu vermeiden, können Sie die erforderlichen Subsysteme mit der Funktion IMG_Init vorinitialisieren. IMG_Init gibt eine Bitmaske mit einer Liste aller Subsysteme zurück, die derzeit erfolgreich initialisiert wurden. Um den Erfolg des Aufrufs zu überprüfen, müssen Sie überprüfen, ob die Bits für alle für die Initialisierung angegebenen Subsysteme gesetzt wurden, z. B. eine Maske auf das bitweise I-Ergebnis anwenden. Für diese Lektion benötigen wir nur ein Subsystem PNG. Es ist wichtig, diesen Vorgang nach SDL_Init auszuführen.

if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) != IMG_INIT_PNG) { logSDLError(std::cout, "IMG_Init"); SDL_Quit(); return 1; } 


Maße einstellen


In dieser Lektion erfahren Sie, wie Sie Bilder mit SDL_image laden, Texturen beim Rendern skalieren und den Hintergrund rationaler als in der vorherigen Lektion mit Kacheln kacheln - ein Zyklus, der auf Fenster- und Kachelgrößen basiert.

Aber zuerst legen wir eine Konstante für die Kachelgröße fest, direkt unter den Konstanten für die Fenstergröße.

 const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; //     const int TILE_SIZE = 40; 

Hochladen von Bildern mit SDL_image


Mit SDL_image können Sie verschiedene Bildtypen laden und diese mit der Funktion IMG_LoadTexture sofort in SDL_Texture konvertieren. Diese Funktion ersetzt fast den gesamten Code der Funktion loadTexture aus der vorherigen Lektion. Rufen Sie jetzt einfach IMG_LoadTexture auf, überprüfen Sie, ob beim Laden Fehler aufgetreten sind, und beenden Sie die Funktion. Da die in SDL_image definierte Funktion IMG_GetError nichts anderes als ein Synonym für SDL_GetError ist, können wir jede dieser Funktionen zum Anzeigen von Fehlermeldungen verwenden.

 /** *       * @param file    * @param ren ,        * @return  ,  nullptr   . */ SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren) { SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str()); if (!texture) { std::cout << IMG_GetError(); //    SDL_GetError() } return texture; } 

Geben Sie die Höhe und Breite für das Rendern an


Wenn Sie beim Rendern der Textur auf dem Renderer eine Rechteckgröße angeben, die sich von der Größe der Textur unterscheidet, skaliert SDL2 diese entsprechend. Wenn jedoch keine Skalierung erforderlich ist, kann es unpraktisch sein, die Anfangsgröße der Textur jedes Mal zu bestimmen. Daher implementieren wir zwei Versionen der renderTexture-Funktion, von denen eine die Textur mit Skalierung und die zweite ohne Skalierung zeichnet.

 /** *  SDL_Texture  SDL_Renderer   x, y,   * @param tex    * @param ren  * @param x  * @param y * @param w     * @param h */ void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y, int w, int h) { SDL_Rect dst; dst.x = x; dst.y = y; dst.w = w; dst.h = h; SDL_RenderCopy(ren, tex, NULL, &dst); } /** *  SDL_Texture  SDL_Renderer   x, y,   * @param tex  * @param ren  * @param x  * @param y */ void renderTexture(SDL_Texture *tex, SDL_Renderer *ren, int x, int y) { int w, h; SDL_QueryTexture(tex, NULL, NULL, &w, &h); renderTexture(tex, ren, x, y, w, h); } 

Laden von Texturen


Da der Hauptzweck dieser Lektion darin besteht, PNG-Bilder herunterzuladen, werden wir einen neuen Satz von Bildern verwenden. Außerdem werden wir die Beibehaltung der PNG-Transparenz beim Rendern eines Vordergrundbilds (mit transparentem Hintergrund) über einem gekachelten Hintergrund demonstrieren.

Wir werden diese Bilder verwenden:

Kachel, um den Hintergrund zu füllen:



Bild des Vordergrunds (wie es darauf geschrieben ist, mit transparentem Hintergrund sowie wieder mit Emoticons, die gegen die Habr-Regeln verstoßen):



Bilder hochladen:

 SDL_Texture *background = loadTexture("background.png", renderer); SDL_Texture *image = loadTexture("image.png", renderer); //  if (!background || !image) { //  ,      cleanup(),   PS   ,     ,  ,    . SDL_DestroyTexture(background); SDL_DestroyTexture(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); IMG_Quit(); SDL_Quit(); return 1; } 

Kacheln Hintergrund


Da die Kacheln merklich kleiner geworden sind, müssen wir mehr als vier Teile einsetzen, um das gesamte Fenster auszufüllen, und es wird ziemlich schwierig sein, die Position für jedes manuell festzulegen. Glücklicherweise können Sie den Computer veranlassen, diese Positionen selbst zu bestimmen.

Wir können herausfinden, wie viele Kacheln in der Breite benötigt werden, indem wir die Breite des Fensters durch die Größe der Kachel und in ähnlicher Weise für die Höhe dividieren.

 //   ,      //  :     ceil(float(SCREEN_WIDTH) / TILE_SIZE),    ,       ,      ; ,        ,     . int xTiles = SCREEN_WIDTH / TILE_SIZE; int yTiles = SCREEN_HEIGHT / TILE_SIZE; //   for (int i = 0; i < xTiles * yTiles; ++i) { int x = i % xTiles; int y = i / xTiles; renderTexture(background, renderer, x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } 

Vordergrundbild zeichnen


Das Vordergrundbild wird nach wie vor in der Mitte des Fensters platziert.

 int iW, iH; SDL_QueryTexture(image, NULL, NULL, &iW, &iH); int x = SCREEN_WIDTH / 2 - iW / 2; int y = SCREEN_HEIGHT / 2 - iH / 2; renderTexture(image, renderer, x, y); 

Es bleibt nur, um das Ergebnis im Fenster anzuzeigen und einige Sekunden zu warten, genau wie in der zweiten Lektion.

 SDL_RenderPresent(renderer); SDL_Delay(2000); 

Reinigung


Die Freigabe von Ressourcen ähnelt der in Lektion 2 (und wurde bereits oben bei der Verarbeitung eines Fehlers beim Laden eines Bildes gesehen), mit Ausnahme des hinzugefügten Aufrufs IMG_Quit.

 SDL_DestroyTexture(background); SDL_DestroyTexture(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); IMG_Quit(); SDL_Quit(); 

Wenn Sie nach erfolgreicher Kompilierung und dem Start alles richtig gemacht haben, sieht das Fenster ungefähr so ​​aus:



Das Ende der dritten Lektion


So ging die nächste Lektion zu Ende. Wir sehen uns in Lektion 4: Behandeln von Ereignissen.

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


All Articles