#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 relative move for each sprite */ void xSpriteGroup::displace(int x, int y, int w, int h){ _mutex.lock(); _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(); } /** draws to renderer */ 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++ ){ draw_sprite(renderer, *it); } _mutex.unlock(); } /** animation process */ void xSpriteGroup::tick(const uint32_t ticks){ _mutex.lock(); 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 ); }