[SDL] Hintergrundbild kacheln
-
Hallo Leute,
gestern hab ich angefangen etwas mit der SDL zu arbeiten.
Eine Frage hat sich mir aufgetan.
Und zwar fand ich keine Möglichkeit Background sowohl horizontal wie auch vertikal zu kacheln (das komplette Window ausfüllend).//Der SDL Include Block #ifdef WIN32 #include <SDL.h> #include <SDL_image.h> #else #include <SDL/SDL.h> #include <SDL/SDL_image.h> #endif //Der STD iostream include, damit wir mit cout etwas auf der Console ausgeben können #include <iostream.h> int main(int argc, char **argv) { cout << "opij" <<endl; int y,x; int d; //Starten von SDL if(SDL_Init(SDL_INIT_VIDEO) < 0 ) { return -1; } //Dafür sorgen, dass SDL_Quit beim Beenden aufgerufen wird atexit(SDL_Quit); //Hier erzeugen wir ein Fenster mit 800x600x32 mit DoubleBuf Support. Wollen wir noch Fullscreen haben, hängen wir einfach an SDL_DOUBLEBUF ein " | SDL_FULLSCREEN" an SDL_Surface *screen = SDL_SetVideoMode(1200, 900, 32, SDL_DOUBLEBUF); if(screen == NULL) { //Sollte ein Fehler beim Erstellen des SDL-Fensters aufgetreten sein, geben wir die SDL Fehler Meldung zurück und beenden das Programm std::cout << "Konnte SDL Fenster nicht erzeugen: " << std::endl << SDL_GetError() << std::endl; return -1; } //Nun setzen wir den Anwendungs-Titel SDL_WM_SetCaption("SDL - Beispiel2","SDL - Bexfgispiel2"); //Hier laden wir unser Bild mit SDL_Image SDL_Surface *Image = IMG_Load("sdl_example2_tux.jpg"); SDL_Surface *Background = IMG_Load("bg.jpg"); if(Image == NULL) { //Sollte er das Bild nicht laden können std::cout << "Konnte das Bild nicht laden: " << std::endl << SDL_GetError() << std::endl; return -1; } if(Background == NULL) { //Sollte er das Bild nicht laden können std::cout << "Konnte das Bild nicht laden: " << std::endl << SDL_GetError() << std::endl; return -1; } //Hier speichern wie die Abmessung für unser Image in einem SDL_Rect SDL_Rect rImage, rBackground; rImage.x = 0; rImage.y = 0; rImage.w = Image->w; rImage.h = Image->h; rBackground.x = 0; rBackground.y = 0; rBackground.w = Background->w; rBackground.h = Background->h; //Hier speichern wir die Position von unserem Image SDL_Rect rPos_Image = rImage; SDL_Rect rPos_Background = rBackground; //Die Event-Struktur, um SDL_Events auszuwerten SDL_Event event; //Unsere Variable die dafür sorgt, dass unser Fenster erstmal geöffnet bleibt bool bRun = true; //Speichern, wohin er sich bewegen soll bool bLeft = false; bool bRight = false; bool bUp = false; bool bDown = false; //Unsere Main Loop while(bRun) { //Hier fragen wir alle anstehenden SDL_Events ab while(SDL_PollEvent(&event)) { //Und gehen diese durch switch(event.type){ case SDL_KEYDOWN: //Eine Taste wurde gedrückt. Nun müssen wir feststellen, welche Taste if(event.key.keysym.sym==SDLK_LEFT) { //Pfeiltaste Links wurde gedrückt bLeft = true; } else if(event.key.keysym.sym==SDLK_RIGHT) { //Pfeiltaste Rechts wurde gedrückt bRight = true; } else if(event.key.keysym.sym==SDLK_DOWN) { //Pfeiltaste Oben wurde gedrückt bDown = true; } else if(event.key.keysym.sym==SDLK_UP) { //Pfeiltaste Unten wurde gedrückt bUp = true; } if(event.key.keysym.sym==SDLK_ESCAPE) { //ESCAPE wurde gedrückt. Also Beenden wir alles bRun = false; } break; case SDL_KEYUP: //Eine Taste wurde losgelassen. Nun müssen wir feststellen, welche Taste if(event.key.keysym.sym==SDLK_LEFT) { //Pfeiltaste Links wurde losgelassen bLeft = false; } else if(event.key.keysym.sym==SDLK_RIGHT) { //Pfeiltaste Rechts wurde losgelassen bRight = false; } else if(event.key.keysym.sym==SDLK_DOWN) { //Pfeiltaste Oben wurde losgelassen bDown = false; } else if(event.key.keysym.sym==SDLK_UP) { //Pfeiltaste Unten wurde losgelassen bUp = false; } break; case SDL_QUIT: //Sollte das Fenster geschlossen werden, soll er auch die Loop beenden bRun = false; break; default: break; } } //Hier können wir später unsere eigenen Sachen einbauen //Hier bewegen wir den Spieler um jeweils 1 Pixel in die gedrückte Richtung if(bLeft) { rPos_Image.x -= 1; } else if(bRight) { rPos_Image.x += 1; } if(bUp) { rPos_Image.y -= 1; } else if(bDown) { rPos_Image.y += 1; } //Zuerst übermalen wir den Bildschirm mit Schwarz SDL_FillRect(screen, 0, SDL_MapRGB(Image->format, 0, 0, 0)); //SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); //Hier blitten wir unser Bild an die Position die wir vorher definiert habe SDL_BlitSurface(Background, &rBackground, screen, &rPos_Background); SDL_BlitSurface(Image, &rImage, screen, &rPos_Image); //Dann updaten wir den Screen, damit wir auch etwas sehen. SDL_Flip(screen); } //Hier müssen wir noch unser Bild nach der Schleife wieder freigeben SDL_FreeSurface(Image); return 0; }
-
mit 2 schleifen?
//Initialisierung ..... for( int y = 0 ; y < AnzahlDerKachelAufDerYAchse ; y++) { for( int x = 0 ; x < AnzahlDerKachelAufDerXAchse ; x++) { //Pseudocode Bild.x = x*(Bild.w); Bild.y = y*(Bild.h); } } //Bliten Render usw.....
-
Danke
Ich hab angenommen, dafür gäbe es eine funktion.
Nun hab ich das Problem, dass wenn ich mit der SDL_gfx Library ein Rechteck zeichne, die geometrischen Formen + Schrift aufblinken.
Wobei ich mich streng an ein Tutorial dazu gehalten habe.
Woran mag das liegen?
-
ok hier muss ich passen
hab noch nie mit SDL_GFX gearbeitet.
-
puuuuh, ich hab gerade deine Schleife ausprobiert.
Logisch ist sie ja, nur irgendwie funktioniert sie nicht.
In welche Codezeile muss ich das packen? (das Dokument findest du in meinem obersten Post).for( int y = 0 ; y < 4 ; y++) { for( int x = 0 ; x < 4 ; x++) { rBackground.x = x*(rBackground.w); rBackground.y = y*(rBackground.h); } } SDL_BlitSurface(Background, &rBackground, screen, &rPos_Background);
-
DieSeenDerHerrlichkeit schrieb:
puuuuh, ich hab gerade deine Schleife ausprobiert.
Logisch ist sie ja, nur irgendwie funktioniert sie nicht.
In welche Codezeile muss ich das packen? (das Dokument findest du in meinem obersten Post).for( int y = 0 ; y < 4 ; y++) { for( int x = 0 ; x < 4 ; x++) { rBackground.x = x*(rBackground.w); rBackground.y = y*(rBackground.h); } } SDL_BlitSurface(Background, &rBackground, screen, &rPos_Background);
Ich würde dein Quellcode so umschreiben.
//SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); //Hier blitten wir unser Bild an die Position die wir vorher definiert habe for( int y = 0 ; y < 4 ; y++) { for( int x = 0 ; x < 4 ; x++) { rBackground.x = x*(rBackground.w); rBackground.y = y*(rBackground.h); SDL_BlitSurface(Background, &rBackground, screen, &rPos_Background); } }
-
Dein Code steht in Zeile 168. Genauso hat ich es auch.
Es klappt nur nicht//Der SDL Include Block #ifdef WIN32 #include <SDL.h> #include <SDL_image.h> #else #include <SDL/SDL.h> #include <SDL/SDL_image.h> #endif #include <SDL_gfxPrimitives.h> //Der STD iostream include, damit wir mit cout etwas auf der Console ausgeben können #include <iostream.h> int main(int argc, char **argv) { cout << "opij" <<endl; int y,x; int d; //Starten von SDL if(SDL_Init(SDL_INIT_VIDEO) < 0 ) { return -1; } //Dafür sorgen, dass SDL_Quit beim Beenden aufgerufen wird atexit(SDL_Quit); //Hier erzeugen wir ein Fenster mit 800x600x32 mit DoubleBuf Support. Wollen wir noch Fullscreen haben, hängen wir einfach an SDL_DOUBLEBUF ein " | SDL_FULLSCREEN" an SDL_Surface *screen = SDL_SetVideoMode(1200, 900, 32, SDL_DOUBLEBUF); if(screen == NULL) { //Sollte ein Fehler beim Erstellen des SDL-Fensters aufgetreten sein, geben wir die SDL Fehler Meldung zurück und beenden das Programm std::cout << "Konnte SDL Fenster nicht erzeugen: " << std::endl << SDL_GetError() << std::endl; return -1; } //Nun setzen wir den Anwendungs-Titel SDL_WM_SetCaption("SDL - Beispiel2","SDL - Bexfgispiel2"); //Hier laden wir unser Bild mit SDL_Image SDL_Surface *Image = IMG_Load("cbg.jpg"); SDL_Surface *Background = IMG_Load("bg.jpg"); if(Image == NULL) { //Sollte er das Bild nicht laden können std::cout << "Konnte das Bild nicht laden: " << std::endl << SDL_GetError() << std::endl; return -1; } if(Background == NULL) { //Sollte er das Bild nicht laden können std::cout << "Konnte das Bild nicht laden: " << std::endl << SDL_GetError() << std::endl; return -1; } //Hier speichern wie die Abmessung für unser Image in einem SDL_Rect SDL_Rect rImage, rBackground; rImage.x = 0; rImage.y = 0; rImage.w = Image->w; rImage.h = Image->h; rBackground.x = 0; rBackground.y = 0; rBackground.w = Background->w; rBackground.h = Background->h; //Hier speichern wir die Position von unserem Image SDL_Rect rPos_Image = rImage; SDL_Rect rPos_Background = rBackground; //Die Event-Struktur, um SDL_Events auszuwerten SDL_Event event; //Unsere Variable die dafür sorgt, dass unser Fenster erstmal geöffnet bleibt bool bRun = true; //Speichern, wohin er sich bewegen soll bool bLeft = false; bool bRight = false; bool bUp = false; bool bDown = false; //Unsere Main Loop while(bRun) { //Hier fragen wir alle anstehenden SDL_Events ab while(SDL_PollEvent(&event)) { //Und gehen diese durch switch(event.type){ case SDL_KEYDOWN: //Eine Taste wurde gedrückt. Nun müssen wir feststellen, welche Taste if(event.key.keysym.sym==SDLK_LEFT) { //Pfeiltaste Links wurde gedrückt bLeft = true; } else if(event.key.keysym.sym==SDLK_RIGHT) { //Pfeiltaste Rechts wurde gedrückt bRight = true; } else if(event.key.keysym.sym==SDLK_DOWN) { //Pfeiltaste Oben wurde gedrückt bDown = true; } else if(event.key.keysym.sym==SDLK_UP) { //Pfeiltaste Unten wurde gedrückt bUp = true; stringColor (screen, 10, 20, "c: loescdfssdffffffffffffffffgddBildschirmes", 0xffffffff); } if(event.key.keysym.sym==SDLK_ESCAPE) { //ESCAPE wurde gedrückt. Also Beenden wir alles bRun = false; } break; case SDL_KEYUP: //Eine Taste wurde losgelassen. Nun müssen wir feststellen, welche Taste if(event.key.keysym.sym==SDLK_LEFT) { //Pfeiltaste Links wurde losgelassen bLeft = false; } else if(event.key.keysym.sym==SDLK_RIGHT) { //Pfeiltaste Rechts wurde losgelassen bRight = false; } else if(event.key.keysym.sym==SDLK_DOWN) { //Pfeiltaste Oben wurde losgelassen bDown = false; } else if(event.key.keysym.sym==SDLK_UP) { //Pfeiltaste Unten wurde losgelassen bUp = false; } break; case SDL_QUIT: //Sollte das Fenster geschlossen werden, soll er auch die Loop beenden bRun = false; break; default: break; } } //Hier können wir später unsere eigenen Sachen einbauen //Hier bewegen wir den Spieler um jeweils 1 Pixel in die gedrückte Richtung if(bLeft) { rPos_Image.x -= 1; } else if(bRight) { rPos_Image.x += 1; } if(bUp) { rPos_Image.y -= 1; } else if(bDown) { rPos_Image.y += 1; } stringColor (screen, 10, 10, "Text", 0xffffffff); rectangleColor (screen, 20, 60, 620, 460, 0xffffffff); SDL_UpdateRect (screen, 0, 0, 640, 480); //Zuerst übermalen wir den Bildschirm mit Schwarz SDL_FillRect(screen, 0, SDL_MapRGB(Image->format, 0, 0, 0)); //SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); //Hier blitten wir unser Bild an die Position die wir vorher definiert habe for( int y = 0 ; y < 4 ; y++) { for( int x = 0 ; x < 4 ; x++) { rBackground.x = x*(rBackground.w); rBackground.y = y*(rBackground.h); SDL_BlitSurface(Background, &rBackground, screen, &rPos_Background); } } SDL_BlitSurface(Image, &rImage, screen, &rPos_Image); //Dann updaten wir den Screen, damit wir auch etwas sehen. SDL_Flip(screen); } //Hier müssen wir noch unser Bild nach der Schleife wieder freigeben SDL_FreeSurface(Image); return 0; }
-
Du musst eine zweite Surface machen. Dann alles darauf kacheln und den Surface auf dein Screen zeichnen. Denn immoment wird nur die Kachel umher geschoben.
Das nennt man dann Doublebuffer