/* [DESTRUCTOR] Destruction de la surface =========================================================*/ Sprite::~Sprite(){ SDL_FreeSurface( _surface ); } /* [CONSTRUCTOR] Construction de la surface vide =========================================================*/ Sprite::Sprite(SDL_Rect r){ _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0); // On definit les dimensions _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; _origin = (SDL_Rect){0, 0, r.w, r.h}; // On applique les offset SDL_SetClipRect( _surface, &_rect ); } /* [CONSTRUCTOR] Construction de la surface avec couleur =========================================================*/ Sprite::Sprite(const int rgb[], SDL_Rect r){ cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl; _surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]); // On recupere la couleur Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]); // On remplit avec la couleur SDL_FillRect( _surface, NULL, color ); // On definit les dimensions _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; _origin = (SDL_Rect){0, 0, r.w, r.h}; // On applique les offset SDL_SetClipRect( _surface, &_rect ); } /* [CONSTRUCTOR] Construction de la surface avec image =========================================================*/ Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){ /* (1) On cree la surface (avec image) */ _surface = IMG_Load( url ); // Gestion erreur if( _surface == NULL ) return; // On definit les dimensions _rect = (SDL_Rect){r.x, r.y, r.w, r.h}; _origin = (SDL_Rect){clip.x, clip.y, r.w, r.h}; // On applique le clip SDL_SetClipRect( _surface, &clip ); } /* [APPENDTO] Ajoute le Sprite a une autre =========================================================*/ void Sprite::appendTo(SDL_Surface *dest){ SDL_BlitSurface( _surface, &_origin, dest, &_rect ); } /* [SURFACE] Retourne la surface =========================================================*/ SDL_Surface *Sprite::surface(){ return _surface; } /**********************************/ /*********** SPRITEGROUP **********/ /**********************************/ /* [CONSTRUCTOR] Initialisation de la liste de Sprite =========================================================*/ SpriteGroup::SpriteGroup(){ // _sprites = new vector(0); } /* [ADD] Ajoute un Sprite au groupe =========================================================*/ void SpriteGroup::add(Sprite *s){ _sprites.push_back( s ); } /* [REMOVE] Suppression d'un Sprite du groupe =========================================================*/ void SpriteGroup::remove(Sprite *s){ int index = -1; // on cherche l'indice du sprite // On parcours la liste pour trouver l'indice for( int i = 0 ; i < _sprites.size() ; i++ ) if( _sprites[i] == s ) index = i; // Si on a pas trouve l'indice if( index == -1 ) return; // On supprime le sprite de la liste _sprites.erase(_sprites.begin() + index ); } /* [APPEBDTI] Ajoute tous les Sprite du groupe a une surface parente =========================================================*/ void SpriteGroup::appendTo(SDL_Surface *dest){ for( int i = 0 ; i < _sprites.size() ; i++ ) _sprites[i]->appendTo( dest ); } /* [GET] Retourne le Sprite d'index donne =========================================================*/ Sprite* SpriteGroup::get(int i){ return _sprites[i]; } /* [TRHEAD] Process de l'animation =========================================================*/ void SpriteGroupAnimation(SDL_Window *win, SpriteGroup *sg, int t, Sprite *clear, int flags){ int length = sg->_sprites.size(); int timer = 0; int step = 1; int start = 0; int stop = length; while( flags&SPRITE_ANIM_INFINITE ){ /* (1) Pour chaque sprite */ for( int i = start ; i != stop ; i+=step ){ timer = SDL_GetTicks(); // On utilise le sprite de clear pour couvrir les calques inferieurs if( clear != NULL ) clear->appendTo( SDL_GetWindowSurface(win) ); // On ajoute le sprite sg->_sprites[i]->appendTo( SDL_GetWindowSurface(win) ); // On met a jour le rendu SDL_UpdateWindowSurface( win ); if( SDL_GetTicks()-timer < t ) SDL_Delay( t - (SDL_GetTicks()-timer) ); } /* (2) Gestion des flags */ // SPRITE_ANIM_REVERSE if( flags&SPRITE_ANIM_REVERSE ){ step *= -1; start = (step==1) ? 0 : length-1; stop = (step==1) ? length-1 : 0; } } /* (n) On termine le thread */ return; } /* [ANIMATE] Modifie le Sprite dans l'ordre du SpriteGroup =========================================================*/ thread* SpriteGroup::animate(SDL_Window *win, int t, Sprite *clear, int flags){ _animation = new thread(SpriteGroupAnimation, win, this, t ,clear, flags); return _animation; }