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

Documentos relacionados