lab.cpp/SDL#4/xSDL/xSprite.cpp

301 lines
7.6 KiB
C++

/* [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;
}
/* [MOVE] Modification de la position/taille du sprite
=========================================================*/
vector<int> xSprite::move(SDL_Rect newpos){
vector<int> 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<int> xSprite::move(int x, int y){
// Protection inter-thread
_mutex_move.lock();
vector<int> 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 moveFasterOnX = 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( moveFasterOnX ){ // 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<int> 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; }