Original Post
Hello everyone! I've created a custom AnimatedSprite class in SDL. It encapsulates a 2D vector of Sprite objects. 2D vector? Here's why. Let's say I create an AnimatedSprite knight. Knight must have sprites to move and to attack for example. The SpriteSet class comes then. It allows for different "categories" of sprites in an AnimatedSprite object; AnimatedSprite knight; SpriteSet knightMoveSet, knightAttackSet; knight.AddSprite(knightMoveSet, "...."); knight.AddSprite(knightMoveSet, "...."); knight.AddSprite(knightAttackSet, "...."); knight.AddSprite(knightAttackSet, "...."); The SpriteSet objects are used to distinguish which category to use. But it requires that AnimatedSprite object has one or more SpriteSet objects working with it. On the other hand, if SpriteSet didn't exist, I would need to have different AnimatedSprites for each animation. What do you think is best?
#ifndef MIN_ANIMATED_SPRITE_HPP
#define MIN_ANIMATED_SPRITE_HPP
// "Min" headers
#include "Min_Image.hpp"
#include "Min_Sprite.hpp"
#include "Min_Debug.hpp"
#include <algorithm>
#include <vector>
namespace Min
{
// class declarations
class SpriteSet;
class AnimatedSprite;
class SpriteSet
{
friend class AnimatedSprite;
unsigned _offset;
unsigned _currentSprite, _lastSprite, _numSprites;
bool _initialized;
public:
SpriteSet() : _offset(0), _currentSprite(0), _lastSprite(0), _numSprites(0), _initialized(false)
{}
};
// represents an animated sprite
// AnimatedSprite contains a vector of Sprites
class AnimatedSprite
{
public:
enum {NOT_USED_BY_THIS, UNINITIALIZED};
// constructor
AnimatedSprite() {}
// destructor
virtual ~AnimatedSprite(); // needed to free storage from _SpriteVector
// return SpriteSet::{SUCCESS, OUT_OF_BOUNDS, UNINITIALIZED};
void AddSprite(SpriteSet &spr_set, const std::string &spriteFileName);
// blit a set of Sprites and move to the next sprite (or back if backwards is true)
void BlitSet(SpriteSet &spr_set, Sint16 x, Sint16 y, bool backwards = false);
// blit only the current sprite
void BlitCurrent(SpriteSet &spr_set, Sint16 x, Sint16 y);
// sets the current Sprite to the next/prev
void SetNextSprite(SpriteSet &spr_set);
void SetPrevSprite(SpriteSet &spr_set);
// COLORKEY AND ALPHA FUNCTIONS
// set a colorkey for all sprites in all vectors
void SetColorKey(const SDL_Color &key);
void SetColorKey(const Uint8 red, const Uint8 green, const Uint8 blue);
// set a colorkey for the SpriteSet passed
void SetColorKey(SpriteSet &spr_set, const SDL_Color &key);
void SetColorKey(SpriteSet &spr_set, const Uint8 red, const Uint8 green, const Uint8 blue);
// x, y, w AND h FUNCTIONS
// return x, y, w and h or the current Sprite in spr_set
Sint16 x(const SpriteSet spr_set) const {return _SpriteVector[spr_set._offset][spr_set._currentSprite]->x();}
Sint16 y(const SpriteSet spr_set) const {return _SpriteVector[spr_set._offset][spr_set._currentSprite]->y();}
Sint16 w(const SpriteSet spr_set) const {return _SpriteVector[spr_set._offset][spr_set._currentSprite]->w();}
Sint16 h(const SpriteSet spr_set) const {return _SpriteVector[spr_set._offset][spr_set._currentSprite]->h();}
// set the position
virtual void SetPos(SpriteSet &spr_set, Sint16 x, Sint16 y); // for a SpriteSet
virtual void SetPos(Sint16 x, Sint16 y); // for all Sprites
// move
virtual void Move(SpriteSet &spr_set, Sint16 dx, Sint16 dy);
virtual void Move(Sint16 dx, Sint16 dy);
// returns the rectangle of the current Sprite in spr_set
virtual SDL_Rect rect(SpriteSet &spr_set) {return _SpriteVector[spr_set._offset][spr_set._currentSprite]->rect();}
// (OVERRIDE) collision functions (arguments that are passed are not const because their might be side effects
virtual void HandleCollision(SDL_Rect &r) {}
virtual void HandleCollision(AnimatedSprite &aspr) {}
virtual void HandleCollision(Sprite &spr) {}
// (OVERRIDE) handle input specific to this class
virtual void HandleInput(SDL_Event &event) {}
// returns true if spr_set is in use with this AnimatedSprite object
bool UsedByThis(const SpriteSet &spr_set)
{return std::count(_all_addresses.begin(), _all_addresses.end(), (long)&spr_set)-
std::count(_own_addresses.begin(), _own_addresses.end(), (long)&spr_set) == 0;}
private:
// vector of vectors containing Sprite* objects (on the heap)
std::vector<std::vector<Sprite*>> _SpriteVector;
// addresses
static std::vector <long> _all_addresses;
std::vector <long> _own_addresses;
// FUNCTIONS
// copy constructor & assignment operator
// not defined
AnimatedSprite(const AnimatedSprite &);
AnimatedSprite& operator = (const AnimatedSprite &);
// creates an new Sprite set
void CreateSet(SpriteSet &spr_set);
// contains debugging code
void dbg(const SpriteSet &spr_set);
};
}
#endif