Sprites



  • GrafikApi: SDL
    Also, ich suche ein Tutorial dass erklärt wie man Sprites auf ein Bild/Map bekommt. Ich möchte eine selbstgemalte Map anzeigen auf der man einen kleinen schwarzen (welche Farbe auch immer) Punkt bewegen kann. Ich hab vor etwas längerer Zeit mal ein Rollenspiel gesehen (von softgames.de) in dem man nur einen Gelben Punkt spielt. Und so etwas würde ich auch ganz gern mal als Test ausprobeiren. Ich habe es mit Diversen guten Tutorials schon hinbekommen das man Bitmaps bewegt. Aber das bringt ja nichts da man ja keine zweite hintergrund Bitmap anzeigen kann, oder doch? Ich zeige hier mal den Quellcode aus dem Turorial mit dem die Tux Bitmap über den Bildschirm bewegen kann. Wenn ich jetzt noch eine zweite Bitmap als Hintergrund einfügen könnte, uiui das wär was. Ein tut wär natülich auch sehr schön.

    mfg Frusciante

    #include <stdlib.h>
    #include <SDL.h>
    
    #ifdef _WIN32
    #undef main
    #endif
    
    int main(int argc, char *argv[])
    {
        SDL_Surface *screen, *image;
    	SDL_Rect dst, dstblue;
        SDL_Event event;
    	Uint8 *keys;
    	int tuxX = 100, tuxY = 100;
        bool done = false;
        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, 255));    
        while(!done)
        {
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                    done = true;
                    break;
                }
            }
    		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;
    		dstblue.x = tuxX - 1;
    		dstblue.y = tuxY - 1;
    		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;
    }
    


  • Frusciante schrieb:

    Ich habe es mit Diversen guten Tutorials schon hinbekommen das man Bitmaps bewegt. Aber das bringt ja nichts da man ja keine zweite hintergrund Bitmap anzeigen kann, oder doch?

    IMHO kann man doch.

    Bye, TGGC (Reden wie die Großen)



  • Ich hab den Code jetzt so umgeändert, nur warum ist tux jetzt nicht mehr im Vordergrund? Kann ich irgendwie einstellen welche Bitmap im Vordergrund sein soll?

    mfg Frusciante

    #include <stdlib.h>
    #include <SDL.h>
    
    #ifdef _WIN32
    #undef main
    #endif
    
    int main(int argc, char *argv[])
    {
        SDL_Surface *screen, *image, *image2;
    	SDL_Rect dst, dstblue;
        SDL_Event event;
    	Uint8 *keys;
    	int tuxX = 100, tuxY = 100;
        bool done = false;
        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);
        }
    
    	image2 = SDL_LoadBMP("Map.bmp");                                     //LOADMAP
    	if(image2 == NULL)
    	{
    		printf("Can't load image of Map: %s\n", SDL_GetError());
    		exit(1);
    	}                                                                   //LOADBMP
        image = SDL_LoadBMP("tux.bmp");
        if(image == NULL)                                                   //LOADTUX
        {
            printf("Can't load image of tux: %s\n", SDL_GetError());
            exit(1);
        }	                                                                //LOADTUX
    	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, 255));    
        while(!done)
        {
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                    done = true;
                    break;
                }
            }
    		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;
    		dstblue.x = tuxX - 1;
    		dstblue.y = tuxY - 1;
    		SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_BlitSurface(image2, 0, screen, 0);
    		SDL_Flip(screen);
    
        }
        SDL_FreeSurface(image);
        return 0;
    }
    


  • Sortiere die Reihenfolge, in der die Objekte auf dem Screen auftauchen sollen.
    Background zuerst rendern, vordergrund als letztes.



  • Vielen danke, ich weiß was du meinst, aber ich hab noch 2 unbedeutende Fragen:
    Was heißt IMHO? Und ist Rendern der Deutsche ausdruck für Blit(t)en?

    mfg Frusciante



  • Juchuuuu ich habs geschafft. Ich such schon ewig nach einer Lösung wie ich einen Charakter auf eine Map bekomme und den dann auch bewegen kann und so, ich überhappy. HAtte immer schiss eins von TGGC draufzubekommen wenn ich frage ^^. Aber dann doch noch mal gleich ne frage bevor ich wieder ewig rumprobiere.
    Wenn mein charakter jetzt durch eine Tür geht und ich jetzt das innere des Hauses anzeigen möchte, blit ich dann einfach den char und den Hintergrund neu?

    mfg Frusciante



  • Frusciante schrieb:

    Vielen danke, ich weiß was du meinst, aber ich hab noch 2 unbedeutende Fragen:
    Was heißt IMHO? Und ist Rendern der Deutsche ausdruck für Blit(t)en?

    mfg Frusciante

    IMHO:
    http://www.google.de/search?q=what+the+fuck+is+imho&ie=UTF-8&hl=de&btnG=Google-Suche&meta=

    Rendern:
    Wird meist als "ich bring das mal auf den Schirm" benutzt, besonders von Gamecodern, ist aber eigentlich der eigentliche Prozess der Verarbeitung von Daten.



  • Ich hab jetzt mal versucht das wenn mein tux durch eine Tür geht eine zweite Map geöffnet wird und hab das so bewerkstelligt. Allerdings bekomm ich immer ienne Speicherfehler wenn ich das programm ausführe und durch die Tür gehe. Dort steht nichts genaues ausser das ein Fehler verursacht wird. Aber das ist doch richtig das ich hiermit den Speicher freigebe: SDL_FreeSurface(image2);
    oder?

    mfg Frusciante

    #include <stdlib.h>
    #include <SDL.h>
    
    #ifdef _WIN32
    #undef main
    #endif
    
    int main(int argc, char *argv[])
    {
        SDL_Surface *screen, *image, *image2, *image3;
    	SDL_Rect dst, dstblue;
        SDL_Event event;
    	Uint8 *keys;
    	int tuxX = 50, tuxY = 50 ;
        bool done = false;
        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);
        }
        image3 = SDL_LoadBMP("Map2.bmp");
    	if(image3 == NULL)
    	{
    		printf("Can't load image of tux: %s\n", SDL_GetError());
    		exit(1);
    	}
    	image2 = SDL_LoadBMP("Map.bmp");                                     //LOADMAP
    	if(image2 == NULL)
    	{
    		printf("Can't load image of Map: %s\n", SDL_GetError());
    		exit(1);
    	}                                                                   //LOADBMP
        image = SDL_LoadBMP("tux.bmp");
        if(image == NULL)                                                   //LOADTUX
        {
            printf("Can't load image of tux: %s\n", SDL_GetError());
            exit(1);
        }	                                                                //LOADTUX
    	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, 255));   
        while(!done)
        {
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                    done = true;
                    break;
                }
            }
    		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--;
    		}
    		if (tuxX == 100, tuxY == 220)
    		{
    			return 0;
    		}
    
    		dst.x = tuxX;
    		dst.y = tuxY;
    		dstblue.x = tuxX - 1;
    		dstblue.y = tuxY - 1;
    		SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
    		SDL_BlitSurface(image2, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    	    if (tuxX == 250, tuxY == 10)
    		{
    		SDL_FreeSurface(image2);
            SDL_BlitSurface(image3, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    		}
    
        }
        SDL_FreeSurface(image);
        return 0;
    }
    


  • Frusciante schrieb:

    Ich hab jetzt mal versucht das wenn mein tux durch eine Tür geht eine zweite Map geöffnet wird und hab das so bewerkstelligt. Allerdings bekomm ich immer ienne Speicherfehler wenn ich das programm ausführe und durch die Tür gehe. Dort steht nichts genaues ausser das ein Fehler verursacht wird. Aber das ist doch richtig das ich hiermit den Speicher freigebe: SDL_FreeSurface(image2);
    oder?

    Ja - SDL_FreeSurface ist richtig, aber schau dir mal das Stueck Code an, mal sehen ob dir etwas auffaellt:

    Frusciante schrieb:

    while(!done)
        {
    /** cut */
    		SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
    		SDL_BlitSurface(image2, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    	    if (tuxX == 250, tuxY == 10)
    		{
    		SDL_FreeSurface(image2);
            SDL_BlitSurface(image3, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    		}
    }
    

    Was passiert, in der naechsten Loop, wenn du das image2 schon geloescht hast?

    .
    .
    .
    .
    .
    . /** Spoiler */
    .
    .
    .
    .
    .

    Richtig - benutzt das Objekt wieder und zwar hier:

    SDL_BlitSurface(image2, 0, screen, 0);
    

    Wenn ich mich nicht taesche, sollte man kein Objekt nutzen, das schon freigebeben ist 😃



  • SnorreDev schrieb:

    Wenn ich mich nicht taesche, sollte man kein Objekt nutzen, das schon freigebeben ist

    Und auch wenn du dich täscht, sollte man kein Objekt nutzen, das schon freigebeben ist.

    Bye, TGGC (Zu viele Primitive hier.)



  • TGGC schrieb:

    SnorreDev schrieb:

    Wenn ich mich nicht taesche, sollte man kein Objekt nutzen, das schon freigebeben ist

    Und auch wenn du dich täscht, sollte man kein Objekt nutzen, das schon freigebeben ist.

    Bye, TGGC (Zu viele Primitive hier.)

    Ok - habs gesehen! Ich dachte immer ich kann nicht rechtschreiben, jetzt klappt schon das tippen nicht mehr 🙄



  • Das sollte ich ja relativ leicht lösen indem ich noch eine if anweisung einbaue damit das Bild nicht wieder geblittet wird. Allerdings bin ich der Meinung das ich das vorhin schon ausprobiert habe und auch dann ne Fehlermeldung bekomme hab. Mal sehen...
    mfg Frusciante



  • Da ich gemerkt hab dass das alles nicht so funzt wie ich mir das vorgestellt hab, hab ich jetzt versucht das mit eine Variable namens var zu reglen. Allerdings hab ich jetzt einen Fehler den ich mir allen ernstes nicht erklären kann.

    mfg Frusciante

    #include <stdlib.h>
    #include <SDL.h>
    
    #ifdef _WIN32
    #undef main
    #endif
    
    int var = 0;
    
    int main(int argc, char *argv[])
    {
        SDL_Surface *screen, *image, *image2, *image3;
    	SDL_Rect dst, dstblue;
        SDL_Event event;
    	Uint8 *keys;
    	int tuxX = 50, tuxY = 50 ;
        bool done = false;
        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);
        }
        image3 = SDL_LoadBMP("Map2.bmp");
    	if(image3 == NULL)
    	{
    		printf("Can't load image of tux: %s\n", SDL_GetError());
    		exit(1);
    	}
    	image2 = SDL_LoadBMP("Map.bmp");                                     //LOADMAP
    	if(image2 == NULL)
    	{
    		printf("Can't load image of Map: %s\n", SDL_GetError());
    		exit(1);
    	}                                                                   //LOADBMP
        image = SDL_LoadBMP("tux.bmp");
        if(image == NULL)                                                   //LOADTUX
        {
            printf("Can't load image of tux: %s\n", SDL_GetError());
            exit(1);
        }	                                                                //LOADTUX
    	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, 255));   
        while(!done)
        {
            while(SDL_PollEvent(&event))
            {
                switch(event.type)
                {
                    case SDL_QUIT:
                    done = true;
                    break;
                }
            }
    		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;
    		dstblue.x = tuxX - 1;
    		dstblue.y = tuxY - 1;
    		SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
    		if (var == 0)
    		{
    		SDL_BlitSurface(image2, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    		}
    	    if (tuxX == 250, tuxY == 10)
    		{
    			var = 2;
    				if (var == 2)
    				{
    		SDL_FreeSurface(image2);
            SDL_BlitSurface(image3, 0, screen, 0);
    		SDL_BlitSurface(image, NULL, screen, &dst);
    		SDL_Flip(screen);
    		}
    		}
    
        }
        SDL_FreeSurface(image);
        return 0;
    }
    


  • und was für einen fehler bitteschön? meine tarrot karten haben grad nen marder schaden 😉



  • Meine Tarot Karten sagen mir, dass man auch ein Surface, was schon einmal freigegeben wurde nicht noch ein zweites mal freigeben kann!
    Ich wuerde dieses Surface NULLen, und dann auch noch ueberpruefen in der Loop, ob es denn noch existiert.



  • ups *lol*
    So was passiert mir öffters ^^
    Ich kann meinen tux nicht mehr bewegen wenn ich auf der nächsten Map bin.
    Nur so ein bisschen nach links und rechts, sehr merkwürdig. Liegt das daran das ich das image bei jedem schleifendurchlauf wieder freigebe das ja gar nicht mehr existiert?



  • Immer schön aufpassen beim Freigeben, egal wie man es nun tippt. 😎

    Bye, TGGC (Zu viele Primitive hier.)



  • So müsste die Überpfüfung doch richtig sein, oder? Wenn es erst genullt wurde und ich dann überprüfe ob das bild größer als 0 ist. Kann Tux aber leider immernoch nicht auf der zweiten map bewegen 😞

    if (image2 > 0)
    					{
    		SDL_FreeSurface(image2);
    					}
    

    Oder liegt das vieleicht da dran:

    [cpp]
    if(keys[SDLK_DOWN])
    {
    if(tuxY < 470 - image->h)
    tuxY++;
    }
    if(keys[SDLK_RIGHT])
    {
    if(tuxX < 630 - image->w)
    tuxX++;
    }
    [/cpp]

    mfg Frusciante



  • wie waers wenn du's dir ganz einfach machst und die Surface erst wieder released, sobald der Dtor aufgerufen wird? 🙂

    Dann musst du nur ueberpruefen, auf welcher Hintergrunds-Surface du gerade bist, und kannst dir die ganzen anderen Pruefungen sparen 🙂



  • Hm, das versteh ich nicht. Was ist der Dtor?


Anmelden zum Antworten