Advertisement

SDL Image Management

Started by February 09, 2003 08:36 PM
5 comments, last by elendil67 21 years, 9 months ago
Hi. In a simple SDL game of mine, I am trying to make a function to move the sprite along an axis for a desired length. The only thing that is not working is that when I try and get the bitmap's width and height and store it in a rectangle, it does not work.
    
// Declare a sprite class

struct t_sprite
{
	SDL_Surface *image;                                                 // The surface for the sprite

	SDL_Rect     rect;                                                  // The sprite's rectangle

};

// A function to load an image onto the sprite

void load_sprite(t_sprite *sprite, char *file)
{
    // Load the bitmap onto the sprite

    sprite->image = SDL_LoadBMP(file);
    if ( sprite->image == NULL ) 
	{
        fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
        return;
    }

    // Initialize the sprite's rect

    sprite->rect.x = 0;
    sprite->rect.y = 0;
    sprite->rect.w = sprite->image->w;
    sprite->rect.h = sprite->image->h;
}

// A function to move the sprite

void move_sprite(t_sprite *sprite, int x, int y)
{
    // If the sprite is within the width boundaries, move the sprite 

    // If the sprite is not on the left edge

    if(sprite->rect.x >= 0)
    {
        // If the sprite is not on the right edge

        if((sprite->rect.x + sprite->rect.w) <= 800)
        {
            // Move the sprite to the desired position

            sprite->rect.x = sprite->rect.x + x;
        }
        // If the sprite is on the right edge

        else
        {
            // Move the sprite just left of the right edge

            sprite->rect.x = (600 - sprite->rect.w);
        }
    }
    // If the sprite is on the left edge

    else
    {
        // Move the sprite just right of the left edge

        sprite->rect.x = 1;
    }
}
    
That is all I think that I need to post. For some reason sprite->rect.w/h is not picking up sprite->image.w/h in load_sprite(). Do you know what I am doing wrong here? Thanks! [edited by - elendil67 on February 9, 2003 9:38:34 PM]
When you go homeTell them of us, and say:For your tomorrow,We gave our today.
Hi,

I had a quick play with your functions and managed to get them to work.

If you are using straight C you might want use typedef on your structure. When I compiled this I had to add had to add struct before t_sprite in every place the structure was declared (you don’t need to do this in C++).

Anyway here’s my main function to test load_sprite and move_sprite.

  int main(int argc, char* argv[]){	SDL_Surface *MainSurface;	t_sprite Sprite;	SDL_Event event;	char bQuit = 0;	SDL_Init(SDL_INIT_VIDEO);	MainSurface = SDL_SetVideoMode (800, 600, 0, SDL_ANYFORMAT);	load_sprite(&Sprite, "ckRedBall.bmp");	while(!bQuit)	{	        move_sprite(&Sprite, 5, 0);		SDL_BlitSurface(Sprite.image, NULL, MainSurface, &Sprite.rect);		SDL_UpdateRect(MainSurface, 0, 0, 0, 0);		// main message loop		if( SDL_PollEvent(&event) )		{			if(event.type == SDL_QUIT)			{				bQuit = 1;			}		}		SDL_Delay(200);	}	SDL_Quit();}  


Cheers.

Advertisement
Thanks. I am using a C++ compiler by the way. I do not see how your modifications made it work. Do you think the bitmap header is corrupted or something? Here is the 32k zip file with the source, the bitmaps, and the exe.

Thanks!
When you go homeTell them of us, and say:For your tomorrow,We gave our today.
Hi,

Are you still having trouble getting it to work?

There seems to be no problem with your source but I think I’m using a different compiler than you (I guess your using VC++, I’m using GCC). You might want to try swapping your #pragma statements around, when linking with GCC I have to specify "SDLMain" before "SDL", the order of the libaries specified is important when linking to SDL but this might be a compiler specific thing.

Your executable seemed to work fine on my machine as well and I don’t think there is anything wrong with the bitmaps because I can open them up fine using a paint program.

If it’s still not behaving you might want to check that your system is correctly setup and failing that step through the whole program.

Also just to clarify on the typedef thing, if you were using straight C and you wanted to declare an instance of a structure of “t_sprite” called “background” you would have to use “struct t_sprite background;”. If you are using C++ you can just use “t_sprite background;”. It’s one of those subtle differences between C and C++. If you wanted to convert your source from C++ to C the only change required would be adding typedef in your definition of t_sprite i.e.

  typedef struct image_rect{	SDL_Surface *image; 	SDL_Rect     rect; } t_sprite;  

This would save you going through your whole source and adding struct wherever t_sprite appears. But you are not using C you are using C++, you do not need to use typedef on t_sprite nor do you need to add struct before t_sprite when declaring an instance of the structure. I saw that this is what you had done in your source and I might have lead you astray.

However if you do want to program your game in C++ then I would recommend that you use a class for your sprites instead of a structure.

Hope that’s of help.

Thanks for the C-C++ portability stuff. I just added that in there because I will be using GCC very soon (once I finish my fifth reinstallation of Debian). This is really weird. Does this work abnormally on anyone elses machine? When you say it works fine on yours you mean that when you hit the screen border the ''plane'' is not allowed to go past the screen, right? But it still can go the other way, right?

Thanks!
When you go homeTell them of us, and say:For your tomorrow,We gave our today.
No, in that case it does not work fine on my machine, when I was talking about the program not working I thought you meant either it wouldn’t start at all or that the ‘plane’ would not move. On my machine the ‘plane’ moves off screen when it is moved to the right or down the bottom. Looking at move_sprite it should not be doing this.

It would appear that SDL_BlitSurface modifies the destination rect (which in your case also is the same rect that contains the position and size for your player/plane) when bliting a surface that is being clipped.

Replace
 if((sprite->rect.x + sprite->rect.w) <= 800)  
with
 if((sprite->rect.x + sprite->image->w) <= 800)  
and you should be laughing.

Cheers.


[edited by - KiwiMelon on February 11, 2003 2:11:59 AM]
Advertisement
WUAHHAHAHHAHAHH!!!!!!!!!!

THanks so much man!
When you go homeTell them of us, and say:For your tomorrow,We gave our today.

This topic is closed to new replies.

Advertisement