I just keep running into problems...
Anyway, the class I created to load and draw sprites in my program (using SDL) isn't working!
I create a sprite object and I can display it just fine. I can set a transparent color, and animate images using a strip.
Here's the problem: if I
ever create more than one sprite object, the program crashes!
Actually, if I create another
empty sprite object (default constructor with no arguments), then the program runs, but it doesn't exit properly; it crashes! Another thing I realized is that, for some reason, if my destructor isn't declared virtual, then I can't create any sprite objects without the program immediately crashing! Please help!
Here's the code for the class. (I hope I post the code correctly. :-P )
SPRITE.H
#ifndef SPRITE_H
#define SPRITE_H
#include<SDL/SDL.h>
#define UINT unsigned short int
class sprite
{
protected:
SDL_Surface* m_psfImage; //image surface
SDL_Color m_cColorKey; //transparent color key
Uint8 m_cAlpha; //alpha channel
SDL_Rect m_rBndBox; //sprite bounding box
UINT m_iNumFrms; //number of frames in the image
UINT m_iFrmWidth; //width of each frame
UINT m_iCurrentFrm; //the current frame to display
void LoadFile( char* szFName );
void ApplyColorKey( SDL_Color cCol );
void ApplyAlpha( Uint8 iA );
public:
sprite();
sprite( char* szFName );
sprite( char* szFName, UINT iNFrms, UINT iFrmW);
//sprite( const sprite& rhs );
virtual ~sprite();
void NextFrame( UINT iRate = 1 );
void Draw( SDL_Surface* sfDest, int iLocX, int iLocY );
void Reload( char* szFName );
void Reload( char* szFName, UINT iNFrms, UINT iFrmW );
void SetColorKey( SDL_Color cCol );
void SetColorKey( UINT iR, UINT iG, UINT iB );
void SetAlpha( UINT iA );
void SetCurrentFrame( UINT iCFrm ) { m_iCurrentFrm = iCFrm; }
void SetNumFrames( UINT iNFrms ) { m_iNumFrms = iNFrms; }
//void SetFrameWidth( UINT iFrmW ) { m_iFrmWidth = iFrmW; }
SDL_Rect GetBoundBox() const { return m_rBndBox; }
SDL_Surface* GetSurface() const { return m_psfImage; }
SDL_Color GetColorKey() const { return m_cColorKey; }
UINT GetCurrentFrame() const { return m_iCurrentFrm; }
UINT GetNumFrames() const { return m_iNumFrms; }
UINT GetFrameWidth() const { return m_iFrmWidth; }
//static void NextFrame( UINT iRate = 1 );
};
#endif
SPRITE.CPP
#include <SDL/SDL.h>
#include <SDL/SDL_Image.h>
#include "sprite.h"
sprite::sprite()
{
}
sprite::sprite( char* szFName )
{
sprite::LoadFile( szFName );
m_iNumFrms = 1;
m_iFrmWidth = m_psfImage->w;
m_iCurrentFrm = 0;
m_rBndBox.x = 0;
m_rBndBox.y = 0;
m_rBndBox.w = m_iFrmWidth;
m_rBndBox.h = m_psfImage->h;
}
sprite::sprite( char* szFName, UINT iNFrms, UINT iFrmW )
{
sprite::LoadFile( szFName );
m_iNumFrms = iNFrms;
m_iFrmWidth = iFrmW;
m_iCurrentFrm = 0;
m_rBndBox.x = 0;
m_rBndBox.y = 0;
m_rBndBox.w = m_iFrmWidth;
m_rBndBox.h = m_psfImage->h;
}
/*
sprite::sprite( const sprite& rhs )
{
if ( &rhs == this )
{
return;
}
//...
}
*/
sprite::~sprite()
{
if ( m_psfImage == NULL )
{
return;
}
SDL_SetColorKey( m_psfImage, 0, 0 );
SDL_FreeSurface( m_psfImage );
m_psfImage = NULL;
}
void sprite::LoadFile( char* szFName )
{
if ( m_psfImage != NULL )
{
SDL_FreeSurface( m_psfImage );
}
SDL_Surface* psfTemp = IMG_Load( szFName );
if ( psfTemp == NULL )
{
return;
}
m_psfImage = SDL_DisplayFormat( psfTemp );
if ( m_psfImage == NULL )
{
SDL_FreeSurface( psfTemp );
return;
}
SDL_FreeSurface( psfTemp );
return;
}
void sprite::Reload( char* szFName )
{
sprite::LoadFile( szFName );
m_iNumFrms = 1;
m_iFrmWidth = m_psfImage->w;
m_iCurrentFrm = 0;
m_rBndBox.x = 0;
m_rBndBox.y = 0;
m_rBndBox.w = m_iFrmWidth;
m_rBndBox.h = m_psfImage->h;
return;
}
void sprite::Reload( char* szFName, UINT iNFrms, UINT iFrmW )
{
sprite::LoadFile( szFName );
m_iNumFrms = iNFrms;
m_iFrmWidth = iFrmW;
m_iCurrentFrm = 0;
m_rBndBox.x = 0;
m_rBndBox.y = 0;
m_rBndBox.w = m_iFrmWidth;
m_rBndBox.h = m_psfImage->h;
return;
}
void sprite::ApplyColorKey( SDL_Color cCol )
{
if (
SDL_SetColorKey(
m_psfImage,
SDL_SRCCOLORKEY,
SDL_MapRGB( m_psfImage->format, cCol.r, cCol.g, cCol.b )
)
< 0 )
{
return;
}
return;
}
void sprite::ApplyAlpha( Uint8 iA )
{
if (
SDL_SetAlpha(
m_psfImage,
SDL_SRCALPHA | SDL_RLEACCEL,
iA
)
< 0 )
{
return;
}
return;
}
void sprite::SetColorKey( SDL_Color cCol )
{
m_cColorKey = cCol;
sprite::ApplyColorKey( m_cColorKey );
}
void sprite::SetColorKey( UINT iR, UINT iG, UINT iB )
{
if ( iR > 255 ) { iR = 255; }
if ( iG > 255 ) { iG = 255; }
if ( iB > 255 ) { iB = 255; }
m_cColorKey.r = (Uint8)iR;
m_cColorKey.g = (Uint8)iG;
m_cColorKey.b = (Uint8)iB;
sprite::ApplyColorKey( m_cColorKey );
return;
}
void sprite::SetAlpha( UINT iA )
{
m_cAlpha = (Uint8)iA;
sprite::ApplyAlpha( m_cAlpha );
return;
}
void sprite::NextFrame( UINT iRate )
{
m_iCurrentFrm += iRate;
if ( m_iCurrentFrm >= m_iNumFrms )
{
m_iCurrentFrm = 0 + ( m_iCurrentFrm - m_iNumFrms );
}
return;
}
void sprite::Draw( SDL_Surface* psfDest, int iLocX, int iLocY )
{
if ( psfDest == NULL )
{
return;
}
SDL_Rect rSrcBox;
rSrcBox.x = (int)( m_iCurrentFrm * m_iFrmWidth );
rSrcBox.y = 0;
rSrcBox.w = (int)( m_iFrmWidth );
rSrcBox.h = m_psfImage->h;
SDL_Rect rDstBox;
rDstBox.x = iLocX;
rDstBox.y = iLocY;
rDstBox.w = rSrcBox.w;
rDstBox.h = rSrcBox.h;
SDL_BlitSurface( m_psfImage, &rSrcBox, psfDest, &rDstBox );
return;
}
At the moment, this class is missing a lot of functionality that I want to add... but I can't see why it's not working. :-( Does anyone see anything here that I've done wrong?