SDL Sprite Sheet

Opinions on my sprite sheet function

  • (2 Pages)
  • +
  • 1
  • 2

22 Replies - 10546 Views - Last Post: 08 July 2010 - 05:51 AM Rate Topic: -----

#16 Guest_ZOMBIE!!!*


Reputation:

Re: SDL Sprite Sheet

Posted 06 July 2010 - 12:07 PM

View Poststayscrisp, on 06 July 2010 - 06:29 AM, said:

The problem is still in your loadFrame function, instead of returning -1 for everything you should return a message so you can see where the problem is. I still don't understand the approach you are taking, can you explain the logic behind your load frame function?

The way I described would not need to know the x and y coordinates of the sprite sheet frame, it only needs to know the height and width of each part of the sprite sheet. You could then pass the maximum number of frames and the row or column you want to loop through.

pseudo code
Walk Button Pressed ()
{
    Player->Animate(8,1); // the walk loop has 8 frames and is in the first column of the sprite sheet
}

Attack Button Pressed ()
{
    Player->Animate(3,2); // the attack loop has 3 frames and is in the second column of the sprite sheet
}



This is what you might want to achieve. I can give you a few more pointers if you need them but I would have a good rethink about your load frame function and try to logically step through it, as it seems to be messing with your code.



I am showing errors through "cerr" not by return value. -1 just means that something went wrong, when that happens you open cerr.txt and see what went wrong.


The logic behind loadFrame() is that it opens a sprite sheet and takes one frame from the spritesheet that you pass through and returns it. This is going to be used for animating the sprite.

You passed X and Y src and dest coordinates through the function did you not?
bool DrawPartOfImage(SDL_Surface* dest, SDL_Surface* src, int x, int y, int x2, int y2, int width, int height) {

As far as your psuedo code, I plan on doing something like that with an animation function which will use this loadFrame function.
Was This Post Helpful? 0

#17 Guest_ZOMBIE!!!*


Reputation:

Re: SDL Sprite Sheet

Posted 06 July 2010 - 12:09 PM

View PostFib, on 06 July 2010 - 05:22 AM, said:

Try giving the complete path to your SpriteSheet.bmp and see if that works.

For example:
SpriteSheet = SDL_LoadBMP("c:\\game\\graphics\\SpriteSheet.bmp");


Just replace the string with the path to your SpriteSheet.bmp. Don't forget to use the double slashes (\\) in your path.

If that doesn't work... well then I don't know.


Alright, I'll give that a shot.
Was This Post Helpful? 0

#18 ZOMBIE!!!  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 206
  • Joined: 28-October 09

Re: SDL Sprite Sheet

Posted 06 July 2010 - 12:19 PM

View PostZOMBIE!!!, on 06 July 2010 - 11:09 AM, said:

View PostFib, on 06 July 2010 - 05:22 AM, said:

Try giving the complete path to your SpriteSheet.bmp and see if that works.

For example:
SpriteSheet = SDL_LoadBMP("c:\\game\\graphics\\SpriteSheet.bmp");


Just replace the string with the path to your SpriteSheet.bmp. Don't forget to use the double slashes (\\) in your path.

If that doesn't work... well then I don't know.


Alright, I'll give that a shot.


Didn't work :no:

Thanks for trying though
Was This Post Helpful? 0
  • +
  • -

#19 Guest_ghillieLEAD*


Reputation:

Re: SDL Sprite Sheet

Posted 07 July 2010 - 10:55 AM

This isn't specific to your project, just SDL related, but I personally think it is better to handle the SDL init and quit like this:

if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
    // Error message
    exit(1);
}
// handle shutting down SDL now
atexit(SDL_Quit);
// the rest or your program



The benefit here is you can have checks later in the program and if you get that cursed -1 back from SDL you can call exit(1) and not have to worry about shutting down SDL. Also you really don't need to initialize everything, a simple
SDL_Init(SDL_INIT_VIDEO);
would sufice. If you need more subsystems you could go about it this way
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
or you could always call
SDL_InitSubSystem(...);
after you use
SDL_Init(...);
I personally think this helps keep things simpler.
Was This Post Helpful? 0

