make xSpriteGroup render all if not animated, and only the current frame in the other case

This commit is contained in:
Adrien Marquès 2020-02-04 18:57:31 +01:00
parent 49deb9e868
commit cc276e1c2a
2 changed files with 65 additions and 10 deletions

View File

@ -25,11 +25,19 @@ void xSpriteGroup::remove(xSprite* sprite){
_mutex.unlock(); _mutex.unlock();
} }
/** set absolute move for each sprite */ /** set relative move for each sprite */
void xSpriteGroup::moveTo(int x, int y){ void xSpriteGroup::displace(int x, int y, int w, int h){
_mutex.lock(); _mutex.lock();
_move.x = x; _displace.x = x;
_move.y = y; _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(); _mutex.unlock();
} }
@ -37,9 +45,23 @@ void xSpriteGroup::moveTo(int x, int y){
void xSpriteGroup::draw(SDL_Renderer* renderer){ void xSpriteGroup::draw(SDL_Renderer* renderer){
_mutex.lock(); _mutex.lock();
// only draw active sprite if animated
if( _animated ){
set<xSprite*>::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<xSprite*>::iterator it; set<xSprite*>::iterator it;
for( it = _sprites.begin() ; it != _sprites.end() ; it++ ){ for( it = _sprites.begin() ; it != _sprites.end() ; it++ ){
(*it)->draw(renderer); draw_sprite(renderer, *it);
} }
_mutex.unlock(); _mutex.unlock();
} }
@ -47,18 +69,46 @@ void xSpriteGroup::draw(SDL_Renderer* renderer){
/** animation process */ /** animation process */
void xSpriteGroup::tick(const uint32_t ticks){ void xSpriteGroup::tick(const uint32_t ticks){
_mutex.lock(); _mutex.lock();
uint32_t time_index = ticks / _animation_interval; const uint32_t time_index = ticks / _animation_interval;
_active_sprite = time_index % _sprites.size(); _active_sprite = time_index % _sprites.size();
_mutex.unlock(); _mutex.unlock();
} }
/** orchestrate the animation */ /** orchestrate the animation */
void xSpriteGroup::animate(uint32_t interval){ void xSpriteGroup::animate(uint32_t interval){
_mutex.lock();
_animated = true;
_animation_interval = interval; _animation_interval = interval;
xApplication::get()->addOrchestrable(this); xApplication::get()->addOrchestrable(this);
_mutex.unlock();
} }
/** stops orchestrating the animation */ /** stops orchestrating the animation */
void xSpriteGroup::freeze(){ void xSpriteGroup::freeze(){
_mutex.lock();
xApplication::get()->removeOrchestrable(this); 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
);
} }

View File

@ -24,7 +24,8 @@
void clear(); void clear();
// set absolute move for each sprite // 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 // implement xDrawable
virtual void draw(SDL_Renderer* renderer) override; virtual void draw(SDL_Renderer* renderer) override;
@ -37,13 +38,17 @@
void freeze(); void freeze();
protected: protected:
SDL_Rect _move; void draw_sprite(SDL_Renderer* renderer, xSprite* sprite);
SDL_Rect _displace;
set<xSprite*> _sprites; set<xSprite*> _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; size_t _active_sprite = 0;
uint32_t _animation_interval; uint32_t _animation_interval = 0;
mutex _mutex; mutex _mutex;