From cc276e1c2a51c37bf33923d1296cb2fc508d6abf Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 4 Feb 2020 18:57:31 +0100 Subject: [PATCH] make xSpriteGroup render all if not animated, and only the current frame in the other case --- xSDL/xSpriteGroup.cpp | 62 ++++++++++++++++++++++++++++++++++++++----- xSDL/xSpriteGroup.h | 13 ++++++--- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/xSDL/xSpriteGroup.cpp b/xSDL/xSpriteGroup.cpp index 9b5ecc6..5930bad 100644 --- a/xSDL/xSpriteGroup.cpp +++ b/xSDL/xSpriteGroup.cpp @@ -25,11 +25,19 @@ void xSpriteGroup::remove(xSprite* sprite){ _mutex.unlock(); } -/** set absolute move for each sprite */ -void xSpriteGroup::moveTo(int x, int y){ +/** set relative move for each sprite */ +void xSpriteGroup::displace(int x, int y, int w, int h){ _mutex.lock(); - _move.x = x; - _move.y = y; + _displace.x = x; + _displace.y = y; + _displace.w = w; + _displace.h = h; + _mutex.unlock(); +} +/** set relative move for each sprite */ +void xSpriteGroup::displace(SDL_Rect displace){ + _mutex.lock(); + _displace = displace; _mutex.unlock(); } @@ -37,9 +45,23 @@ void xSpriteGroup::moveTo(int x, int y){ void xSpriteGroup::draw(SDL_Renderer* renderer){ _mutex.lock(); + // only draw active sprite if animated + if( _animated ){ + set::iterator at_index = _sprites.begin(); + advance(at_index, _active_sprite); + if( at_index == _sprites.end() ){ + _mutex.unlock(); + return; + } + draw_sprite(renderer, *at_index); + _mutex.unlock(); + return; + } + + // else draw every sprite set::iterator it; for( it = _sprites.begin() ; it != _sprites.end() ; it++ ){ - (*it)->draw(renderer); + draw_sprite(renderer, *it); } _mutex.unlock(); } @@ -47,18 +69,46 @@ void xSpriteGroup::draw(SDL_Renderer* renderer){ /** animation process */ void xSpriteGroup::tick(const uint32_t ticks){ _mutex.lock(); - uint32_t time_index = ticks / _animation_interval; + const uint32_t time_index = ticks / _animation_interval; _active_sprite = time_index % _sprites.size(); _mutex.unlock(); } /** orchestrate the animation */ void xSpriteGroup::animate(uint32_t interval){ + _mutex.lock(); + _animated = true; _animation_interval = interval; xApplication::get()->addOrchestrable(this); + _mutex.unlock(); } /** stops orchestrating the animation */ void xSpriteGroup::freeze(){ + _mutex.lock(); xApplication::get()->removeOrchestrable(this); + _mutex.unlock(); +} + + + +/* draws a sprite using the relative displace */ +void xSpriteGroup::draw_sprite(SDL_Renderer* renderer, xSprite* sprite) { + const SDL_Rect projection = sprite->projection(); + const SDL_Rect clip = sprite->clip(); + + // displace sprite projection with group move + const SDL_Rect displace { + projection.x + _displace.x, + projection.y + _displace.y, + projection.w + _displace.w, + projection.h + _displace.h + }; + + SDL_RenderCopy( + renderer, + SDL_CreateTextureFromSurface(renderer, sprite->surface()), + &clip, + &displace + ); } \ No newline at end of file diff --git a/xSDL/xSpriteGroup.h b/xSDL/xSpriteGroup.h index 87c002f..26a90a0 100644 --- a/xSDL/xSpriteGroup.h +++ b/xSDL/xSpriteGroup.h @@ -24,7 +24,8 @@ void clear(); // set absolute move for each sprite - void moveTo(int x, int y); + void displace(SDL_Rect displace); + void displace(int x, int y, int w, int h); // implement xDrawable virtual void draw(SDL_Renderer* renderer) override; @@ -37,13 +38,17 @@ void freeze(); protected: - SDL_Rect _move; + void draw_sprite(SDL_Renderer* renderer, xSprite* sprite); + + SDL_Rect _displace; set _sprites; - // active sprite for animation ; equal to 0 if not an animated sprite + // if not animated, draw all sprites, else draw one at a time + bool _animated = false; + // active sprite for animation size_t _active_sprite = 0; - uint32_t _animation_interval; + uint32_t _animation_interval = 0; mutex _mutex;