From 7a6022e69410e37a1c76422bdffd01f70c3e121c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sun, 2 Feb 2020 16:18:12 +0100 Subject: [PATCH] create orchestrable xSpriteGroup (no more xSprite alone) --- include/xSDL.h | 1 + xSDL/xSprite.cpp | 63 +++++++----------------------------------- xSDL/xSprite.h | 33 ++++------------------ xSDL/xSpriteGroup.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++ xSDL/xSpriteGroup.h | 52 +++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 81 deletions(-) create mode 100644 xSDL/xSpriteGroup.cpp create mode 100644 xSDL/xSpriteGroup.h diff --git a/include/xSDL.h b/include/xSDL.h index 2f3de5e..c65d299 100644 --- a/include/xSDL.h +++ b/include/xSDL.h @@ -6,5 +6,6 @@ #include "../xSDL/xController.h" #include "../xSDL/xDrawable.h" #include "../xSDL/xSprite.h" + #include "../xSDL/xSpriteGroup.h" #endif \ No newline at end of file diff --git a/xSDL/xSprite.cpp b/xSDL/xSprite.cpp index 0d79e7e..0b76c0e 100644 --- a/xSDL/xSprite.cpp +++ b/xSDL/xSprite.cpp @@ -2,7 +2,7 @@ /** clean SDL objects */ xSprite::~xSprite(){ - _mutex.try_lock(); + _mutex.lock(); SDL_FreeSurface( _surface ); _mutex.unlock(); } @@ -24,7 +24,7 @@ xSprite::xSprite(const char *url, SDL_Rect clip){ /** update sprite to rhb color */ void xSprite::setSurface(const int rgba[]){ - _mutex.try_lock(); + _mutex.lock(); if( _surface != NULL ){ SDL_FreeSurface( _surface ); _surface = NULL; @@ -42,7 +42,7 @@ void xSprite::setSurface(const int rgba[]){ /** update sprite to image */ void xSprite::setSurface(const char *url){ - _mutex.try_lock(); + _mutex.lock(); if( _surface != NULL ){ SDL_FreeSurface( _surface ); _surface = NULL; @@ -58,7 +58,7 @@ void xSprite::setSurface(const char *url){ /** copies an existing surface */ void xSprite::setSurface(SDL_Surface *s){ - _mutex.try_lock(); + _mutex.lock(); if( _surface != NULL ){ SDL_FreeSurface( _surface ); _surface = NULL; @@ -73,72 +73,29 @@ void xSprite::setSurface(SDL_Surface *s){ _mutex.unlock(); } -/** add new animation frame with new clip */ -void xSprite::addFrame(SDL_Rect clip){ - _mutex.try_lock(); - _frames.push_back(clip); - _mutex.unlock(); -} - -/** clear every animation frames */ -void xSprite::clearFrames(){ - _mutex.try_lock(); - _frames.clear(); - _mutex.unlock(); -} -/** set sprite clip and clears animation frames */ +/** set sprite clip */ void xSprite::setClip(SDL_Rect clip){ - _mutex.try_lock(); - _frames.clear(); - _frames.push_back(clip); + _mutex.lock(); + _clip = clip; _mutex.unlock(); } /** set sprite projection */ void xSprite::project(SDL_Rect dest){ - _mutex.try_lock(); + _mutex.lock(); _projection = dest; _mutex.unlock(); } /** draws to renderer */ void xSprite::draw(SDL_Renderer* renderer){ - _mutex.try_lock(); - - // no clip -> use surface dimensions - if( _frames.size() <= 0 ){ - setClip( (SDL_Rect){0, 0, _surface->w, _surface->h} ); - } - - // only 1 clip -> use it - if( _frames.size() == 1 ){ - _active_clip = 0; - } + _mutex.lock(); SDL_RenderCopy( renderer, SDL_CreateTextureFromSurface(renderer, _surface), - &_frames.at(_active_clip), + &_clip, &_projection ); _mutex.unlock(); -} - -/** animation process */ -void xSprite::tick(const uint32_t ticks){ - _mutex.try_lock(); - uint32_t time_index = ticks / _animation_interval; - _active_clip = time_index % _frames.size(); - _mutex.unlock(); -} - -/** orchestrate the animation */ -void xSprite::animate(uint32_t interval){ - _animation_interval = interval; - xApplication::get()->addOrchestrable(this); -} - -/** stops orchestrating the animation */ -void xSprite::freeze(){ - xApplication::get()->removeOrchestrable(this); } \ No newline at end of file diff --git a/xSDL/xSprite.h b/xSDL/xSprite.h index f911853..5189dd1 100644 --- a/xSDL/xSprite.h +++ b/xSDL/xSprite.h @@ -6,12 +6,11 @@ #include #include "SDL.h" #include "SDL_image.h" - #include "xElement.h" - #include "xOrchestrable.h" + #include "xDrawable.h" #include "xApplication.h" using namespace std; - class xSprite : public xElement, public xOrchestrable { + class xSprite : public xDrawable{ public: // color sprite @@ -27,41 +26,19 @@ void setSurface(const char *url); // image sprite void setSurface(SDL_Surface *t); // copy surface - // animation - void addFrame(SDL_Rect clip); - void clearFrames(); - // sets the sprite clip - // + clears animation frames void setClip(SDL_Rect clip); // set projection into scene void project(SDL_Rect dest); - // implement xElement + // implement xDrawable virtual void draw(SDL_Renderer* renderer) override; - - // orchestrable process - void tick(const uint32_t ticks); - - // animation handles - void animate(uint32_t interval); - void freeze(); - - protected: + private: SDL_Surface* _surface = NULL; + SDL_Rect _clip; SDL_Rect _projection; - // surface clips - // [0] : no clip, use default surface dimensions - // [1] : global clip, use it every time - // [2+]: clips are used for animation - vector _frames; - - // active clip for animation ; equal to 0 if not an animated sprite - size_t _active_clip = 0; - uint32_t _animation_interval; - mutex _mutex; }; diff --git a/xSDL/xSpriteGroup.cpp b/xSDL/xSpriteGroup.cpp new file mode 100644 index 0000000..9b5ecc6 --- /dev/null +++ b/xSDL/xSpriteGroup.cpp @@ -0,0 +1,64 @@ +#include "xSpriteGroup.h" + +/** clean SDL objects */ +xSpriteGroup::~xSpriteGroup(){ + _mutex.lock(); + _sprites.clear(); + _mutex.unlock(); +} + +/** default constructor */ +xSpriteGroup::xSpriteGroup(){ +} + +/** adds a sprite to the group */ +void xSpriteGroup::add(xSprite* sprite){ + _mutex.lock(); + _sprites.insert(sprite); + _mutex.unlock(); +} + +/** removes a sprite from the group */ +void xSpriteGroup::remove(xSprite* sprite){ + _mutex.lock(); + _sprites.erase(sprite); + _mutex.unlock(); +} + +/** set absolute move for each sprite */ +void xSpriteGroup::moveTo(int x, int y){ + _mutex.lock(); + _move.x = x; + _move.y = y; + _mutex.unlock(); +} + +/** draws to renderer */ +void xSpriteGroup::draw(SDL_Renderer* renderer){ + _mutex.lock(); + + set::iterator it; + for( it = _sprites.begin() ; it != _sprites.end() ; it++ ){ + (*it)->draw(renderer); + } + _mutex.unlock(); +} + +/** animation process */ +void xSpriteGroup::tick(const uint32_t ticks){ + _mutex.lock(); + uint32_t time_index = ticks / _animation_interval; + _active_sprite = time_index % _sprites.size(); + _mutex.unlock(); +} + +/** orchestrate the animation */ +void xSpriteGroup::animate(uint32_t interval){ + _animation_interval = interval; + xApplication::get()->addOrchestrable(this); +} + +/** stops orchestrating the animation */ +void xSpriteGroup::freeze(){ + xApplication::get()->removeOrchestrable(this); +} \ No newline at end of file diff --git a/xSDL/xSpriteGroup.h b/xSDL/xSpriteGroup.h new file mode 100644 index 0000000..87c002f --- /dev/null +++ b/xSDL/xSpriteGroup.h @@ -0,0 +1,52 @@ +#ifndef DEF_XSPRITEGROUP_H + #define DEF_XSPRITEGROUP_H + + #include + #include + #include + #include "SDL.h" + #include "SDL_image.h" + #include "xDrawable.h" + #include "xOrchestrable.h" + #include "xApplication.h" + #include "xSprite.h" + using namespace std; + + class xSpriteGroup : public xDrawable, public xOrchestrable { + + public: + xSpriteGroup(); + virtual ~xSpriteGroup(); + + // manage sprite list + void add(xSprite* sprite); + void remove(xSprite* sprite); + void clear(); + + // set absolute move for each sprite + void moveTo(int x, int y); + + // implement xDrawable + virtual void draw(SDL_Renderer* renderer) override; + + // implement xOrchestrable + void tick(const uint32_t ticks); + + // animation handles + void animate(uint32_t interval); + void freeze(); + + protected: + SDL_Rect _move; + + set _sprites; + + // active sprite for animation ; equal to 0 if not an animated sprite + size_t _active_sprite = 0; + uint32_t _animation_interval; + + mutex _mutex; + + }; + +#endif \ No newline at end of file