In my last project I designed a sprite class but it was messy. This time I want to design a sprite class which can be a base class to other ojects.
Sprite.h
#ifndef SPRITE_H
#define SPRITE_H
#include "SDL/SDL.h"
//contains functions that deal with collision
#include "mySDLfunctions.h"
class Sprite
{
public:
Sprite(Sint16 x, Sint16 y, SDL_Surface *image); // constructor
Sprite(SDL_Surface *image); // constructor (x and y are set to 0)
Sprite(Sprite &spr); // copy constructor
Sprite& operator = (Sprite &spr); // assignment operator
~Sprite(); // destructor
SDL_Surface *image(); // returns a pointer to the sprite's image
SDL_Rect rect() const; // returns a copy of the rectangle holding x, y, w, h
// collision functions
bool collidesWith(const SDL_Rect &rect) const; // returns true if there's a collision with an SDL_Rect
virtual bool collidesWith(const Sprite &spr) const; // returns true on collision with Sprite object. Made virtual to be overrideen
Sint16 x() const;
Sint16 y() const;
Uint16 w() const;
Uint16 h() const;
protected:
SDL_Rect offset; // holds x, y, w and h
private:
SDL_Surface *img; // pointer to the sprite's image
};
#endif // SPRITE_H
So I have my own destructor, copy constructor and assignment operator because I have an SDL_Surface * struct which is stored on the heap and its memory must be freed.
I created two constructors to add some flexibility (a pointer to an SDL_Surface is always required though, it can't be set later).
collision functions
bool
collidesWith is overloaded. The arguments I pass are declared as
const (plus the functions). This way I can't have side effects right? (e.g when two sprites collide change their speed etc; ok I don't have speed but Sprite more of a generic type so classes that inherit it can have it). So to have side effect I have to removed the const keywords and pass a reference, am I correct?
The Sprite version is also declared as virtual to be overriden.
SDL_Rect offset. It's
protected. I have some questions regarding this. If I make it private, will child classes be able to call functions such as x() (that returns offset.x) ?
It makes me think that if it's protected, child classes will be free to change the width and height of the rectangle (offset.w/h) and mess things up. So I thought of this: keep it private and provide functions to set x and y (not w and h).
What do you think about the design? I will be using the Sprite class in all my projects.
--------------------------------------------------------------------------------
This is
sprite.cpp by the way.
#include "Sprite.h"
Sprite::Sprite(Sint16 x, Sint16 y, SDL_Surface *image): img(0)
{
img = SDL_DisplayFormat(image);
offset.x = x;
offset.y = y;
offset.w = img->w;
offset.h = img->h;
}
Sprite::Sprite(SDL_Surface *image): img(0)
{
img = SDL_DisplayFormat(image);
offset.x = 0;
offset.y = 0;
offset.w = image->w;
offset.h = img->h;
}
Sprite::Sprite(Sprite &spr)
{
SDL_FreeSurface(img);
img = 0;
img = SDL_DisplayFormat(spr.image());
offset = spr.rect();
}
Sprite::~Sprite()
{
SDL_FreeSurface(img);
}
Sprite& Sprite::operator =(Sprite &spr)
{
if(this != &spr) // if we are not assigning to itself
{
SDL_FreeSurface(img);
img = 0;
img = SDL_DisplayFormat(spr.image());
offset = spr.rect();
}
return *this;
}
SDL_Surface* Sprite::image()
{
return img;
}
SDL_Rect Sprite::rect() const
{
return offset;
}
bool Sprite::collidesWith(const SDL_Rect &rect) const
{
return collision(offset, rect);
}
bool Sprite::collidesWith(const Sprite &spr) const
{
return collision(offset, spr.rect());
}
Sint16 Sprite::x() const
{
return offset.x;
}
Sint16 Sprite::y() const
{
return offset.y;
}
Uint16 Sprite::w() const
{
return offset.w;
}
Uint16 Sprite::h() const
{
return offset.h;
}
I haven't inlined one line functions. The compiler will do it right?