SDL: Tux-Programm
Tux bewegen in blauer Szene:
[Bearbeiten]Da wir jetzt alle wichtigen Sachen für unser erstes richtiges Programm in diesem Kapitel gelernt haben, werde ich auch sogleich dessen Quellcode zeigen:
Quellcode
[Bearbeiten] #include <stdlib.h>
#include <SDL/SDL.h>
int main(int argc, char *argv[])
{
SDL_Surface *screen, *image;
SDL_Rect dst, dstblue;
SDL_Event event;
Uint8 *keys;
int tuxX = 50, tuxY = 50;
int done = 0;
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
printf("Can't init SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
if (screen == NULL) {
printf("Can't set video mode: %s\n", SDL_GetError());
exit(1);
}
image = SDL_LoadBMP("tux.bmp");
if (image == NULL) {
printf("Can't load image of tux: %s\n", SDL_GetError());
exit(1);
}
dst.w = image->w;
dst.h = image->h;
dstblue.w = image->w + 1;
dstblue.h = image->h + 1;
SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 255, 0, 0));
while (!done) {
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
}
}
dstblue.x = tuxX;
dstblue.y = tuxY;
keys = SDL_GetKeyState(NULL);
if (keys[SDLK_UP]) {
if (tuxY > 10) {
tuxY--;
}
}
if (keys[SDLK_DOWN]) {
if (tuxY < 470 - image->h) {
tuxY++;
}
}
if (keys[SDLK_RIGHT]) {
if(tuxX < 630 - image->w) {
tuxX++;
}
}
if (keys[SDLK_LEFT]) {
if (tuxX > 10) {
tuxX--;
}
}
dst.x = tuxX;
dst.y = tuxY;
SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
SDL_BlitSurface(image, NULL, screen, &dst);
SDL_Flip(screen);
}
SDL_FreeSurface(image);
return 0;
}
Erläuterungen
[Bearbeiten]Wow, das sieht ziemlich schlimm aus, obwohl eigentlich doch garnicht soviel Neues drin ist. Oben deklarieren wir zwei Integer Variablen namens tuxX
und tuxY
, welche die Position des x-, bzw. y-Wertes der Oberfläche des Bildes von Tux speichern. Weiter unten wird dann nach der Aktualisierung des Feldes keys
, die den Zustand der Tasten speichert, durch if-Anweisungen der Wert von tuxX
und tuxY
je nach Richtung der Pfeiltaste verändert. Dabei wird überprüft, dass Tux nicht an den Rand kommt und in einem solchen Fall keine weitere Bewegegung in diese Richtung gemacht wird. Unter den ganzen if-Anweisungen wird dann der x- und y-Wert des Rechteckes, welches den Bereich, in dem Tux auf das Bildschirmsurface geblittet wird, darstellt, den Werten der Variablen tuxX und tuxY angepasst.
Eigentlich wären diese beiden unnötig, da man theoretisch direkt die Werte des Rechtecks ändern könnte, doch steigert das Speichern dieser in zwei extra angelegte Integer Variablen die Übersicht gewaltig.
Jetzt ringe ich mich auch dazu durch, den Sinn des Rechtecks: "dstblue" zu erklären. Es stellt den Bereich dar, der auf dem Bildschirm blau angestrichen werden soll, doch da am Anfang schon das komplette screen Surface blau angemalt wurde, ist nur das Neuzeichnen der vorher von Tux verdeckten Bereiche von Nöten. So würde Tux ohne neues blaues Anzeichnen des vorher von ihm verdeckten Bereiches einen Schweif hinter sich herziehen. Dieses ließe sich natürlich ganz einfach durch das neu blau Anmalen des gesamten Bildschirms realiseren, doch wäre das nicht sehr effektiv. Speed ist aber wie jeder wissen sollte das Wichtigste überhaupt in Spielen. Deshalb geben wir kurz nach der Initialisierung des Surfaces, welches das Bild von Tux enthält, dem Rechteck "dstblue" die Weite des Bildes plus eins und die Höhe des Bildes plus eins. Bloß warum + 1? Ganz einfach: Wir bewegen Tux immer genau ein Pixel weiter, wenn eine bestimmte Pfeiltaste gedrückt wird und deshalb wird auch immer eine Reihe von Pixel die vorher verdeckt waren angezeigt, und diese gilt es mit blau zu übermalen. Darum wird dann je nach Tastendruck, der x- und y-Wert von "dstblue" dementsprechend angepasst, damit ist der blau zu malende Bereich des Bildschirms immer ein Pixel höher, breiter, weiter links und weiter oben als Tux selbst, so werden also diese blöden Schweife beim Bewegen vermieden.
Screenshot des Programms.