#20 ghillieLEAD  Icon User is offline

  • D.I.C Head

Reputation: 31
  • View blog
  • Posts: 208
  • Joined: 08-March 10

Re: SDL Sprite Sheet

Posted 07 July 2010 - 03:25 PM

I forgot to add that when you check for any errors when you attempt to initialize SDL or create the main surface or whatever, just knowing that there was an error really isn't very helpful. you might as well go the extra yard and figure out what went wrong.
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
    fprintf(stderr, SDL_GetError());
    exit(1);
}


Was This Post Helpful? 1
  • +
  • -

#21 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: SDL Sprite Sheet

Posted 07 July 2010 - 04:49 PM

Here is what I meant by using the function I gave you, this is just to get an idea. You will notice that I did not have to pass in the X and Y of the frame I want to draw as I increment by the sprite height each time.

#include "SDL.h"
#include <string>
#include <iostream>
using namespace std;

// These should be part of a class when you get to that point
int CurrentFrame = 0;
int SpriteColumn = 1;
int SpriteRow = 0;
int SpriteWidth = -64;
int SpriteHeight = 64;
int MaxFrames = 8;

// Added bool for main loop so you don't have to use SDL_Delay to keep the window open
bool running;

// Loads a surface from BMP
SDL_Surface* LoadPlayer(const char* File)
{
	SDL_Surface* temp = NULL;
	SDL_Surface* optimized = NULL;

	if((temp = SDL_LoadBMP(File)) == NULL)
	{
		return NULL;
	}

	optimized = SDL_DisplayFormatAlpha(temp);
	SDL_FreeSurface(temp);

	return optimized;
}

// Draw the player, this will only be a single frame
bool DrawPlayer(SDL_Surface* dest, SDL_Surface* src, int x, int y, int x2, int y2, int width, int height)
{
	SDL_Rect destR;

	destR.x = x;
	destR.y = x;

	SDL_Rect srcR;

	srcR.x = x2;
	srcR.y = y2;
	srcR.w = width;
	srcR.h = height;

	SDL_BlitSurface(src, &srcR, dest, &destR);

	return true;
}

int main(int args, char* argv[])
{
	cout<<"Initializing SDL..."<<endl;
	if(SDL_Init(SDL_INIT_EVERYTHING)== -1){
		cerr<<"ERROR IN INITIALIZING SDL"<<endl;
		return -1;
	}

	// Make running true
	running = true;

	SDL_Surface* Screen = NULL;

	Screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
	
	SDL_Surface* player;
	player = LoadPlayer("yoshi.bmp");

	while(running)
	{
		DrawPlayer(Screen,player, 100, 100, SpriteColumn * SpriteWidth, 
			(SpriteRow + CurrentFrame) * SpriteHeight, SpriteWidth, SpriteHeight);

		if(CurrentFrame <= MaxFrames)
		{
			SDL_Delay(100);
			CurrentFrame += 1;
		}
		else if(CurrentFrame >= MaxFrames)
		{
			CurrentFrame = 1;
		}
		SDL_Flip(Screen);
	}

	cout<<endl<<endl<<"Quitting SDL..."<<endl;

	SDL_Quit();

	return 0;
}



Here is the sprite sheet I used for this example
Attached File  yoshi.bmp (32.12K)
Number of downloads: 116

This program increments the current frame and uses SDL_Delay as you do not have a timer implemented, if you wanted to move to another animation loop then you could just change the current column and loop through that.
Was This Post Helpful? 0
  • +
  • -

#22 ZOMBIE!!!  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 206
  • Joined: 28-October 09

Re: SDL Sprite Sheet

Posted 07 July 2010 - 05:44 PM

View Poststayscrisp, on 07 July 2010 - 03:49 PM, said:

