make xSpriteGroup displace() actually update sprites with relative displace

This commit is contained in:
Adrien Marquès 2020-02-04 20:22:17 +01:00
parent 0b7e7a2948
commit cb1a862b6f
2 changed files with 29 additions and 41 deletions

View File

@ -25,19 +25,24 @@ void xSpriteGroup::remove(xSprite* sprite){
_mutex.unlock(); _mutex.unlock();
} }
/** set relative move for each sprite */ /** apply relative displace for each sprite */
void xSpriteGroup::displace(int x, int y, int w, int h){ void xSpriteGroup::displace(int x, int y, int w, int h){
_mutex.lock(); displace( (SDL_Rect){x,y,w,h} );
_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 relative_displace){
void xSpriteGroup::displace(SDL_Rect displace){
_mutex.lock(); _mutex.lock();
_displace = displace;
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
);
}
_mutex.unlock(); _mutex.unlock();
} }
@ -47,13 +52,22 @@ void xSpriteGroup::draw(SDL_Renderer* renderer){
// only draw active sprite if animated // only draw active sprite if animated
if( _animated ){ if( _animated ){
// invalid active index
if( _active_sprite >= _sprites.size() ) {
_active_sprite = 0;
_mutex.unlock();
return;
}
set<xSprite*>::iterator at_index = _sprites.begin(); set<xSprite*>::iterator at_index = _sprites.begin();
advance(at_index, _active_sprite); advance(at_index, _active_sprite);
if( at_index == _sprites.end() ){ if( at_index == _sprites.end() ){
_mutex.unlock(); _mutex.unlock();
return; return;
} }
draw_sprite(renderer, *at_index); (*at_index)->draw(renderer);
_mutex.unlock(); _mutex.unlock();
return; return;
} }
@ -61,7 +75,7 @@ void xSpriteGroup::draw(SDL_Renderer* renderer){
// else draw every sprite // 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++ ){
draw_sprite(renderer, *it); (*it)->draw(renderer);
} }
_mutex.unlock(); _mutex.unlock();
} }
@ -79,6 +93,7 @@ void xSpriteGroup::animate(uint32_t interval){
_mutex.lock(); _mutex.lock();
_animated = true; _animated = true;
_animation_interval = interval; _animation_interval = interval;
_active_sprite = 0;
xApplication::get()->addOrchestrable(this); xApplication::get()->addOrchestrable(this);
_mutex.unlock(); _mutex.unlock();
} }
@ -88,27 +103,4 @@ void xSpriteGroup::freeze(){
_mutex.lock(); _mutex.lock();
xApplication::get()->removeOrchestrable(this); xApplication::get()->removeOrchestrable(this);
_mutex.unlock(); _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

@ -23,8 +23,8 @@
void remove(xSprite* sprite); void remove(xSprite* sprite);
void clear(); void clear();
// set absolute move for each sprite // apply relative displace for each sprite
void displace(SDL_Rect displace); void displace(SDL_Rect relative_displace);
void displace(int x, int y, int w, int h); void displace(int x, int y, int w, int h);
// implement xDrawable // implement xDrawable
@ -38,10 +38,6 @@
void freeze(); void freeze();
protected: protected:
void draw_sprite(SDL_Renderer* renderer, xSprite* sprite);
SDL_Rect _displace;
set<xSprite*> _sprites; set<xSprite*> _sprites;
// if not animated, draw all sprites, else draw one at a time // if not animated, draw all sprites, else draw one at a time