/* [DESTRUCTUR] Destruction de l'animation =========================================================*/ xSpriteAnimation::~xSpriteAnimation(){ SDL_DestroyTexture( _texture ); _manager = NULL; _texture = NULL; } /* [CONSTRUCTOR] Construction de l'animation (chargement) =========================================================*/ xSpriteAnimation::xSpriteAnimation(xManager *manager, const char *url, SDL_Rect viewport){ /* (1) Definition des attributs */ _manager = manager; _texture = NULL; _viewport = viewport; /* (2) On charge le spritesheet */ _texture = IMG_LoadTexture( _manager->renderer(), url ); // Gestion erreur if( _texture == NULL ) return; } /* [CONSTRUCTOR] Construction de l'animation a partir d'une texture existante =========================================================*/ xSpriteAnimation::xSpriteAnimation(xManager *manager, SDL_Texture *t, SDL_Rect viewport){ /* (1) Definition des attributs */ _manager = manager; _texture = NULL; _viewport = viewport; /* (2) On charge le spritesheet */ _texture = t; // Gestion erreur if( _texture == NULL ) return; } /* [MOVE] Modification de la position/taille du sprite =========================================================*/ void xSpriteAnimation::move(SDL_Rect newpos){ if( !_manager->hit(_texture, newpos.x, newpos.y) ){ if( newpos.x != 0 ) _viewport.x = newpos.x; if( newpos.y != 0 ) _viewport.y = newpos.y; if( newpos.w != 0 ) _viewport.w = newpos.w; if( newpos.h != 0) _viewport.h = newpos.h; } } /* [MOVE] Deplacement de la position/taille du sprite =========================================================*/ void xSpriteAnimation::move(int x, int y){ /* (1) Variables utiles */ int incrx = x; int incry = y; bool moveY = true; int signofx = (x==0) ? 0 : x / abs(x); int signofy = (y==0) ? 0 : y / abs(y); /* (2) Tant qu'on n'a pas bouge */ while( incrx != 0 || incry != 0 ){ /* (3) Si on peut aller a la destination */ if( !_manager->hit(_texture, incrx, incry) ){ _viewport.x += incrx; _viewport.y += incry; return; } /* (4) Sinon, on decremente les deplacements alternativement */ if( moveY ) incry -= signofy; else incrx -= signofx; moveY = !moveY; } } /* [ADDFRAME] Ajout d'une frame d'animation =========================================================*/ void xSpriteAnimation::addFrame(SDL_Rect clip){ // On ajoute une frame _frames.push_back( (SDL_Rect){ clip.x, clip.y, clip.w, clip.h } ); } /* [CLEAR] Supprime toutes les frames =========================================================*/ void xSpriteAnimation::clear(){ for( int i = 0 ; i < _frames.size() ; i++ ) _frames.erase(_frames.begin() + i); cout << "NB: " << _frames.size() << endl; } /* [MANAGER] Retourne le manager =========================================================*/ xManager *xSpriteAnimation::manager(){ return _manager; } /* [VIEWPORT] Retourne le viewport =========================================================*/ SDL_Rect *xSpriteAnimation::viewport(){ return &_viewport; } /* [PUSH] Ajoute au rendu =========================================================*/ void xSpriteAnimation::push(string index){ _index = index; // Gestion erreur si aucune frame if( _frames.size() == 0 ) return; _frame = _frames[0]; /* (1) On ajoute le sprite au rendu */ _manager->push(index, _texture, &_frame, &_viewport); } /* [PULL] Retire du rendu =========================================================*/ void xSpriteAnimation::pull(string index){ _index = index; /* (2) On retire le sprite du rendu */ _manager->pull(index); } /* [PULL] Retire du rendu =========================================================*/ void xSpriteAnimation::pull(){ /* (2) On retire le sprite du rendu */ _manager->pull(_texture); } /* [TRHEAD] Process de l'animation =========================================================*/ void xSpriteAnimationProcess(xSpriteAnimation *xSA, int t, int flags){ int timer = 0; bool way = true; int start = 0; int stop = xSA->_frames.size(); while( flags&SPRITE_ANIM_INFINITE ){ /* (1) Pour chaque sprite */ for( int i = start ; i != xSA->_frames.size() ; i+=(way?1:-1) ){ timer = SDL_GetTicks(); // On met a jour la frame xSA->_frame = xSA->_frames[i]; xSA->manager()->update(); if( SDL_GetTicks()-timer < t ) SDL_Delay( t - (SDL_GetTicks()-timer) ); } /* (2) Gestion des flags */ // SPRITE_ANIM_REVERSE if( flags&SPRITE_ANIM_REVERSE ){ way = !way; start = (way) ? 0 : xSA->_frames.size()-1; stop = (way) ? xSA->_frames.size()-1 : 0; } } /* (n) On termine le thread */ return; } /* [START] Ajoute l'animation au rendu =========================================================*/ void xSpriteAnimation::start(int t, int flags){ _timeout = t; _flags = flags; /* (1) On lance l'animation */ _animation = new thread(xSpriteAnimationProcess, this, t, flags); // On attends pas le thread _animation->detach(); } /* [STOP] Arrete l'animation =========================================================*/ void xSpriteAnimation::stop(){ /* (1) On arrete l'animation */ delete _animation; }