Montag, 8 Feb, 2010
Lektion 4
In dieser Lektion möchten wir ein paar mehr Grafiken auf den Bildschirm zaubern und dabei klären was eigentlich blitting ist.
Dazu schauen wir uns zuerst einmal an was wir seit der letzten Lektion haben. So sieht also aktuell unser Programm aus:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
SDL_Surface *lade_bild( std::string bildpfad )
{
//Nicht optimiertes Bild
SDL_Surface* normal_img = NULL;
//Optimiertes Bild
SDL_Surface* opt_img = NULL;
//Unoptimiertes Bild laden
normal_img = IMG_Load( bildpfad.c_str() );
//Optimiertes Bild erstellen
opt_img = SDL_DisplayFormat( normal_img );
//Unoptimiertes Bild freigeben
SDL_FreeSurface( normal_img );
//Farbschlüssel für die transparente Farbe im richigen Format erzeugen
Uint32 colorkey = SDL_MapRGB( opt_img->format, 0xFF, 0, 0xFF );
//Setze die Pixel der Farbe Rot 0, Grün 0xFF, Blau 0xFF auf Transparent
SDL_SetColorKey( opt_img, SDL_SRCCOLORKEY, colorkey );
return opt_img;
}
int main( int argc, char* args[] )
{
// Das Hallo Bild
SDL_Surface* hallo = NULL;
// Das Fenster in dem das Bild angezeigt werden soll
SDL_Surface* fenster = NULL;
//Initialisieren von SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Fenster Konfigurieren
fenster = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
//Bild laden
hallo = lade_bild( "hallo.png" );
//Bild auf dem Fenster anzeigen
SDL_BlitSurface( hallo, NULL, fenster, NULL );
//Anzeige aktualisieren
SDL_Flip( fenster );
//Pause
SDL_Delay( 3000 );
//Bildspeicher freigeben
SDL_FreeSurface( hallo );
//SDL beenden
SDL_Quit();
return 0;
}
Was wir machen wollen ist eine Raumschschiffflotte in beliebiger Formation vor einen Weltraumhintergrund darzustellen, ca. so:

Um das zu bewerkstelligen, erstellen wir eine Funktion in der wir die SDL_BlitSurface() aufrufen. So können wir auf einfache weise ein Bild bliten. Aber was bedeutet eigentlich dieses blitten. Blitten heist ein Bild oder Bildteil in den Speicher zur Anzeige zu laden. Also wie bis her, unser Bild auf dem Fenster blitten. Wir haben also unser Bild auf das Fenster geschoben. Was jetzt neu hinzu kommt das wir die Position angeben an der ein Bild im Ziel angezeigt wird, in diesem Fall wird unsere Raumschiffe an einer bestimmten Position auf das Fenster geschoben.

An der Stelle gibt es noch zu klären, wie das Koordinaten-System im SDL Funktioniert. Von Links nach Rechts verläuft zunehmend die X-Achse und von Oben nach unten die Y-Achse, also so:

Nun aber zu unserer Blittingfunktion. Diese hatte keinen Rückgabewert aber ein paar Parameter die sie übergeben bekommt. Die ersten beiden Parameter legen die Position fest, an der das Bild auf dem Ziel angezeigt werden soll. Parameter 3 enthält das Bild was auf eine Oberfläche geschoben werden soll und das vierte Argument enthält die Zieloberfläche auf der das Bild dargestellt werden soll. Die Positionsangabe speichern wir in einen SDL-Rechteck. Dieses enthält sowohl den x und y Offset und eine hohen und breiten Angabe für ein Rechteck. Das SDL-Rechteck benötigen wir dann für die Blitting-Funktion, da die nur ein SDL-Rect zur Positionsangabe akzeptiert
void blit_obj( int x, int y, SDL_Surface* quelle, SDL_Surface* ziel ) {
//Erzeugt ein temporäres Rechteck zur Positionierung der Quelle
SDL_Rect offset;
//Übergibt die Position an das SDL-Rechteck
offset.x = x;
offset.y = y;
Als nächstes blitten wir unser Bild auf die Anzeigeoberfläche(um das verbleibende NULL kümmern wir uns in einer späteren Lektion):
//Bild blitten SDL_BlitSurface( quelle, NULL, ziel, &offset ); }
Jetzt kümmern wir uns um unsere Main Funktion. Als erstes deklarieren wir die SDL Oberflächen. Also einmal für das Fenster, einmal für den Hintergrund und einmal für das Raumschiff. An dieser Stelle merkt ihr schon das wir das Raumschiff nur einmal laden müssen und es dann 3 mal auf unterschiedliche Positionen blitten können.
int main( int argc, char* args[] )
{
// Fenster
SDL_Surface* fenster = NULL;
//Hintergrund
SDL_Surface* hintergrund = NULL;
// Raumschiff
SDL_Surface* raumschiff = NULL;
Dann initialisieren wir wieder SDL und setzen die Attribute für unser Fenster.
//Initialisieren von SDL SDL_Init( SDL_INIT_EVERYTHING ); //Fenster Konfigurieren fenster = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
Nun laden wir unseren Hintergrund und unser Raumschiff:
//Hintergrund laden hintergrund = lade_bild( "hintergrund.png" ); //Raumschiff laden raumschiff = lade_bild( "raumschiff.png" );
So und jetzt blitten wir den Hintergrund und 3 mal das Raumschiff:
//Hintergrund blitten blit_obj( 0,0, hintergrund, fenster ); // Raumschiffe blitten blit_obj( 350,150, raumschiff, fenster ); blit_obj( 250,250, raumschiff, fenster ); blit_obj( 450,250, raumschiff, fenster );
Und nun Updaten wir das Fenster, warten ein paar Sekunden und räumen auf:
//Anzeige aktualisieren SDL_Flip( fenster ); //Pause SDL_Delay( 3000 ); //Bildspeicher freigeben SDL_FreeSurface( hintergrund ); SDL_FreeSurface( raumschiff ); //SDL beenden SDL_Quit(); return 0; }
So und schon haben wir ein Raumschiffflotte =^=.