lab.cpp/SDL#2/Sprite.cpp

201 lines
4.6 KiB
C++
Raw Permalink Normal View History

2016-03-11 12:42:48 +00:00
/* [DESTRUCTOR] Destruction de la surface
=========================================================*/
Sprite::~Sprite(){
SDL_FreeSurface( _surface );
}
2016-03-10 23:00:26 +00:00
/* [CONSTRUCTOR] Construction de la surface vide
=========================================================*/
Sprite::Sprite(SDL_Rect r){
_surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0);
2016-03-10 23:00:26 +00:00
// On definit les dimensions
_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
_origin = (SDL_Rect){0, 0, r.w, r.h};
2016-03-10 23:00:26 +00:00
// 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]);
2016-03-10 23:00:26 +00:00
// On recupere la couleur
Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]);
2016-03-10 23:00:26 +00:00
// 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};
2016-03-10 23:00:26 +00:00
2016-03-10 23:00:26 +00:00
// 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){
2016-03-10 23:00:26 +00:00
/* (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};
2016-03-10 23:00:26 +00:00
// On applique le clip
SDL_SetClipRect( _surface, &clip );
2016-03-10 23:00:26 +00:00
}
/* [APPENDTO] Ajoute le Sprite a une autre
=========================================================*/
void Sprite::appendTo(SDL_Surface *dest){
SDL_BlitSurface( _surface, &_origin, dest, &_rect );
2016-03-10 23:00:26 +00:00
}
/* [SURFACE] Retourne la surface
=========================================================*/
SDL_Surface *Sprite::surface(){ return _surface; }
/**********************************/
/*********** SPRITEGROUP **********/
/**********************************/
/* [CONSTRUCTOR] Initialisation de la liste de Sprite
=========================================================*/
SpriteGroup::SpriteGroup(){
// _sprites = new vector<Sprite*>(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
=========================================================*/
2016-03-11 12:42:48 +00:00
void SpriteGroupAnimation(SDL_Window *win, SpriteGroup *sg, int t, Sprite *clear, int flags){
int length = sg->_sprites.size();
int timer = 0;
2016-03-11 12:42:48 +00:00
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) );
2016-03-11 12:42:48 +00:00
}
2016-03-11 12:42:48 +00:00
/* (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
=========================================================*/
2016-03-11 12:42:48 +00:00
thread* SpriteGroup::animate(SDL_Window *win, int t, Sprite *clear, int flags){
_animation = new thread(SpriteGroupAnimation, win, this, t ,clear, flags);
return _animation;
}