Here is what I meant by using the function I gave you, this is just to get an idea. You will notice that I did not have to pass in the X and Y of the frame I want to draw as I increment by the sprite height each time.

#include "SDL.h"
#include <string>
#include <iostream>
using namespace std;

// These should be part of a class when you get to that point
int CurrentFrame = 0;
int SpriteColumn = 1;
int SpriteRow = 0;
int SpriteWidth = -64;
int SpriteHeight = 64;
int MaxFrames = 8;

// Added bool for main loop so you don't have to use SDL_Delay to keep the window open
bool running;

// Loads a surface from BMP
SDL_Surface* LoadPlayer(const char* File)
{
	SDL_Surface* temp = NULL;
	SDL_Surface* optimized = NULL;

	if((temp = SDL_LoadBMP(File)) == NULL)
	{
		return NULL;
	}

	optimized = SDL_DisplayFormatAlpha(temp);
	SDL_FreeSurface(temp);

	return optimized;
}

// Draw the player, this will only be a single frame
bool DrawPlayer(SDL_Surface* dest, SDL_Surface* src, int x, int y, int x2, int y2, int width, int height)
{
	SDL_Rect destR;

	destR.x = x;
	destR.y = x;

	SDL_Rect srcR;

	srcR.x = x2;
	srcR.y = y2;
	srcR.w = width;
	srcR.h = height;

	SDL_BlitSurface(src, &srcR, dest, &destR);

	return true;
}

int main(int args, char* argv[])
{
	cout<<"Initializing SDL..."<<endl;
	if(SDL_Init(SDL_INIT_EVERYTHING)== -1){
		cerr<<"ERROR IN INITIALIZING SDL"<<endl;
		return -1;
	}

	// Make running true
	running = true;

	SDL_Surface* Screen = NULL;

	Screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
	
	SDL_Surface* player;
	player = LoadPlayer("yoshi.bmp");

	while(running)
	{
		DrawPlayer(Screen,player, 100, 100, SpriteColumn * SpriteWidth, 
			(SpriteRow + CurrentFrame) * SpriteHeight, SpriteWidth, SpriteHeight);

		if(CurrentFrame <= MaxFrames)
		{
			SDL_Delay(100);
			CurrentFrame += 1;
		}
		else if(CurrentFrame >= MaxFrames)
		{
			CurrentFrame = 1;
		}
		SDL_Flip(Screen);
	}

	cout<<endl<<endl<<"Quitting SDL..."<<endl;

	SDL_Quit();

	return 0;
}



Here is the sprite sheet I used for this example
Attachment yoshi.bmp

This program increments the current frame and uses SDL_Delay as you do not have a timer implemented, if you wanted to move to another animation loop then you could just change the current column and loop through that.



I understand what you mean, I just wanted it to be simpler to call the function. Instead of:


DrawPlayer(Screen,player, 100, 100,SpriteColumn * SpriteWidth,(SpriteRow + CurrentFrame) * SpriteHeight, SpriteWidth, SpriteHeight);





I'd rather have something like this(keep in mind, the draw function hasn't been made yet:

SDL_Surface* Frame = loadFrame(SpriteSheet, Frame, SpriteX, SpriteY, SheetX, SheetY, FrameNum);


Was This Post Helpful? 0
  • +
  • -

#23 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1000
  • View blog
  • Posts: 4,181
  • Joined: 14-February 08

Re: SDL Sprite Sheet

Posted 08 July 2010 - 05:51 AM

Sorry I don't mean to change your code and your idea but I honestly think that the way you want to do it will be a lot more work than you think.

You want to return an SDL_Surface* created from taking another SDL_Surface*, finding a specific part of it and then returning it as an SDL_Surface*. So your function will need to have a way of finding the frame you want from the values you pass in and then convert those values into an SDL_Surface* and return it. What about when you want to create an animation? will you need to call this function on every frame you want to use?

This will be much easier to achieve by using the SDL blitsurface method.

Good luck with your project
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2