2020-02-02 15:18:12 +00:00
|
|
|
#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();
|
|
|
|
}
|
|
|
|
|
2020-02-04 19:22:17 +00:00
|
|
|
/** apply relative displace for each sprite */
|
2020-02-04 17:57:31 +00:00
|
|
|
void xSpriteGroup::displace(int x, int y, int w, int h){
|
2020-02-04 19:22:17 +00:00
|
|
|
displace( (SDL_Rect){x,y,w,h} );
|
2020-02-04 17:57:31 +00:00
|
|
|
}
|
2020-02-04 19:22:17 +00:00
|
|
|
void xSpriteGroup::displace(SDL_Rect relative_displace){
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.lock();
|
2020-02-04 19:22:17 +00:00
|
|
|
|
|
|
|
for( set<xSprite*>::iterator it = _sprites.begin() ; it != _sprites.end() ; it++ ) {
|
|
|
|
xSprite* sprite = (*it);
|
|
|
|
const SDL_Rect actual_projection = sprite->projection();
|
|
|
|
|
|
|
|
sprite->project(
|
|
|
|
actual_projection.x + relative_displace.x,
|
|
|
|
actual_projection.y + relative_displace.y,
|
|
|
|
actual_projection.w + relative_displace.w,
|
|
|
|
actual_projection.h + relative_displace.h
|
|
|
|
);
|
|
|
|
}
|
2020-02-02 15:18:12 +00:00
|
|
|
_mutex.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** draws to renderer */
|
|
|
|
void xSpriteGroup::draw(SDL_Renderer* renderer){
|
|
|
|
_mutex.lock();
|
|
|
|
|
2020-02-04 17:57:31 +00:00
|
|
|
// only draw active sprite if animated
|
|
|
|
if( _animated ){
|
2020-02-04 19:22:17 +00:00
|
|
|
|
|
|
|
// invalid active index
|
|
|
|
if( _active_sprite >= _sprites.size() ) {
|
|
|
|
_active_sprite = 0;
|
|
|
|
_mutex.unlock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-04 17:57:31 +00:00
|
|
|
set<xSprite*>::iterator at_index = _sprites.begin();
|
|
|
|
advance(at_index, _active_sprite);
|
|
|
|
if( at_index == _sprites.end() ){
|
|
|
|
_mutex.unlock();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-04 19:22:17 +00:00
|
|
|
(*at_index)->draw(renderer);
|
|
|
|
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.unlock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// else draw every sprite
|
2020-02-02 15:18:12 +00:00
|
|
|
set<xSprite*>::iterator it;
|
|
|
|
for( it = _sprites.begin() ; it != _sprites.end() ; it++ ){
|
2020-02-04 19:22:17 +00:00
|
|
|
(*it)->draw(renderer);
|
2020-02-02 15:18:12 +00:00
|
|
|
}
|
|
|
|
_mutex.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** animation process */
|
|
|
|
void xSpriteGroup::tick(const uint32_t ticks){
|
|
|
|
_mutex.lock();
|
2020-02-04 17:57:31 +00:00
|
|
|
const uint32_t time_index = ticks / _animation_interval;
|
2020-02-02 15:18:12 +00:00
|
|
|
_active_sprite = time_index % _sprites.size();
|
|
|
|
_mutex.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** orchestrate the animation */
|
|
|
|
void xSpriteGroup::animate(uint32_t interval){
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.lock();
|
|
|
|
_animated = true;
|
2020-02-02 15:18:12 +00:00
|
|
|
_animation_interval = interval;
|
2020-02-04 19:22:17 +00:00
|
|
|
_active_sprite = 0;
|
2020-02-02 15:18:12 +00:00
|
|
|
xApplication::get()->addOrchestrable(this);
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.unlock();
|
2020-02-02 15:18:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** stops orchestrating the animation */
|
|
|
|
void xSpriteGroup::freeze(){
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.lock();
|
2020-02-02 15:18:12 +00:00
|
|
|
xApplication::get()->removeOrchestrable(this);
|
2020-02-04 17:57:31 +00:00
|
|
|
_mutex.unlock();
|
2020-02-02 15:18:12 +00:00
|
|
|
}
|