Spieleprogrammierung mit der SDL
Transcrição
Spieleprogrammierung mit der SDL
Spieleprogrammierung mit der SDL Bernhard Trummer Linux User Group Graz für die Linuxtage04 [email protected] 6. Mai 2004 – Typeset by FoilTEX – Bernhard Trummer 6. Mai 2004 Übersicht Simple DirectMedia Layer (SDL): Der erste Teil dieser Präsentation widmet sich der SDL selbst. Hier werden die wichtigsten Funktionen vorgestellt und anhand von kleinen Demoprogrammen veranschaulicht. Zusatzbibliotheken: Basierend auf der SDL existieren inzwischen viele Zusatzbibliotheken, von denen einige vorgestellt werden. Design einer Game-Engine: Zuletzt wird auf einige Grundlagen eingegangen, die für das Design einer Game-Engine (dem Kern eines Spiels) notwendig sind. – Typeset by FoilTEX – 1 Bernhard Trummer 6. Mai 2004 Simple DirectMedia Layer (SDL) • SDL bietet eine einfache Schnittstelle für den Zugriff auf einen 2D Framebuffer, OpenGL und Soundkarten an. Ferner bietet SDL die Möglichkeit, Keyboard-, Maus- und Joystick-Events abzufragen. • Zu den unterstützten Plattformen gehören: Linux, Windows, BeOS, MacOS, MacOS X, FreeBSD, OpenBSD, BSD/OS, Solaris, IRIX, QNX. • Inoffiziell wird auch Windows CE, AmigaOS, Dreamcast, Atari, NetBSD, AiX, OSF/Tru64, RISC OS und SymbianOS unterstützt. – Typeset by FoilTEX – 2 Bernhard Trummer 6. Mai 2004 Initialisierung • Um die SDL in einem Programm verwenden zu können, muß die Funktion SDL Init(Uint32 flags) aufgerufen werden. • Über den Parameter flags kann angegeben werden, welche Subsysteme der SDL initialisiert werden sollen. • Mit den Funktionen SDL InitSubSystem() und SDL QuitSubSystem() können einzelne Subsysteme auch während der Laufzeit hoch- und runtergefahren werden. • Beim Beenden des Programms muß die Funktion SDL Quit() aufgerufen werden, um die SDL wieder herunterzufahren. – Typeset by FoilTEX – 3 Bernhard Trummer 6. Mai 2004 SDL Subsysteme Der Parameter flags für SDL Init(), SDL InitSubSystem() und SDL QuitSubSystem() wird als bitweise Oder-Verknüpfung von vorgegebenen Defines gebildet. Die wichtigsten davon sind: SDL INIT VIDEO: Initialisiert das Video Subsystem. SDL INIT AUDIO: Initialisiert das Audio Subsystem. SDL INIT NOPARACHUTE: Ohne diesen Parameter werden Segmentation Faults von der SDL abgefangen, was das Schreiben eines Core Dumps unterbindet. – Typeset by FoilTEX – 4 Bernhard Trummer 6. Mai 2004 Fehlerbehandlung char *SDL_GetError(); Viele SDL-Funktionen geben im Fehlerfall -1 bzw. NULL as Returnwert zurück. Liegt so ein Fehlerfall vor, kann mit der Funktion SDL GetError() ein NULL-terminierter char* String abgerufen werden, der eine detaillierte Fehlerbeschreibung enthält. – Typeset by FoilTEX – 5 Bernhard Trummer 6. Mai 2004 Das Event Subsystem Beim Aufruf von SDL Init() wird immer das Event Subsystem initialisiert, und zwar unabhängig davon, welche flags gesetzt worden sind. Das Event Subsystem dient in erster Linie dazu, Ereignisse von verschiedenen Eingabegeräten (Tastatur, Maus, Joystick) zu sammeln und über eine Event Queue der Applikation zur Verfügung zu stellen. – Typeset by FoilTEX – 6 Bernhard Trummer 6. Mai 2004 Abfragen von Events int SDL_PollEvent(SDL_Event *event); int SDL_WaitEvent(SDL_Event *event); Die wichtigsten beiden Funktionen, um SDL Events abzurufen, sind SDL PollEvent() und SDL WaitEvent(). Beiden Funktionen muß ein Pointer auf eine SDL Event Struktur übergeben werden, in der dann ein ev. vorhandenes Event gespeichert wird. Der Hauptunterschied zwischen diesen beiden Funktionen ist, daß ein Aufruf von SDL WaitEvent() so lange bockiert, bis ein Event in der Queue verfügbar ist. Im Gegensatz dazu kehrt SDL PollEvent() sofort zurück, wobei ein Returnwert von 1 bedeutet, daß ein Event aus der Queue entfernt und in event gespeichert worden ist. – Typeset by FoilTEX – 7 Bernhard Trummer 6. Mai 2004 Aufbau von SDL Event typedef union { Uint8 type; SDL_ActiveEvent active; SDL_KeyboardEvent key; ... } SDL_Event; Das SDL Event ist eine union, bestehend aus einem Typ und einer Reihe von speziellen Event-Strukturen. Die Definitionen aller dieser EventStrukturen müssen ebenfalls mit einem Uint8 type beginnen, damit über das type-Feld von SDL Event abgefragt werden kann, um welches Event es sich handelt. – Typeset by FoilTEX – 8 Bernhard Trummer 6. Mai 2004 Keyboard Events Als Beispiel sei hier das SDL KeyboardEvent angeführt: typedef struct { Uint8 type; /* SDL_KEYDOWN or SDL_KEYUP */ Uint8 which; /* The keyboard device index */ Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ SDL_keysym keysym; } SDL_KeyboardEvent; Abgesehen vom notwendigen type-Feld enthält die Struktur alle notwendigen Informationen, um feststellen zu können, welche Taste wie betätigt worden ist. – Typeset by FoilTEX – 9 Bernhard Trummer 6. Mai 2004 Das Video Subsystem Das Video Subsystem wird initialisiert, in dem man SDL Init() mit dem Parameter SDL INIT VIDEO aufruft. Bei der Benutzung der SDLFunktionen des Video Subsystems wird man immer wieder mit folgenden Datenstrukturen zu tun haben: SDL Rect: Entspricht einem Rechteck, welches über den linken oberen Eckpunkt, der Breite und der Höhe (x, y, w, h) definiert ist. SDL Surface: Entspricht einem Zeichenbereich bzw. einer Bitmap-Grafik. Die Struktur enthält abgesehen von den Pixeldaten u.a. auch die Dimensionen (Breite, Höhe, Farbtiefe). – Typeset by FoilTEX – 10 Bernhard Trummer 6. Mai 2004 SDL BlitSurface() int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); Eine der wichtigsten Operationen im Video Subsystem ist das Zeichnen (Blitten) einer SDL Surface auf eine andere SDL Surface. Dies kann mit der Funktion SDL BlitSurface() gemacht werden, wobei zusätzlich angegeben werden kann, welcher Bereich der Quell-Surface auf welche Position der Ziel-Surface gezeichnet werden soll. In den meisten Fällen soll die gesamte Quell-Surface auf die Ziel-Surface gezeichnet werden. Dies wird erreicht, in dem der Parameter srcrect auf NULL gesetzt wird. – Typeset by FoilTEX – 11 Bernhard Trummer 6. Mai 2004 SDL SetVideoMode() SDL_Surface *SDL_SetVideoMode( int width, int height, int bpp, Uint32 flags); Mit dieser Funktion wird ein Framebuffer angelegt und als Fenster dargestellt. Interessant hierbei ist die Tatsache, daß dieser Framebuffer als SDL Surface abgebildet wird und auch als solche verwendbar ist. width, height: Die Dimensionen (Breite und Höhe) des Fensters. bpp: Die Farbtiefe (8, 16 oder 32 bit). flags: Parameter für das Anlegen des Hauptfensters. – Typeset by FoilTEX – 12 Bernhard Trummer 6. Mai 2004 Flags für SDL SetVideoMode() SDL SWSURFACE: Erzeuge die Surface im RAM des Systems. SDL HWSURFACE: Erzeuge die Surface im RAM der Grafikkarte. SDL FULLSCREEN: Stelle die Surface im Vollbildmodus dar. SDL DOUBLEBUF: Aktiviere Double-Buffering. – Typeset by FoilTEX – 13 Bernhard Trummer 6. Mai 2004 SDL LoadBMP() SDL_Surface *SDL_LoadBMP(const char *file); Mit dieser Funktion kann eine beliebige Bitmap-Grafik eingelesen und als SDL Surface weiterverwendet werden. Die Farbtiefe bzw. Palette der Bitmap-Grafik spielt keine Rolle. Sie darf nur nicht im RLE-Format gespeichert sein, da SDL LoadBMP() dafür keinen Support implementiert hat. – Typeset by FoilTEX – 14 Bernhard Trummer 6. Mai 2004 SDL CreateRGBSurface() SDL_Surface *SDL_CreateRGBSurface( Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); Mit Hilfe von dieser Funktion kann eine SDL Surface mit der angegebenen Höhe, Breite und Farbtiefe erzeugt werden. Über den Parameter flags kann auch hier mit SDL SWSURFACE bzw. SDL HWSURFACE angegeben werden, ob die Surface in das RAM des Systems oder der Grafikkarte gelegt werden soll. Zusätzlich kann mit den beiden Flags SDL SRCCOLORKEY und SDL SRCALPHA eine Hardware-Beschleunigung für Transparenzeffekte aktiviert werden. – Typeset by FoilTEX – 15 Bernhard Trummer 6. Mai 2004 Color Keying int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key); Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b); Mit der Funktion SDL SetColorKey() kann für eine Surface ein bestimmter Farbwert (key) als transparent definiert werden. Für den Parameter flag muß dazu der Wert SDL SRCCOLORKEY verwendet werden. Mit dem Wert 0 kann ein zuvor eingestellter Color Key wieder deaktiviert werden. Da man ausgehend von einem RGB-Wert nicht direkt auf den richtigen Wert für key schließen kann, muß die Funktion SDL MapRGB() verwendet werden, wobei surface->format als Parameter fmt übergeben wird. – Typeset by FoilTEX – 16 Bernhard Trummer 6. Mai 2004 Alpha Blending int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); Mit der Funktion SDL SetAlpha() und dem flag SDL SRCALPHA kann der Alpha-Wert alpha für eine Surface gesetzt werden. Dieser Wert kann dabei zwischen SDL ALPHA TRANSPARENT (0) und SDL ALPHA OPAQUE (255) liegen. – Typeset by FoilTEX – 17 Bernhard Trummer 6. Mai 2004 RLE-beschleunigtes Blitting Bei SDL SetColorKey() und SDL SetAlpha() kann beim Parameter flag zusätzlich der Wert SDL RLEACCEL oder-verknüpft werden, um BlitOperationen zu beschleunigen. Damit diese Beschleunigung allerdings etwas bringt, muß die Surface so aufgebaut sein, daß möglichst viele benachbarte Pixel den gleichen Farbwert haben (bzw. transparent sind). Für den Fall, daß sich die Pixeldaten der Surface ändern, sollte man jedoch auf die RLE-Beschleunigung verzichten, da sonst bei jeder Änderung eine interne Neuberechnung der RLE-Codierung durchgeführt wird. – Typeset by FoilTEX – 18 Bernhard Trummer 6. Mai 2004 SDL FreeSurface() void SDL_FreeSurface(SDL_Surface *surface); Wird eine SDL Surface nicht mehr benötigt, muß sie mit dieser Funktion wieder freigegeben werden. Die einzige Ausnahme stellt die Display-Surface dar, die mit SDL SetVideoMode() erzeugt wurde. Diese Surface wird nämlich in der Funktion SDL Quit() freigegeben. – Typeset by FoilTEX – 19 Bernhard Trummer 6. Mai 2004 Update der Display-Surface Änderungen der Display-Surface werden nicht automatisch in das dargestellte Fenster übernommen. Dies muß durch den Aufruf von einer der Update-Funktionen händisch gemacht werden: • SDL UpdateRect() • SDL UpdateRects() • SDL Flip() (nur für Double-Buffering) – Typeset by FoilTEX – 20 Bernhard Trummer 6. Mai 2004 SDL UpdateRect() void SDL_UpdateRect( SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h); screen: Der Pointer auf die Display-Surface. Will man diesen Pointer nicht extra speichern, kann auch der Rückgabewert der Funktion SDL GetVideoSurface() verwendet werden. x, y, w, h: Die linke obere Ecke, die Breite und die Höhe des rechteckigen Bereichs, der dargestellt bzw. aktualisiert werden soll. Sind alle vier Parameter 0, so wird das ganze Fenster aktualisiert. – Typeset by FoilTEX – 21 Bernhard Trummer 6. Mai 2004 SDL UpdateRects() void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects); Alternativ kann diese Funktion verwendet werden, mit der es auch möglich ist, eine Liste von zu aktualisierenden Rechtecken anzugegeben. Allerdings muß man hier selbst dafür sorgen, daß alle Rechtecke innerhalb des Darstellungsbereichs liegen. screen: Der Pointer auf die Display-Surface, bzw. SDL GetVideoSurface(). numrects: Die Anzahl der Rechtecke im rects Array. rects: Ein Pointer auf ein Array der zu aktualisierenden Rechtecke. – Typeset by FoilTEX – 22 Bernhard Trummer 6. Mai 2004 SDL Flip() int SDL_Flip(SDL_Surface *screen); Wurde die Display-Surface mit dem Flag SDL DOUBLEBUF initialisiert, kann mit der Funktion SDL Flip() ein Umschalten zwischen den beiden Buffern ausgelöst werden. – Typeset by FoilTEX – 23 Bernhard Trummer 6. Mai 2004 Beispielprogramme (Teil 1) 01-window.cpp: Stellt ein leeres Fenster dar und wartet, bis die ESC Taste gedrückt worden ist. 02-blit.cpp: Zeichnet ein Raumschiff in das Fenster wobei auch Color Keying und Alpha Blending demonstriert wird. 03-flip.cpp: Zeigt die Unbrauchbarkeit“ vom SDL Double Buffering, weil ” nicht das passiert, was man sich eigentlich erwartet. 04-control1.cpp: Eine primitive Hauptschleife, um ein Raumschiff mit den Cursortasten zu bewegen. – Typeset by FoilTEX – 24 Bernhard Trummer 6. Mai 2004 Zusatzbibliotheken In diesem Abschnitt sollen einige der vielen verfügbaren Zusatzbibliotheken vorgestellt werden, welche auf der SDL basieren bzw. zusätzliche Funktionalität anbieten. – Typeset by FoilTEX – 25 Bernhard Trummer 6. Mai 2004 libSDL image Diese Bibliothek ermöglicht es, Grafik-Dateien in einem beliebigen Format (GIF, JPG, PNG, etc.) in eine SDL Surface zu laden. Die wohl wichtigste Funktion dieser Bibliothek ist: SDL_Surface *IMG_Load(const char *file); – Typeset by FoilTEX – 26 Bernhard Trummer 6. Mai 2004 libSDL gfx Diese Bibliothek enthält die folgenden Komponenten: • Zeichnen von primitiven geometrischen Objekten wie Linien, Polygone, Kreise und Ellipsen. • Eine Zoom-Funktion, um Surfaces in x- und y-Richtung zu skalieren. • Eine Rotozoomer-Funktion, um Surfaces zu rotieren und skalieren. • Funktionen zur Framerate-Control. – Typeset by FoilTEX – 27 Bernhard Trummer 6. Mai 2004 rotozoomSurface() 1/2 SDL_Surface *rotozoomSurface( SDL_Surface *src, double angle, double zoom, int smooth); src: Die zu skalierende und/oder rotierende SDL Surface. angle: Der Rotationswinkel in Grad, gegen den Uhrzeigersinn. zoom: Der Skalierungsfaktor (1.0 entspricht der Originalgröße). smooth: Gibt an, ob beim Rotieren/Skalieren ein Anti-Aliasing gemacht werden soll (SMOOTHING OFF oder SMOOTHING ON). – Typeset by FoilTEX – 28 Bernhard Trummer 6. Mai 2004 rotozoomSurface() 2/2 Abbildung 1: original – rotiert – beschnitten Das Problem beim Verwenden der Rotozoomer-Funktion ist, daß sich die Breite und Höhe der resultierenden SDL Surface verändert. Für eine saubere Rotation um den Mittelpunkt der Surface müßte man daher diese Größenveränderungen berücksichtigen, oder man schneidet aus der Mitte nachträglich einen Bereich in der ursprünglichen Größe aus. – Typeset by FoilTEX – 29 Bernhard Trummer 6. Mai 2004 Weitere Zusatzbibliotheken libSDL mixer: Mit dieser Bibliothek können Musik und Soundeffekte in unterschiedlichen Formaten geladen und abgespielt werden. libSDL net: Eine Wrapper-Library für die Socket-API der libc. libSDL ttf: Mit dieser Bibliothek können Texte unter Verwendung von TrueType Fonts gezeichnet werden. libparagui: Eine GUI Widget-Bibliothek, die vollständig auf der SDL basiert. – Typeset by FoilTEX – 30 Bernhard Trummer 6. Mai 2004 Design einer Game-Engine Wie auch im Fernsehen und im Kino, werden bei Computerspielen Animationen bzw. Bewegungsabläufe als Folge von Einzelbildern (Frames) dargestellt. Als grundlegendes Framework für eine Game-Engine macht es daher Sinn, von einer Hauptschleife auszugehen, in der für jeden Durchlauf ein Frame berechnet und dargestellt wird. – Typeset by FoilTEX – 31 Bernhard Trummer 6. Mai 2004 Aktionen in der Hauptschleife • Abfragen der Event Queue (Keyboard, Joystick). • Aktualisieren aller Objekte (physikalisches Modell). • Kollisionsabfragen (Objekt-Objekt, Objekt-Spielfeld). • Entfernen nicht mehr benötigter Objekte. • Neuzeichnen aller Objekte und Aktualisierung des Displays. • Wartezeit bis zum nächsten Frame. – Typeset by FoilTEX – 32 Bernhard Trummer 6. Mai 2004 Physikalisches Modell Jede Bewegung von einem Objekt muß in einem physikalischen Modell abgebildet werden, wobei sowohl globale Gegebenheiten (Gravitation, Reibung, etc.) als auch aktuelle Eigenschaften des Objekts (Beschleunigung, Masse, Geschwindigkeit) berücksichtigt werden müssen. Ziel des physikalischen Modells ist es, basierend auf diesen Informationen die Position aller Objekte für das nächste Frame zu berechnen, damit sie neu gezeichnet werden können. – Typeset by FoilTEX – 33 Bernhard Trummer 6. Mai 2004 Formeln Geschwindigkeit: v = Beschleunigung: a = ∆s ∆t ∆v ∆t Kraft: F = m · a Wenn man die Masse eines Objekts und die darauf einwirkende Kraft als gegeben betrachtet, kann somit über die Beschleunigung die Geschwindigkeit und Position des Objekts berechnet werden. Als Grundlage für weitere Berechnungen sind diese Formeln allerdings nur teilweise brauchbar. Besser ist es, mit verallgemeinerten Zusammenhängen zwischen Beschleunigung, Geschwindigkeit und Weg zu beginnen. – Typeset by FoilTEX – 34 Bernhard Trummer 6. Mai 2004 a Z t t a(t)dt v(t) = 0 v Z t v(t)dt s(t) = 0 t s t Abbildung 2: Beschleunigung, Geschwindigkeit und Weg – Typeset by FoilTEX – Betrachtet man die Beschleunigung a als Funktion von der Zeit t, so kann man über die Integralrechnung einen allgemein gültigen Zusammenhang zwischen der Beschleunigung a(t), der Geschwindigkeit v(t) und dem Weg s(t) aufstellen. 35 Bernhard Trummer 6. Mai 2004 Zeitdiskretes Modell Jeder Bewegungsablauf wird letztendlich als Sequenz von Einzelbildern (Frames) dargestellt. Daher ist es notwendig, die vorigen Integralformeln in eine zeitdiskrete Form umzurechnen, um auf ein für den Computer berechenbares physikalisches Modell zu kommen. Zusätzlich werden folgende Vereinfachungen getroffen: • Die Beschleunigungsfunktion a(t) ist eine Treppenfunktion, dessen Wert innerhalb eines Frames konstant ist. • Die Framerate ist konstant. Damit ist auch das Zeitintervall ∆t, welches dem Kehrwert der Framerate entspricht, konstant. – Typeset by FoilTEX – 36 Bernhard Trummer 6. Mai 2004 Berechnung der Geschwindigkeit v0 = 0 Z v1 = v0 + 0 ∆t ∆t a1dt = v0 + (a1 · t)0 v1 = v0 + a1 · ∆t .. vn+1 = vn + an+1 · ∆t – Typeset by FoilTEX – 37 Bernhard Trummer 6. Mai 2004 Berechnung des Weges s0 = 0 Z s1 = s0 + 0 s1 s1 sn+1 ∆t v1 − v0 · t + v0 dt = s0 + ∆t 2 v1 − v0 t · + v0 · t ∆t 2 ∆t 0 v1 − v0 (v1 − v0) · ∆t 2 · v0 · ∆t 2 = s0 + · ∆t + v0 · ∆t = s0 + + 2 · ∆t 2 2 v1 + v0 = s0 + · ∆t 2 .. vn+1 + vn · ∆t = sn + 2 – Typeset by FoilTEX – 38 Bernhard Trummer 6. Mai 2004 Zusammenfassung vn+1 = vn + an+1 · ∆t vn+1 + vn · ∆t sn+1 = sn + 2 • Die Berechnung der Geschwindigkeit und der Position eines Objekts für das nächste Frame erfolgt inkrementell. Die Werte des vorigen Frames müssen also gespeichert werden. • Die Beschleunigung an+1 ist die einzige Unbekannte, welche für die Berechnung notwendig ist. Diese ergibt sich aus der Gravitation, Reibung und z.B. einer Schubkraft des Objekts. – Typeset by FoilTEX – 39 Bernhard Trummer 6. Mai 2004 Kollisionsabfrage zwischen zwei Objekten • Ermittle die Überschneidung der Bounding Boxes beider Objekte. • Liegt keine Überschneidung vor, kann auch keine Kollision vorliegen. • Bei einer Überschneidung wird ein pixelweiser Vergleich in diesem Bereich durchgeführt. Existiert ein Pixel, das in beiden Objekten nicht transparent ist, liegt eine Kollision vor. – Typeset by FoilTEX – 40 Bernhard Trummer 6. Mai 2004 Wartezeit bis zum nächsten Frame Einige Spiele verzichten auf eine Wartezeit, was allerdings zu einer vollen CPU-Auslastung führt. Auf schneller Hardware können dann zwar sehr hohe Framerates erreicht werden, die jedoch von einem Monitor praktisch nicht mehr dargestellt werden können. Weiters muß die vergangene Zeit zwischen zwei Frames bestimmt und im physikalischen Modell berücksichtigt werden, da sich z.B. ein steuerbares Raumschiff unabhängig von der Framerate immer gleich verhalten soll. Eine andere Möglichkeit ohne diese Nachteile ist die Vorgabe einer (fixen) Framerate, die durch einen Wartezyklus nach jedem Durchlauf der Hauptschleife erreicht wird, ohne dabei CPU-Zeit zu verbrauchen. – Typeset by FoilTEX – 41 Bernhard Trummer 6. Mai 2004 SDL Delay() Verwendet man SDL Delay() für die Wartezeit zwischen zwei Frames, wobei als Parameter der Kehrwert der Framerate verwendet wird, so ergibt sich in Wirklichkeit eine Framerate, die je nach Geschwindigkeit der Maschine etwas geringer ist. Die Ursache dafür liegt in der Berechnung und Darstellung eines Frames, wofür Rechenzeit benötigt wird. Für eine korrekte Wartezeit müßte also diese Zeit vom Kehrwert der Framerate abgezogen werden, bevor SDL Delay() aufgerufen wird. – Typeset by FoilTEX – 42 Bernhard Trummer 6. Mai 2004 Framerate Control der libSDL gfx void SDL_initFramerate(FPSmanager * manager); int SDL_setFramerate(FPSmanager * manager, int rate); void SDL_framerateDelay(FPSmanager * manager); Eine elegantere Lösung für das Einhalten einer fixen Framerate kann durch obige Funktionen erreicht werden. Nach der Initialisierung und dem Setzen einer Framerate muß nur dafür gesorgt werden, daß die Funktion SDL framerateDelay() einmal in der Hauptschleife aufgerufen wird. Weiters sorgt diese Funktion dafür, daß die Wartezeit über mehrere Frames hinweg beobachtet wird, um betriebssystembedingte Abweichungen in den nächsten Frames wieder auszugleichen zu können. – Typeset by FoilTEX – 43 Bernhard Trummer 6. Mai 2004 Beispielprogramme (Teil 2) 05-control2.cpp: Erweiterung von 05-control1.cpp mit einer Frameratekontrollierte Hauptschleife. 06-control3.cpp: Noch eine Erweiterung mit einem verbesserten KeyboardHandling für die Steuerung des Schiffs. 07-rotozoom.cpp: Demonstration des Rotozoomers der libSDL gfx. – Typeset by FoilTEX – 44 Bernhard Trummer 6. Mai 2004 Homepage der SDL http://www.libsdl.org/index.php Zusätzlich zu SDL-eigenen Links (Source, FAQ, Dokumentationen, etc.) sind hier auch massenhaft externe Links angeführt, die auf Zusatzbibliotheken, Applikationen, Spiele, Tutorials und Dokumentationen verweisen, die mit der SDL zu tun haben. – Typeset by FoilTEX – 45