[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


Anmelden zum Antworten