Satyria

SDL-Programmierung / Zeichen

void gfxPrimitivesSetFont (const void *fontdata, Uint32 cw, Uint32 ch)
void gfxPrimitivesSetFontRotation (Uint32 rotation)
int characterColor (SDL_Renderer *renderer, Sint16 x, Sint16 y, char c, Uint32 color)
int characterRGBA (SDL_Renderer *renderer, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
int stringColor (SDL_Renderer *renderer, Sint16 x, Sint16 y, const char *s, Uint32 color)
int stringRGBA (SDL_Renderer *renderer, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
rendererRenderer des Fensters
xx-Positionen
yy-Position
cZeichen (char)
sZeichenkette (string)
colorDie Farbe des Pixels (Format 0xRRGGBBAA)
rRotanteil
gGrünanteil
bBlauanteil
aalphablendig (Deckung zum Hintergrund)
fontdataListe des Zeichensatzes
cwBreite eines Zeichens
chHöhe eines Zeichens
rotationRotation ( 0 = keine Rotation. 1 = 90°. 2 = 180°. 3 = 270°)

Beispiel

Sourcen: zeichen.c ; Font

<Bezier| GFX Übersicht

SDL-Programmierung / Bezier

int bezierColor (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, int s, Uint32 color)
int bezierRGBA (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
rendererRenderer des Fensters
vxFeld mit x-Positionen
vyFeld mit y-Position
nAnzahl Ecken
s Anzahl der Schritte für die Interpolation
colorDie Farbe des Pixels (Format 0xRRGGBBAA)
rRotanteil
gGrünanteil
bBlauanteil
aalphablendig (Deckung zum Hintergrund)

Beispiel

Sourcen: bezier.c

<Mehrecke | GFX Übersicht | Zeichen >

SDL-Programmierung / Das erste Spiel?

Wir haben inzwischen gesehen, wie Sprites angezeigt werden und wie auf events reagiert werden kann. In dem Vorhergehenden Kurs konnten wir das Sprite mit der Tastatur ansprechen, aber warum nicht auch mit der Maus. Also fragen wir auch das Event der Maus ab und holen uns die Position der Maus. An dieser Position, setzen wir das Sprite.

Wenn nun die Maus bewegt wird, rufen wir auch die Funktion „Mausbewegt“ auf.

In dieser Funktion setzen wir einfach die Position des Sprites gleich der Maus.

Source 10.c; blume.png; sprite1.png

Das war jetzt keine große Kunst… Verändern wir doch etwas diese Zuordnung und mache es etwas „interaktiv“.

Jetzt kommt noch eine Eigenschaft von SDL, es ist ziemlich schnell. Wir bauen noch eine SDL-Funktion in das main ein

Hier habe ich noch ein Delay eingebaut und damit wird das Sprite etwas langsamer.

Source 11.c; blume.png; sprite1.png

Wie ein kleiner Hund läuft unser Sprite der Maus hinterher…

Da wir nun bereits die Kontrolle der Maus mit eingebaut haben, können wir auch dies dazu benutzen eine Art Reaktion auszulösen. Wenn ich hier das Bild anschaue, warum lasse ich nicht eine Biene hier rumfliegen. Und wenn die Biene die Maus erwischt, dann „Aua“.

Das einzige, was wir verändern müssen, ist die Mausbewegt-Funktion.

In einer If-Anweisung vergleiche ich einfach die Positionen der Biene und der Maus. Wenn diese zu ähnlich sind, dann wird einfach herausgegeben, dass die Maus von der Biene gestochen wurde.

Source 12.c; blume.png; sprite2.png

Sprites

Was sind Sprites. Dies sind Figuren, Gegenstände, die in einem Spiel sich in der Regel bewegen lassen. Diese können Animationen enthalten. Man kann Sprites noch in aktive und passive Sprites unterscheiden. Passive Sprites haben außer der Darstellung auf einem Bildschirm keine Funktion. Aktive Sprites können auf Kollisionen geprüft werden und interagieren mit der Umgebung, was in einem Spiel sehr sinnvoll ist…

Eigentlich sind Sprites kleinere Bilder, da wir mit diesen allerdings interagieren wollen, erstellen wir eine Struktur, die wir später auch für alle Sprites verwenden können

Und legen zu unserem ersten Sprite, welches wir Gesicht nennen, global an.

Zunächst müssen wir das Bild des Sprites laden, dazu schreiben wir folgende Funktion

Und nun brauchen wir auch eine Funktion, die das Sprite zeichnet.

Vom Grunde her ist es nichts anderes, als ein Bild zu Zeichnen. Allerdings wurde dem Bild keine „Position“ angegeben, außer das es an Pos 0,0 ist. Was dann ganz oben ist. Der Trick kommt später, wenn wir festlegen, was zuerst gezeichnet wird, und dies wird in unserem Hauptprogramm festgelegt.

Zunächst initialisieren wir das Programm, laden das Bild, laden den Sprite und geben dem Sprite eine Position. In der While Schleife legen wir nun Fest, das zunächst das Bild gezeichnet wird. Anschließen wird der Sprite gezeichnet und dann alles angezeigt.

Schon jetzt sind wir fertig. Unser Programm zeigt ein Sprite an.

Source 8.c; blume.png; sprite1.png

Bewegung im Spiel

Hmm… Soweit so gut… Aber das war ja noch nicht der Hammer. Deswegen lassen wir diese Sprite noch bewegen. Dies ist gar nicht so schwer.

Wie wir bereits wissen, können wir über die Events auf die Eingabe der Tastatur reagieren. Zuvor haben wir sie nur angezeigt, nun reagieren wir darauf. Sobald eine Taste gedrückt wurde, rufen wir eine neue Funktion auf, die wir TasteGedrueckt nennen.

Dieser Funktion wird die Eventstruktur übermittel. In dieser steht über den keysym.scancode, welche Taste gedrückt wurde. Diese fragen wir ab und wenn die Tasten rechts, links, runter oder rauf gedrückt wurden, addieren oder subtrahieren wir jeweils 1 mit der Variable „Gesicht.x“ oder „Gesicht.y“. Damit bekommt das Sprite jeweils eine neue Position.

Damit allerdings diese Funktion benutzt werden kann, muss auch noch die Eingabe-Funktion angepasst werden.

Also wenn eine Taste gedrückt wurde, rufe die Funktion TasteGedrueckt auf.

Das war es schon. Probiere es aus…

Source 9.c; blume.png; sprite1.png

<< Übersicht | < Auf Eingaben reagieren | Texturen >

Die GNU Compiler Collection Version 7.5 wurde veröffentlicht.

GCC 7.5 ist eine Fehlerkorrekturversion aus dem GCC 7-Zweig, die wichtige Korrekturen für Regressionen und schwerwiegende Fehler in GCC 7.4 enthält. Seit der vorherigen Version wurden mehr als 215 Fehler behoben.

Dies ist auch die letzte Version aus dem GCC 7-Zweig, die ab sofort keine weiteren Korrekturen mehr erhalten wird. GCC wird weiterhin in den Zweigstellen GCC 8 und GCC 9 sowie im Entwicklungsstamm verwaltet.

Diese Version ist auf den folgenden FTP-Servern verfügbar:

http://www.gnu.org/order/ftp.html

SDL-Programmierung / Auf Eingaben reagieren

Im ersten Teil (Das erste Programm) wurde bereits auf die Events eingegangen. Hier beschreibe ich mal, was es sich dabei auf sich hat.

Unsere Funktion „Eingabe“, die wir bisher verwendet hat folgendes Aussehen:

Dieser Code ist relativ einfach gestrickt. Durch das while, wird solange gewartet bis es ein Event gibt. Durch die Abfrage switch wird dann verteilt. Hier wird nur auf das SDL_QUIT reagiert, was das Schließen des Fensters bedeutet. Da im Hauptprogramm der Rückgabewert geprüft wird, wird hier für das Beenden des Programms eine 1 zurückgegeben.

Diese Schleife wird in den meisten Programmen als Hauptschleife bezeichnet und eigentlich der Kern jeder Anwendung. Mit SDL_PollEvent wird die „event“-Struktur gefüllt, die wir dann Abfragen können. In dieser Struktur werden alle Ereignisse abgelegt, die hier geschehen sind. Dies können Tastatur eingaben, Joystick, die Maus oder auch der Touchscreen, Touchpad sein, die hier Ereignisse übergeben. Aber auch Interaktionen mit dem Fenster (z.B. das Schließsymbol).

Diese gesamten Ereignisse, werden in SDL in eine Warteschlange abgelegt. Die über „SDL_PollEvent“ abgefragt werden können. Wenn nichts mehr in der Warteschlange ist, wird eine NULL zurückgegeben.

Hier in unserer Grundstruktur habe ich bereits eine Abfrage eingebaut.
SDL_QUIT
Damit wird dem Programm mitgeteilt, dass der Benutzer das Programm schließen möchte. Wir setzen hier einfach eine eins nach „done“ welches wir dem Hauptprogramm zurückgeben.

Da es verschiedenen Arten gibt, wie hier interagiert werden kann, muss SDL auch verschieden reagieren. Z.B. bei einen Tastendruck, sollte man dann wissen, welche Taste den gedrückt wurde, oder wenn sich die Maus bewegt, da würde ich dann gerne wissen, wo sich die Maus befindet. Dies sind verschiedene Arten von Daten, die hier ausgewertet werden müssen. Zu jedem Event, wird dadurch zu dem eigentlich Zweck, eine weitere Struktur initialisiert, die auch entsprechend ausgewertet werden muss. Ich zeige hier hier nun ein paar Beispiele. Eine gesamte Auflistung findet ihr bei https://wiki.libsdl.org/SDL_EventType .

Auf Tastatureingaben eingehen

Wenn eine Taste gedrückt oder losgelassen wird, wird jeweils ein Event ausgelöst. Diese Events haben die Bezeichnung SDL_KEYDOWN und
SDL_KEYUP
Beide erzeugen die Struktur „key“.

Uint32TypeSDL_KEYDOWN oder SDL_KEYUP
Uint32 ZeitstempelZeitstempel, als es geschah
Uint32 Window IDFenster, auf dem der Fokus war
Uint8StatusDer Zustand der Taste; SDL_PRESSED oder SDL_RELEASED
Uint8WiederholungWenn es einen Wiederholtaste ist, wird hier keine NULL angezeigt
SDL_KeysymkeysymDiese Struktur zeigt welche Taste gedrückt oder losgelassen wurde.

Um es auch zu veranschaulichen, hier nun ein Beispiel.

Sourcecode: 6.c

Diesen Code kann man nun auch dazu benutzen, um die Tasten zu probieren, die man für die Anwendung verwenden will.

Das gleiche machen wir noch mit der Maus:

Sourcecode: 7.c

<< Übersicht | < Zeichnen | Sprites >

SDL Links

MSYS2 installieren (GCC)

Als erstes ist es wichtig, in welcher Umgebung das MSYS2 installiert wird. Für Windows 10 mit 64-Bit werden die Pakete für „x86_64“ benötigt. Sollte man allerdings eine 32-Bit Umgebung haben, sollte man auch die entsprechenden „i686“ Pakete verwenden. Ich beschreibe hier mal die 64-Bit Installation:

Download: http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20190524.exe

Diese Datei wird ausgeführt und wir verwenden zur einfachen Beschreibung die Standard Vorgaben.

Sobald MSYS2 installiert ist müssen wir es aktualisieren:

pacman -Syu

Da in der Regel auch das Programm „pacman“ aktualisiert wurde, muss das MSYS2 „böse“ beendet werden. Gestartet kann es dann wieder mit „Windowstaste“ und über die Tastatureingabe von „msys2“ findet Windows das Programm wieder. Sobald die Konsole wieder gestartet ist wird das MSYS2 mit folgenden Befehl weiter aktualisiert:

pacman -Su

Damit man nun programmieren kann, werden nun auch alle Development Dateien geladen:

pacman -S msys2-devel

SDL2 mit MSYS2 zur Programmierung installieren

Als erstes ist es wichtig, in welcher Umgebung das MSYS2 installiert wird. Für Windows 10 mit 64-Bit werden die Pakete für „x86_64“ benötigt. Sollte man allerdings eine 32-Bit Umgebung haben, sollte man auch die entsprechenden „i686“ Pakete verwenden. Leider stimmt diese Aussage nicht. Ich konnte bisher nicht herausbekommen, welche Version die richtige ist. Ich habe zwei Rechner, jeweils mit Windows 10 und 64Bit. Auf dem einen geht nur die 32-Bit-Version, auf dem anderen die 64-Bit-Version. Man muss es leider einfach versuchen, welche die richtige ist. Sollte hier jemand mehr wissen, kann er mich gerne per Mail anschreiben: SDL@satyria.de.

Ich beschreibe hier mal die 64-Bit Installation, sollte die 32-Bit Version installiert werden, so müsst ihr einfach das „x85_64“ durch „i686“ ersetzen:

Download: http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20190524.exe

Downloadseite: https://www.msys2.org/

Diese Datei wird ausgeführt und wir verwenden zur einfachen Beschreibung die Standard Vorgaben.

Sobald MSYS2 installiert ist müssen wir es aktualisieren:

pacman -Syu

Da in der Regel auch das Programm „pacman“ aktualisiert wurde, muss das MSYS2 „böse“ beendet werden. Gestartet kann es dann wieder mit „Windowstaste“ und über die Tastatureingabe von „msys2“ findet Windows das Programm wieder. Sobald die Konsole wieder gestartet ist wird das MSYS2 mit folgenden Befehl weiter aktualisiert:

pacman -Su

Damit man nun programmieren kann, werden nun auch alle Development Dateien geladen:

pacman -S msys2-devel

Dieser Befehl installiert nun auch gcc, welches wir für die Programmierung benötigen. Bereits jetzt können wir in „C“ programmieren. Da wir allerdings nun SDL2 verwenden wollen, müssen wir noch ein paar Sachen dazu installieren. Damit wir uns zumindest eine Zeile sparen, installieren wir gleich SDL2_image. Durch die Abhängigkeiten dieses Pakets wird dann auch gleich das SDL2 selbst installiert:

pacman -S mingw-w64-x86_64-SDL2_image

Weiter empfehlende Pakete sind dann:

pacman -S mingw-w64-x86_64-SDL2_gfx
pacman -S mingw-w64-x86_64-SDL2_mixer
pacman -S mingw-w64-x86_64-SDL2_net
pacman -S mingw-w64-x86_64-SDL2_ttf
pacman -S mingw-w64-x86_64-smpeg2

Als Test benutzen wir das erste Programm im Kurs: 1.c und kopieren es nach C:\msys64\home\"name"\ für diese installation. Bei 32-Bit nach C:\msys32\home\"name"\ . Für „name“ ist das Verzeichnis, welches das MSYS2 für das Benutzer-Home erstellt hat. Kompiliert wird es bei 64-Bit dann mit folgenden Befehl:

gcc -o 1.exe 1.c -Ic:/msys64/mingw64/include -Lc:/msys64/mingw64/lib -lmsys-2.0 -lSDL2main -lSDL2 -mwindows

Bei 32-Bit dann:

gcc -o 1.exe 1.c -Ic:/msys32/mingw32/include -Lc:/msys32/mingw32/lib -lmsys-2.0 -lSDL2main -lSDL2 -mwindows

Gestartet wird das Programm mit:

./1.exe

SDL-Programmierung / Mehrecke

int polygonColor (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint32 color)
int polygonRGBA (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
int aapolygonColor (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint32 color)
int aapolygonRGBA (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
int filledPolygonColor (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint32 color)
int filledPolygonRGBA (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
int texturedPolygon (SDL_Renderer *renderer, const Sint16 *vx, const Sint16 *vy, int n, SDL_Surface *texture, int texture_dx, int texture_dy)
rendererRenderer des Fensters
vxFeld mit x-Positionen
vyFeld mit y-Position
nAnzahl Ecken
colorDie Farbe des Pixels (Format 0xRRGGBBAA)
rRotanteil
gGrünanteil
bBlauanteil
aalphablendig (Deckung zum Hintergrund)
textureSDL_Surface mit einer Texture
dx, dyDelta x und Delta y der Texture

Beispiel:

Sourcen: poly.c

<Dreiecke | GFX Übersicht | Beziers >

Weiterblättern »