Sign in to follow this  
ukdeveloper

Clip blitting from spritesheet [SDL]

Recommended Posts

Hi all, I'm working on a simple card game using SDL. I've got a spritesheet which can be found here. I am creating a separate CCard object to represent each card in a pack of cards. I've had this working textually before but am rewriting the game graphically with SDL. I'm using LazyFoo's clip blitting tutorial as reference, but the code there uses the co-ordinates from a clip frame to blit on the fly. What I'm trying to do is to take a "snapshot" using the clipping frame, and storing what's inside the frame in a SDL_Surface variable inside my CCard class, that is to say each CCard object has the surface preassigned with the correct image to be blitted instead of storing the co-ordinates and blitting on the fly. Here's the code I've got right now:
for(col_for_card = 0; col_for_card < 13; col_for_card++)
			{

				SDL_Surface* tempSurface;
				SDL_Rect frame[4];

				// Top left
				frame[0].x  = curX;
				frame[0].y = curY;
				frame[0].w = cardWidth;
				frame[0].h = cardHeight;

				// Top right
				frame[1].x = (curX + cardWidth) ;
				frame[1].y = cardHeight;
				frame[1].w = cardWidth;
				frame[1].h = cardHeight;

				// Bottom left
				frame[2].x = curX;
				frame[2].y = (curY + cardHeight);
				frame[2].w = cardWidth;
				frame[2].h = cardHeight;

				// Bottom right
				frame[3].x = (curX + cardWidth);
				frame[3].y = (curY + cardHeight);
				frame[3].w = cardWidth;
				frame[3].h = cardHeight;

				CCard* tempCard = new CCard();

				// Blows up when we try to assign the SDL_Rect to tempSurface which is then assigned in turn to the local SDL_Surface inside the new CCard object
				// Line removed for now

				curX += cardWidth+2;
			}
			std::cout<<std::endl;
			curX = 1;
			curY += cardHeight+2;
		}

Two main questions: 1) Do you think this is a good way of doing it? My theory is that it would be just easier to store the clipped sprite as I'm trying to do. 2) More importantly, is there an easy way of doing it? I've looked at the SDL documentation and there doesn't seem to be an obvious built in function for doing this, and I'm not sure how to assign the SDL_Rect to the SDL_Surface. Hopefully what I'm trying to do is possible :S TIA, ukd.

Share this post


Link to post
Share on other sites
I assume you want to turn the sprite sheet into a db of sprites? I would create a class to contain an SDL_Surface, and some data pertaining to the use of that image (e.g. color key, or whatever). Then I would size the SDL_Surface to the exact dimensions of the sprite. Finally, I would create an std::map of these classes and treat it as a crude database.
Don't forget to set the format of the smaller surface to that of the surface it will be blitted onto for a further speed boost.

Oh yeah, the SDL_Rect is a way of storing a rectangle. (ahem) what I mean to say is, the surface can be of any size, but a rectangle allows you to select a certain area of that surface to be used in a blit.

Share this post


Link to post
Share on other sites
Quote:
Original post by shotgunnutter
I assume you want to turn the sprite sheet into a db of sprites? I would create a class to contain an SDL_Surface, and some data pertaining to the use of that image (e.g. color key, or whatever). Then I would size the SDL_Surface to the exact dimensions of the sprite. Finally, I would create an std::map of these classes and treat it as a crude database.
Don't forget to set the format of the smaller surface to that of the surface it will be blitted onto for a further speed boost.

Oh yeah, the SDL_Rect is a way of storing a rectangle. (ahem) what I mean to say is, the surface can be of any size, but a rectangle allows you to select a certain area of that surface to be used in a blit.


Thanks for your suggestions which I'll hold onto in case I can't get my own solution working, but I apologise as in retrospect I didn't quite explain myself properly.

What I'm trying to achieve with the clip blitting is to select a specific area of the sprite sheet, like I've said. That'll give me a rectangle, snapping round said specific area like the Ace of Diamonds.

I then want to take the rectangle's contents and assign them to the SDL_Surface inside my CCard class, which is shown below:


#pragma once
#include <SDL/SDL.h>
#include <iostream>
#include <string>

class CCard
{
public:
CCard(void /* Decide on parameters slightly later */);
~CCard(void);
std::string returnSuit();
int returnRank();
void setSuit(std::string suit);
void setRank(int rank);
SDL_Surface* cardGraphic;

private:
std::string cardSuit;
int cardRank;
};



That way, the cardGraphic would be assigned with the contents of the rectangle on the sprite sheet (the Ace of Diamonds, for example). It's public instead of private right now as part of a dirty hack; I'll likely get round to making it private again and putting in a vaguely elegant means of accessing it.

The idea is that I could blit this surface later on when a specific card is used and requires to be shown on screen. I plan to do this for the entire deck and create a separate CCard object for each, with cardGraphic containing a "snapshot" or effectively a copy of what's inside the clipping rectangle for each card. The algorithm I've written for selecting the right areas of my sprite sheet works as I've had it spit out its current co-ordinates textually and I've checked them against the image, so it knows where to look.

Is this even possible? I assume to do this would require a temporary SDL_Surface created from the contents of the SDL_Rect, and then that SDL_Surface is assigned to the one inside the CCard object. You can see I've had a basic stab at it, but I'm not so sure where to go next.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this