SDL Linux fragen



  • hallo,

    ich schreibe momentan mit mein Tablett via C4droid (ein c/c++ compiler für android) ein Spiel in SDL. -> dieses ist durch ein sdl plugin aus dem play-store möglich.

    -> android laüft auf linux kernel, daher programmiert man auf linux basis

    Da ich totaler neuling in diesem gebiet bin, bin ich nach stundenlangen googeln und nicht laufenden samples auf irgendein wikki gestoßen.

    mit hilfe des sample ordner, der in diesem wikki war, wollte ich anfangen ein space shooter zu schreiben, da der code laüft (siehe unter linux)

    das beispiel program zeigt wie man in sdl (linux) den screen blau einfäbt,
    ein linux pinguin bmp darstellt und steuern kann, sowie hintergrund music und wenn man space drückt ein ton kommt

    ...

    Aus diesem beispiel habe ich nun angefangen ein spiel zu programmieren

    Da ich vorher nur in lite C (eine programmiersprache für das autorensystem "3D Game Studio") programmiert habe ist sdl wie schon gesagt neuland

    der fehler liegt glaub ich bei der sdl_blit bitmap darstellung in der shoot function
    weil screen hab ich zu 0 gemacht weil nicht weiß welches sdl_surface ich benutzen soll, oder ob ich es überhaupt benutzen soll.

    Es soll ein laser schuss vom raumschiff geschossen wedern , hie aber nur von der position des images... programm laüft aber... es kommt nichts wenn ich schieße (mit space)..

    hier der code:



  • // SDL-, SDL_image-, SDL_mixer- und SDL_ttf-Header einbinden
    #ifdef WIN32
    #include <SDL.h>
    #include <SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_ttf.h>
    #else
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <SDL/SDL_mixer.h>
    #include <SDL/SDL_ttf.h>
    #endif
    
    #include <iostream>
    
    int shoot_1();
    
    int main(int argc, char* argv[])
    {
    	// SDL mit dem Grafik- und Audiosystem initialisieren.
    	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1)
    	{
    		// Ups, das hat nicht funktioniert!
    		// Wir geben die Fehlermeldung aus.
    		std::cerr << "Konnte SDL nicht initialisieren! Fehler: " << SDL_GetError() << std::endl;
    		return -1;
    	}
    
    	// Hier erzeugen wir ein Fenster der Gr��e 800x600 Pixel mit 32-Bit Farbtiefe und Double Buffer.
    	// Wenn Vollbildmodus erw�nscht ist, f�gen wir noch das Flag SDL_FULLSCREEN mittels |-Operator hinzu.
    	SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, SDL_DOUBLEBUF);
    	if(!screen)
    	{
    		// Fehler! Fehlermeldung ausgeben und Programm beenden.
    		std::cerr << "Konnte SDL-Fenster nicht erzeugen! Fehler: " << SDL_GetError() << std::endl;
    		return -1;
    	} 
    
    	// Nun setzen wir noch den Titel des Fensters.
    	SDL_WM_SetCaption("Game", "Game");
    
    	// Hier laden wir unser Bild mit SDL_image.
    	SDL_Surface* image = IMG_Load("ship.jpg");
    	SDL_Surface* background_a = IMG_Load("background_a.jpg");
    	SDL_Surface* shoot_a =IMG_Load("shoot.jpg");
    
    	if(!image)
    	{
    		// Fehler!
    		std::cerr << "Konnte das Bild nicht laden! Fehler: " << IMG_GetError() << std::endl;
    		return -1;
    	}
    
    	// SDL_mixer starten.
    	const int samplingFrequency = 44100;	// 44100 Hz Abtastfrequenz
    	Uint16 audioFormat = AUDIO_S16SYS;		// 16 Bits pro Sample
    	const int numChannels = 2;				// 2 Kan�le = Stereo
    	const int chunkSize = 4096;				// ein guter Wert ...
    	if(Mix_OpenAudio(samplingFrequency, audioFormat, numChannels, chunkSize) == -1)
    	{
    		std::cerr << "Konnte SDL_mixer nicht starten! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// WAV-Datei laden.
    	Mix_Chunk* sound = Mix_LoadWAV("SDL_Example_Sound.wav");
    	if(!sound)
    	{
    		std::cerr << "Konnte WAV-Datei nicht laden! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// OGG-Datei als Musik laden.
    	Mix_Music* music = Mix_LoadMUS("SDL_Example_Music.ogg");
    	if(!music)
    	{
    		std::cerr << "Konnte OGG-Datei nicht laden! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// Musik abspielen.
    	Mix_PlayMusic(music, -1);
    
    	// SDL_ttf initialisieren.
    	if(TTF_Init() == -1)
    	{
    		std::cerr << "Konnte SDL_ttf nicht initialisieren! Fehler: " << TTF_GetError() << std::endl;
    		return -1;
    	}
    
    	// Schriftart "FreeSans.ttf" laden.
    	TTF_Font* font = TTF_OpenFont("FreeSans.ttf", 12);
    	if(!font)
    	{
    		std::cerr << "Konnte Schriftart nicht laden! Fehler: " << TTF_GetError() << std::endl;
    		return -1;
    	}
    
    	// Einen Text zeichnen.
    	SDL_Color textColor = {255, 255, 1};
    	SDL_Surface* text = TTF_RenderText_Blended(font, "written by Patrick Ratz", textColor);
    
    	// In diesem Array merken wir uns, welche Tasten gerade gedr�ckt sind.
    	bool keyPressed[SDLK_LAST];
    	memset(keyPressed, 0, sizeof(keyPressed));
    
    	// Position des Bilds initialisieren.
    
    	SDL_Rect imagePosition;
    	imagePosition.x = 400;
    	imagePosition.y = 500;
    
    	SDL_Rect background_aPosition;
    	background_aPosition.x = 0;
    	background_aPosition.y = 0;
    
    	bool run = true;
    
    	// die Event-Schleife
    	while(run)
    	{
    		// Wir holen uns so lange neue Ereignisse, bis es keine mehr gibt.
    		SDL_Event event;
    		while(SDL_PollEvent(&event))
    		{
    			// Was ist passiert?
    			switch(event.type)
    			{
    			case SDL_QUIT:
    				// Das Programm soll beendet werden.
    				// Wir merken uns das und brechen beim n�chsten Mal die Schleife ab.
    				run = false;
    				break;
    
    			case SDL_KEYDOWN:
    				keyPressed[event.key.keysym.sym] = true;
    				if(event.key.keysym.sym == SDLK_SPACE)
    				{
    					// Sound abspielen
    					Mix_PlayChannel(-1, sound, 0);
    				}
    
    				break;
    			case SDL_KEYUP:
    				keyPressed[event.key.keysym.sym] = false;
    				break;
    			}
    		}
    
    		// Hier w�rden bei einem Spiel die eigentliche Spiellogik berechnet
    		// und Grafiken angezeigt werden.
    
    		// Bild je nach gedr�ckten Tasten bewegen.
    
    		if(keyPressed[SDLK_LEFT]    && imagePosition.x > 0)                     --imagePosition.x;  // Bild nach links bewegen.
    		if(keyPressed[SDLK_RIGHT]   && imagePosition.x + image->w < screen->w)  ++imagePosition.x;  // Bild nach rechts bewegen.
    		if(keyPressed[SDLK_UP]      && imagePosition.y > 0)                     --imagePosition.y;  // Bild nach oben bewegen.
    		if(keyPressed[SDLK_DOWN]    && imagePosition.y + image->h < screen->h)  ++imagePosition.y;  // Bild nach unten bewegen.
    		if(keyPressed[SDLK_SPACE]) shoot_1(); 
    		if(keyPressed[SDLK_ESCAPE])												run = false;		// Programm beenden.
    
    		// Bildschirm mit Blau f�llen und dann das Bild zeichnen.
    		SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 255));
    
    		SDL_BlitSurface(background_a, 0, screen, &background_aPosition);
    		SDL_BlitSurface(image, 0, screen, &imagePosition);
    
    		// Den Text ausgeben.
    		SDL_Rect textPosition;
    		textPosition.x = 10;
    		textPosition.y = 50;
    		SDL_BlitSurface(text, 0, screen, &textPosition);
    
    		// Dann aktualisieren wir den Bildschirm, damit wir auch etwas sehen.
    		SDL_Flip(screen);
    	}
    
    	// Bild wieder freigeben
    	SDL_FreeSurface(image);
    	SDL_FreeSurface(background_a);
    
    	// Sound und Musik aufr�umen und SDL_mixer stoppen
    	Mix_FreeChunk(sound);
    	Mix_FreeMusic(music);
    	Mix_CloseAudio();
    
    	// Schriftart und gezeichneten Text freigeben und SDL_ttf herunterfahren
    	SDL_FreeSurface(text);
    	TTF_CloseFont(font);
    	TTF_Quit();
    
    	// SDL herunterfahren
    	SDL_Quit();
    
    	return 0;
    }
    

    int shoot_1()
    {
    SDL_Surface* shoot_a =IMG_Load("shoot.jpg");
    SDL_Rect imagePosition;
    imagePosition.x = 400;
    imagePosition.y = 500;

    SDL_Rect shoot_Position;
    shoot_Position.x = imagePosition.x;
    shoot_Position.y = imagePosition.y;

    while(shoot_Position.y < 0)
    {
    SDL_BlitSurface(shoot_a, 0, 0, &shoot_Position);
    shoot_Position.y++;
    }
    SDL_FreeSurface(shoot_a);
    return 0;
    }



  • Hallo,

    zum einen ist deine while-Schleife in der shoot_1-Funktion falsch (die Bedingung ist bisher immer falsch) und dann wirst du bei der SDL_BlitSurface-Funktion (wie du ja schon selbst erkannt hast) denselben screen-Wert wie bei den anderen SDL_BlitSurface-Aufrufen verwenden müssen (Stichwort: Parameter-Übergabe).

    Hast du denn eine Möglichkeit auf dem Android zu debuggen (bzw. es erst einmal direkt unter Linux laufen zu lassen und dort zu debuggen)?
    Mir scheint, dir fehlen noch ein paar Grundlagen der C-Programmierung - und dann wird es (sehr) schwer, einfach Code zu erzeugen, zu kompilieren und hoffen, daß es dann einwandfrei läuft (gerade bei C muß man ja immer mal mit Abstürzen durch fehlerhafte Zeiger etc. rechnen).



  • Parameter übergabe ist glaub ich auch schon das stichwort
    ...
    Wie mache ich sdl_surface screen* denn "global", für sdl_blit ?
    So das ich von einer neuen function aus auf screen zugreifen kann ??

    Genau das selbe problem habe ich auch bei der position den schusses, denn der schuss sollte ursprünglich von der position des images (raumshiff) abgefeuert werden... aber auch hier kann ich nicht global auf die imageposition zugreifen - kla weil ja alles schon in main verankert ist... ergebniss, wenn der schuss functionieren würde,
    dann würde er immer von x 400, y 500 abgefeuert werden (siehe shoot_a)

    Kann mir mal wer das richtig stellen ?

    Achja ein noch ...

    warum steht oben bei den include folgendes:

    Wenn win32 starte include von sdl/sdl.h ...
    Wenn nicht,starte include von sdl/sdl.h ...

    Häää??



  • Sorry, aber wenn du noch nicht mal in der Lage bist eigene Funktionen mit Parametern zu erstellen, dann bist du noch nicht soweit, um externe Libs (wie die SDL) anzusteuern. Schau mal hier nach: Parameter.
    Bloß keine globalen Variablen verwenden (das scheint zwar einfacher zu sein, aber mögliche Fehler bei wachsendem Programmcode zu finden, dauert dann ewig)!

    Und bei den Includes sieh auch noch mal genauer hin (Stichwort: Unterverzeichnis)...



  • Danke es laüft ! 😉

    Ist zwar jetzt global als test aber es geht 🙂

    // SDL-, SDL_image-, SDL_mixer- und SDL_ttf-Header einbinden
    #ifdef WIN32
    #include <SDL.h>
    #include <SDL_image.h>
    #include <SDL_mixer.h>
    #include <SDL_ttf.h>
    #else
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <SDL/SDL_mixer.h>
    #include <SDL/SDL_ttf.h>
    #endif
    
    #include <iostream>
    
    int shoot_1(     SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, SDL_DOUBLEBUF));
    
    int main(int argc, char* argv[])
    {
    	// SDL mit dem Grafik- und Audiosystem initialisieren.
    	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1)
    	{
    		// Ups, das hat nicht funktioniert!
    		// Wir geben die Fehlermeldung aus.
    		std::cerr << "Konnte SDL nicht initialisieren! Fehler: " << SDL_GetError() << std::endl;
    		return -1;
    	}
    
    	// Hier erzeugen wir ein Fenster der Gr��e 800x600 Pixel mit 32-Bit Farbtiefe und Double Buffer.
    	// Wenn Vollbildmodus erw�nscht ist, f�gen wir noch das Flag SDL_FULLSCREEN mittels |-Operator hinzu.
        SDL_Surface* screen = SDL_SetVideoMode(800, 600, 32, SDL_DOUBLEBUF); 
    	if(!screen)
    	{
    		// Fehler! Fehlermeldung ausgeben und Programm beenden.
    		std::cerr << "Konnte SDL-Fenster nicht erzeugen! Fehler: " << SDL_GetError() << std::endl;
    		return -1;
    	} 
    
    	// Nun setzen wir noch den Titel des Fensters.
    	SDL_WM_SetCaption("Game", "Game");
    
    	// Hier laden wir unser Bild mit SDL_image.
    	SDL_Surface* image = IMG_Load("ship.jpg");
    	SDL_Surface* background_a = IMG_Load("background_a.jpg");
    	SDL_Surface* shoot_a =IMG_Load("shoot.jpg");
    	SDL_Surface* shoot = IMG_Load("ship.jpg");
    
    	if(!image)
    	{
    		// Fehler!
    		std::cerr << "Konnte das Bild nicht laden! Fehler: " << IMG_GetError() << std::endl;
    		return -1;
    	}
    
    	// SDL_mixer starten.
    	const int samplingFrequency = 44100;	// 44100 Hz Abtastfrequenz
    	Uint16 audioFormat = AUDIO_S16SYS;		// 16 Bits pro Sample
    	const int numChannels = 2;				// 2 Kan�le = Stereo
    	const int chunkSize = 4096;				// ein guter Wert ...
    	if(Mix_OpenAudio(samplingFrequency, audioFormat, numChannels, chunkSize) == -1)
    	{
    		std::cerr << "Konnte SDL_mixer nicht starten! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// WAV-Datei laden.
    	Mix_Chunk* sound = Mix_LoadWAV("SDL_Example_Sound.wav");
    	if(!sound)
    	{
    		std::cerr << "Konnte WAV-Datei nicht laden! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// OGG-Datei als Musik laden.
    	Mix_Music* music = Mix_LoadMUS("SDL_Example_Music.ogg");
    	if(!music)
    	{
    		std::cerr << "Konnte OGG-Datei nicht laden! Fehler: " << Mix_GetError() << std::endl;
    		return -1;
    	}
    
    	// Musik abspielen.
    	Mix_PlayMusic(music, -1);
    
    	// SDL_ttf initialisieren.
    	if(TTF_Init() == -1)
    	{
    		std::cerr << "Konnte SDL_ttf nicht initialisieren! Fehler: " << TTF_GetError() << std::endl;
    		return -1;
    	}
    
    	// Schriftart "FreeSans.ttf" laden.
    	TTF_Font* font = TTF_OpenFont("FreeSans.ttf", 12);
    	if(!font)
    	{
    		std::cerr << "Konnte Schriftart nicht laden! Fehler: " << TTF_GetError() << std::endl;
    		return -1;
    	}
    
    	// Einen Text zeichnen.
    	SDL_Color textColor = {255, 255, 1};
    	SDL_Surface* text = TTF_RenderText_Blended(font, "written by Patrick Ratz", textColor);
    
    	// In diesem Array merken wir uns, welche Tasten gerade gedr�ckt sind.
    	bool keyPressed[SDLK_LAST];
    	memset(keyPressed, 0, sizeof(keyPressed));
    
    	// Position des Bilds initialisieren.
    
      SDL_Rect shoot_Position;
        shoot_Position.x = 400;
    	shoot_Position.y = 300;	
    
    	SDL_Rect imagePosition;
    	imagePosition.x = 400;
    	imagePosition.y = 500;
    
    	SDL_Rect background_aPosition;
    	background_aPosition.x = 0;
    	background_aPosition.y = 0;
    
    	bool run = true;
    
    	// die Event-Schleife
    	while(run)
    	{
    		// Wir holen uns so lange neue Ereignisse, bis es keine mehr gibt.
    		SDL_Event event;
    		while(SDL_PollEvent(&event))
    		{
    			// Was ist passiert?
    			switch(event.type)
    			{
    			case SDL_QUIT:
    				// Das Programm soll beendet werden.
    				// Wir merken uns das und brechen beim n�chsten Mal die Schleife ab.
    				run = false;
    				break;
    
    			case SDL_KEYDOWN:
    				keyPressed[event.key.keysym.sym] = true;
    				if(event.key.keysym.sym == SDLK_SPACE)
    				{
    					// Sound abspielen
    					shoot_1(screen);
    						SDL_BlitSurface(shoot, 0, screen, &shoot_Position);
    					Mix_PlayChannel(-1, sound, 0);
    				}
    
    				break;
    			case SDL_KEYUP:
    				keyPressed[event.key.keysym.sym] = false;
    				break;
    			}
    		}
    
    		// Hier w�rden bei einem Spiel die eigentliche Spiellogik berechnet
    		// und Grafiken angezeigt werden.
    
    		// Bild je nach gedr�ckten Tasten bewegen.
    
    		if(keyPressed[SDLK_LEFT]    && imagePosition.x > 0)                     --imagePosition.x;  // Bild nach links bewegen.
    		if(keyPressed[SDLK_RIGHT]   && imagePosition.x + image->w < screen->w)  ++imagePosition.x;  // Bild nach rechts bewegen.
    		if(keyPressed[SDLK_UP]      && imagePosition.y > 0)                     --imagePosition.y;  // Bild nach oben bewegen.
    		if(keyPressed[SDLK_DOWN]    && imagePosition.y + image->h < screen->h)  ++imagePosition.y;  // Bild nach unten bewegen.
    		if(keyPressed[SDLK_SPACE]) shoot_1(screen); 
    		if(keyPressed[SDLK_ESCAPE])												run = false;		// Programm beenden.
    
    		// Bildschirm mit Blau f�llen und dann das Bild zeichnen.
    		SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 255));
    
    		SDL_BlitSurface(background_a, 0, screen, &background_aPosition);
    		SDL_BlitSurface(image, 0, screen, &imagePosition);
    
    		// Den Text ausgeben.
    		SDL_Rect textPosition;
    		textPosition.x = 10;
    		textPosition.y = 50;
    		SDL_BlitSurface(text, 0, screen, &textPosition);
    
    		// Dann aktualisieren wir den Bildschirm, damit wir auch etwas sehen.
    		SDL_Flip(screen);
    	}
    
    	// Bild wieder freigeben
    	SDL_FreeSurface(image);
    	SDL_FreeSurface(background_a);
    
    	// Sound und Musik aufr�umen und SDL_mixer stoppen
    	Mix_FreeChunk(sound);
    	Mix_FreeMusic(music);
    	Mix_CloseAudio();
    
    	// Schriftart und gezeichneten Text freigeben und SDL_ttf herunterfahren
    	SDL_FreeSurface(text);
    	TTF_CloseFont(font);
    	TTF_Quit();
    
    	// SDL herunterfahren
    	SDL_Quit();
    
    	return 0;
    }
    
    int shoot_1(SDL_Surface *screen)
    {
      SDL_Surface* shoot = IMG_Load("laser.png");
    
        SDL_Rect shoot_Position;
        shoot_Position.x = ;
    	shoot_Position.y = ;	
    
    	while(shoot_Position.y > 0 )
      {
    	SDL_BlitSurface(shoot, 0, screen, &shoot_Position);
    	--shoot_Position.y;
    	 SDL_Flip(screen);
      }
    
      return 0;
    }
    

    Ich hoffe es gefällt euch...



  • Der schuss bugt aber noch ... ist in arbeit 😉



  • So ich habs jetzt nochmal verucht umzustellen aber nichts ...
    es bleibt immer ein schwarzer screen

    KÖNNTE MIR MAL WER HELFEN

    Und einen so blöd runtermachen nur weil was nicht klappt oder versteht,dass man es dann ganz vergessen soll ? o.O

    Echt krass... zueienm muss ich sagen dass ich informatik nie in der schule hatte, es weder studiere noch für die arbeit brauche...

    Da ich mich aber trotzdem fürs programmieren interessiere, hab ich mir
    in laufe von etlichen jahren alles wissen selbst angeeignet und aus copy,paste und etlichen tutorials gelernt

    Es ging mir nur darum, ob mir mal wer den code richtig stellen kann

    Es wundert mich nicht, dass kaum leute spieleprogammieren wollen , da es anscheint einige affen gibt , die meinen anderen leuten alles nur schwer machen zu wollen und ihn zeigen wollen, wie blöd sie doch sind. Was ich ja selber hier schon erfahren habe, oder man auf irgendwelche links geschickt wird nach dem motto: kannste selbst ausarbeiten und dich mit beschäfftigen
    (-> dazu gibs auch nen kapittel in einigen büchern)...

    Egal.

    anscheind bin ich nicht der einzigste der mit dem sdl_surface probleme hatt
    Denn google spuckt mir echt viele foren aus, wo zwar nachgefragt wird, aber dann aufenmal keiner rückantworten mehr gibt ...

    So in etwa will ich das umgestellt haben:

    SDL_Surface* screen = SetVideoMode(800,600,32,DOUBLEBUF);  //erst dies
    ...
    Int shoot(screen)    // screen soll auf shoot für bildausgabe 
                         //übermittelt werden
    

    Und nicht jede function mit ein neuem fenster starten

    Ps: ich kann ja auch nichts dafür wenn das bei der eienen sprache so geht , beinder anderen sprache so...(bezogen auf die parameterübergabe)


Log in to reply