/* [DESTRUCTOR] Destruction de la surface =========================================================*/ xSprite::~xSprite(){ SDL_DestroyTexture( _texture ); _manager = NULL; _manager = NULL; } /* [CONSTRUCTOR] Construction de la surface vide =========================================================*/ xSprite::xSprite(xManager *m){ _type = "basic"; _manager = m; SDL_DestroyTexture(_texture); _texture = NULL; } /* [CONSTRUCTOR] Construction de la surface avec couleur =========================================================*/ xSprite::xSprite(xManager *m, const int rgb[]){ _type = "basic"; _manager = m; _texture = NULL; SDL_Surface *surf = SDL_CreateRGBSurface(0, 0, 0, 32, 0, 0, 0, rgb[3]); // On recupere la couleur Uint32 color = SDL_MapRGBA( surf->format, rgb[0], rgb[1], rgb[2], rgb[3]); // On cree la texture a partir de la surface _texture = SDL_CreateTextureFromSurface(_manager->renderer(), surf); // On libere la surface inutile maintenant SDL_FreeSurface( surf ); surf = NULL; } /* [CONSTRUCTOR] Construction de la surface avec image =========================================================*/ xSprite::xSprite(xManager *m, const char *url){ _type = "basic"; _manager = m; _texture = NULL; /* (1) On cree la texture directement */ _texture = IMG_LoadTexture(_manager->renderer(), url); // Gestion erreur if( _texture == NULL ) return; } /* [CONSTRUCTOR] Constructions avec copie de texture =========================================================*/ xSprite::xSprite(xManager *m, SDL_Texture *t){ _type = "basic"; _manager = m; _texture = t; // Gestion erreur if( _texture == NULL ) return; } /* [SETTEXTURE] Modification de la texture avec couleur =========================================================*/ void xSprite::setTexture(const int rgb[]){ _texture = NULL; SDL_Surface *surf = SDL_CreateRGBSurface(0, 0, 0, 32, 0, 0, 0, rgb[3]); // On recupere la couleur Uint32 color = SDL_MapRGBA( surf->format, rgb[0], rgb[1], rgb[2], rgb[3]); // On cree la texture a partir de la surface _texture = SDL_CreateTextureFromSurface(_manager->renderer(), surf); // On libere la surface inutile maintenant SDL_FreeSurface( surf ); surf = NULL; } /* [SETTEXTURE] Modification de la texture avec image =========================================================*/ void xSprite::setTexture(const char *url){ _texture = NULL; /* (1) On cree la texture directement */ _texture = IMG_LoadTexture(_manager->renderer(), url); // Gestion erreur if( _texture == NULL ) return; } /* [SETTEXTURE] Modification de la texture texture =========================================================*/ void xSprite::setTexture(SDL_Texture *t){ _type = "basic"; _texture = NULL; _texture = t; // Gestion erreur if( _texture == NULL ) return; } /* [MOVE] Modification de la position/taille du sprite =========================================================*/ vector xSprite::move(SDL_Rect newpos){ vector result; if( !_manager->hit(this, newpos.x, newpos.y) ){ if( newpos.x != 0 ) _dst.x = newpos.x; if( newpos.y != 0 ) _dst.y = newpos.y; if( newpos.w != 0 ) _dst.w = newpos.w; if( newpos.h != 0) _dst.h = newpos.h; } result.push_back( newpos.x ); result.push_back( newpos.y ); result.push_back( newpos.w ); result.push_back( newpos.h ); return result; } /* [MOVE] Deplacement de la position/taille du sprite =========================================================*/ // renvoie un tableau d'au moins 4 entiers // 1 -> -1 ou 1 en fonction de la direction de la collision sur x // 2 -> -1 ou 1 en fonction de la direction de la collision sur y // 3 -> le deplacement effectif sur x // 4 -> le deplacement effectif sur y // vector xSprite::move(int x, int y){ // Protection inter-thread _mutex_move.try_lock(); vector result; result.push_back( (x!=0) ? (int)( x / abs(x) ) : 0 ); result.push_back( (y!=0) ? (int)( y / abs(y) ) : 0 ); result.push_back(0); result.push_back(0); /* (1) Variables utiles */ int incrx = x; int incry = y; bool moveFasterOnY = abs(x) <= abs(y); int signofx = (x==0) ? 0 : x / abs(x); int signofy = (y==0) ? 0 : y / abs(y); /* (2) Tant qu'on peut bouger (ni x ni y ne vaut 0) */ while( incrx!=0 || incry!=0 ){ result[2] = incrx; result[3] = incry; /* (3) Si on peut aller a la destination */ if( !_manager->hit(this, incrx, incry) ){ _dst.x += incrx; _dst.y += incry; // cerr << ">>> not locked <<<" << endl; result[2] = incrx; result[3] = incry; _mutex_move.unlock(); return result; } /* (4) Sinon, on decremente les deplacements 'alternativement' */ if( moveFasterOnY ){ // Si on a plus de mouvement horizontal if( signofx != 0 && incrx != 0 ) // si la vel. sur x n'est pas nulle incrx -= signofx; // on diminue la vel. sur x else if( signofy != 0 && incry != 0 ) // sinon si vel. sur y n'est pas nulle incry -= signofy; // on diminue la vel. sur y else // sinon, velocite nulle return result; // On arrete de chercher }else{ // Si on a plus de mouvement vertical if( signofy != 0 && incry != 0 ) // si la vel. sur y n'est pas nulle incry -= signofy; // on diminue la vel. sur y else if( signofx != 0 && incrx != 0 ) // sinon si vel. sur x n'est pas nulle incrx -= signofx; // on diminue la vel. sur x else // sinon, velocite nulle return result; // On arrete de chercher } // if( !_manager->hit(this, 0, 1) ){ // cerr << "locked from (" << _dst.x << ", " << _dst.y << ") to (" << incrx << ", " << incry << ")" << endl; // } } // retour _mutex_move.unlock(); return result; } /* [ONCOLLIDE] Action en cas de collision =========================================================*/ void xSprite::onCollide(vector from, xSprite* by){ if( from[0] == 0 && from[1] == 0 ) return; cerr << _type << " collided with " << by->_type << " from "; if( from[0] != 0 ) cerr << ((from[0]==1)?"right":"left") << endl; if( from[1] != 0 ) cerr << ((from[1]==1)?"bottom":"top") << endl; } /* [GETTYPE] Retourne le type de sprite =========================================================*/ string xSprite::getType(){ return _type; } /* [SETTYPE] Modifie le type de sprite =========================================================*/ void xSprite::setType(string newtype){ _type = newtype; } /* [DIMENSIONS] Definition des dimensions par defaut =========================================================*/ void xSprite::dimensions(){ /* (1) On recupere les informations de la texture */ int w, h; SDL_QueryTexture(_texture, NULL, NULL, &w, &h); /* (2) On definit les dimensions par defaut */ _dst = (SDL_Rect){0, 0, w, h}; _src = (SDL_Rect){0, 0, w, h}; } /* [DIMENSIONS] Definition des dimensions de la texture =========================================================*/ void xSprite::dimensions(SDL_Rect r){ /* (1) On recupere les informations de la texture */ int w, h; SDL_QueryTexture(_texture, NULL, NULL, &w, &h); /* (2) On definit les dimensions */ _dst = (SDL_Rect){r.x, r.y, r.w, r.h}; _src = (SDL_Rect){0, 0, w, h}; } /* [DIMENSIONS] Definition des dimensions de la texture+clip =========================================================*/ void xSprite::dimensions(SDL_Rect r, SDL_Rect clip){ /* (1) On definit les dimensions */ _dst = (SDL_Rect){r.x, r.y, r.w, r.h}; _src = (SDL_Rect){clip.x, clip.y, clip.w, clip.h}; } /* [PUSH] Ajoute le xSprite au rendu =========================================================*/ void xSprite::push(string index){ _index = index; _manager->push(index, this); } /* [PULL] Retire une sprite du rendu =========================================================*/ void xSprite::pull(string index){ _index = index; _manager->pull( index ); } /* [PULL] Retire une sprite du rendu =========================================================*/ void xSprite::pull(){ _manager->pull( this ); } /* [UPDATE] Mise a jour du rendu =========================================================*/ void xSprite::update(){ _manager->update(); } /* [TEXTURE] Retourne la texture =========================================================*/ SDL_Texture *xSprite::texture(){ return _texture; } /* [MANAGER] Retourne le manager =========================================================*/ xManager *xSprite::manager(){ return _manager; } /* [DST] Retourne le SDL_Rect de destination =========================================================*/ SDL_Rect *xSprite::dst(){ return &_dst; } /* [SRC] Retourne le SDL_Rect source =========================================================*/ SDL_Rect *xSprite::src(){ return &_src; }