xmario/xSDL/xSpriteAnimation.cpp

116 lines
2.3 KiB
C++
Raw Normal View History

#include "xSpriteAnimation.h"
/** clean SDL objects and frames */
xSpriteAnimation::~xSpriteAnimation(){
_mutex.try_lock();
SDL_FreeSurface( _surface );
_frames.erase( _frames.begin(), _frames.end() );
_mutex.unlock();
}
/** builds an animation */
xSpriteAnimation::xSpriteAnimation(const char *url, SDL_Rect dest)
: xSprite( url ){
this->dimensions(dest);
}
/** builds an animation from an existing surface */
xSpriteAnimation::xSpriteAnimation(SDL_Surface *s, SDL_Rect dest)
: xSprite(s) {
this->dimensions(dest);
}
/** adds an animation frame */
void xSpriteAnimation::addFrame(SDL_Rect clip){
_mutex.try_lock();
_frames.push_back( (SDL_Rect){
clip.x,
clip.y,
clip.w,
clip.h
} );
_mutex.unlock();
}
/** clears all frames */
void xSpriteAnimation::clearFrames(){
_mutex.try_lock();
_frames.erase(_frames.begin(), _frames.end());
_mutex.unlock();
}
/** draw to scene */
void xSpriteAnimation::draw(SDL_Renderer* renderer){
_mutex.try_lock();
SDL_RenderCopy(
renderer,
SDL_CreateTextureFromSurface(renderer, this->surface()),
this->src(),
this->dst()
);
_mutex.unlock();
}
/** animation process */
void xSpriteAnimationProcess(xSpriteAnimation *xSA, uint32_t t, int flags){
uint32_t timer = 0;
bool way = true;
uint32_t start = 0;
while( flags&SPRITE_ANIM_INFINITE ){
// for every frame (sprite)
for( uint32_t i = start ; i != xSA->_frames.size() ; i+=(way?1:-1) ){
timer = SDL_GetTicks();
// update current frame clip
// xSA->_mutex.try_lock();
xSA->_src = xSA->_frames.at(i);
// xSA->_mutex.unlock();
// xSA->manager()->update();
if( SDL_GetTicks()-timer < t )
SDL_Delay( t - (SDL_GetTicks()-timer) );
}
// manage reverse flag
if( flags&SPRITE_ANIM_REVERSE ){
way = !way;
start = (way) ? 0 : xSA->_frames.size()-1;
}
}
// end thread
return;
}
/** adds the animation to the render */
void xSpriteAnimation::start(int t, int flags){
_timeout = t;
_flags = flags;
// launch animation
_animation = new thread(xSpriteAnimationProcess, this, t, flags);
// don't wait for the thread to end
_animation->detach();
}
/** stops the animation */
void xSpriteAnimation::stop(){
// stop animation thread
delete _animation;
if( _animation->joinable() )
_animation->join();
_animation = NULL;
}