/* [CONSTRUCTOR] Constructeur de la classe =========================================================*/ xManager::xManager(const char *t, int w, int h){ // default values _lasttick = SDL_GetTicks(); _fpstime = 1000/60; _window = NULL; _renderer = NULL; _texture = NULL; // Initialisation des sous-sys. SDL SDL_Init( SDL_INIT_EVERYTHING ); // Creation de la fenetre _window = SDL_CreateWindow( t, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_SHOWN ); // Gestion erreur if( _window == NULL ) return; // On enregistre les dimensions de la fenetre _winrect.x = _winrect.y = 0; SDL_GetWindowSize(_window, &_winrect.w, &_winrect.h); // Creation du renderer _renderer = SDL_CreateRenderer( _window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC ); } /* [DESTROYER] Destructeur de la classe =========================================================*/ xManager::~xManager(){ SDL_DestroyTexture(_texture); SDL_DestroyRenderer(_renderer); SDL_DestroyWindow( _window ); SDL_Quit(); } /* [STATUS] Retourne le status =========================================================*/ bool xManager::status(){ return _window != NULL && _renderer != NULL; } /* [WINDOW] Retourne la fenetre =========================================================*/ SDL_Window* xManager::window(){ return _window; } /* [SCREEN] Retourne la fenetre =========================================================*/ SDL_Renderer* xManager::renderer(){ return _renderer; } /* [SETBACKGROUND] Modifie la couleur de fond =========================================================*/ bool xManager::setBackground(Uint8 r, Uint8 g, Uint8 b, Uint8 a){ SDL_SetRenderDrawColor( _renderer, r, g, b, a ); return true; } /* [SETIMAGE] Met une image en fond =========================================================*/ bool xManager::setImage(const char *url){ // On cree la texture associee _texture = IMG_LoadTexture( _renderer, url ); return _texture != NULL; } /* [HIT] Retourne si une texture est en collision avec une autre =========================================================*/ bool xManager::hit(string current, int movex, int movey){ /* (1) On recupere le SDL_Rect destination du sprite courant */ SDL_Rect *cRect = this->getDst(current); // Gestion erreur if( cRect == NULL ) return false; SDL_Rect r = (SDL_Rect){ (*cRect).x+movex, (*cRect).y+movey, (*cRect).w, (*cRect).h }; SDL_Rect c; /* (2) On regarde si en dehors de la fenetre */ for( int y = r.y ; y < r.y+r.h ; y++ ) for( int x = r.x ; x < r.x+r.w ; x++ ) if( x < _winrect.x || x > _winrect.x+_winrect.w || y < _winrect.y || y>_winrect.y+_winrect.h ) return true; /* (3) On compare avec toutes les autres textures */ for( int i = 0 ; i < _indexes.size() ; i++ ){ // Si c'est pas le sprite courant if( _indexes[i] != current ){ // taille du sprite en cours c.x = (*_dst[i]).x; c.y = (*_dst[i]).y; c.w = (*_dst[i]).w; c.h = (*_dst[i]).h; for( int y = r.y ; y < r.y+r.h ; y++ ) for( int x = r.x ; x < r.x+r.w ; x++ ) if( x>=c.x && x<=c.x+c.w && y>=c.y && y<=c.y+c.h ) return true; } } return false; } /* [HIT] Retourne si une texture est en collision avec une autre =========================================================*/ bool xManager::hit(SDL_Texture *current, int movex, int movey){ /* (1) On recupere le SDL_Rect destination du sprite courant */ int xIndex = -1; for( int i = 0 ; i < _sprites.size() ; i++ ) if( _sprites[i] == current ) xIndex = i; if( xIndex == -1 ) return false; SDL_Rect r = (SDL_Rect){ (*_dst[xIndex]).x+movex, (*_dst[xIndex]).y+movey, (*_dst[xIndex]).w, (*_dst[xIndex]).h }; SDL_Rect c; /* (2) On regarde si en dehors de la fenetre */ for( int y = r.y ; y < r.y+r.h ; y++ ) for( int x = r.x ; x < r.x+r.w ; x++ ) if( x < _winrect.x || x > _winrect.x+_winrect.w || y < _winrect.y || y>_winrect.y+_winrect.h ) return true; /* (3) On compare avec toutes les autres textures */ for( int i = 0 ; i < _sprites.size() ; i++ ){ // Si c'est pas le sprite courant if( _sprites[i] != current ){ // taille du sprite en cours c.x = (*_dst[i]).x; c.y = (*_dst[i]).y; c.w = (*_dst[i]).w; c.h = (*_dst[i]).h; for( int y = r.y ; y < r.y+r.h ; y++ ) for( int x = r.x ; x < r.x+r.w ; x++ ) if( x>=c.x && x<=c.x+c.w && y>=c.y && y<=c.y+c.h ) return true; } } return false; } /* [GETTEXTURE] Renvoie la texture =========================================================*/ SDL_Texture *xManager::getTexture(string index){ // On cherche la texture avec l'index for( int i = 0 ; i < _indexes.size() ; i++ ) if( _indexes[i] == index ) return _sprites[i]; return NULL; } /* [GETSRC] Renvoie le SDL_Rect source =========================================================*/ SDL_Rect *xManager::getSrc(string index){ // On cherche la texture avec l'index for( int i = 0 ; i < _indexes.size() ; i++ ) if( _indexes[i] == index ) return _src[i]; return NULL; } /* [GETDST] Renvoie le SDL_Rect destination =========================================================*/ SDL_Rect *xManager::getDst(string index){ // On cherche la texture avec l'index for( int i = 0 ; i < _indexes.size() ; i++ ) if( _indexes[i] == index ) return _dst[i]; return NULL; } /* [PUSH] Ajoute une texture au rendu principal =========================================================*/ void xManager::push(string index, SDL_Texture *t, SDL_Rect *src, SDL_Rect *dst){ // On bloque l'acces inter-thread _mutex.lock(); _indexes.push_back( index ); _sprites.push_back( t ); _src.push_back( src ); _dst.push_back( dst ); // On debloque l'acces _mutex.unlock(); } /* [PULL] Retire une texture du rendu principal =========================================================*/ void xManager::pull(string index){ // On bloque l'acces inter-thread _mutex.lock(); // On cherche l'indice de la texture int xIndex = -1; for( int i = 0 ; i < _indexes.size() ; i++ ) if( _indexes[i] == index ) xIndex = i; // Si on a rien trouve if( xIndex == -1 ) return; // On supprime la texture et ses dimensions _indexes.erase( _indexes.begin() + xIndex ); _sprites.erase( _sprites.begin() + xIndex ); _src.erase( _src.begin() + xIndex ); _dst.erase( _dst.begin() + xIndex ); // On debloque l'acces _mutex.unlock(); } /* [PULL] Retire une texture du rendu principal =========================================================*/ void xManager::pull(SDL_Texture *t){ // On bloque l'acces inter-thread _mutex.lock(); // On cherche l'indice de la texture int xIndex = -1; for( int i = 0 ; i < _sprites.size() ; i++ ) if( _sprites[i] == t ) xIndex = i; // Si on a rien trouve if( xIndex == -1 ) return; // On supprime la texture et ses dimensions _indexes.erase( _indexes.begin() + xIndex ); _sprites.erase( _sprites.begin() + xIndex ); _src.erase( _src.begin() + xIndex ); _dst.erase( _dst.begin() + xIndex ); // On debloque l'acces _mutex.unlock(); } /* [MANAGEFTP] Gestion de la vitesse de boucle =========================================================*/ void xManager::manageFps(const int fps){ /* (1) Definition de fps */ if( fps != 0 ) _fpstime = 1000/fps; if( _lasttick == 0 ) _lasttick = SDL_GetTicks()-_fpstime; /* (2) Utilisation en fin de boucle */ // 1 > Si trop rapide, on attends if( SDL_GetTicks()-_lasttick < _fpstime ) SDL_Delay( _fpstime - (SDL_GetTicks()-_lasttick) ); // On enregistre le temps actuel _lasttick = SDL_GetTicks(); } /* [UPDATE] Mise a jour du rendu =========================================================*/ void xManager::update(){ // cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl; // On bloque l'acces inter-thread _mutex.lock(); /* (1) On efface le rendu */ SDL_RenderClear(_renderer); /* (2) On applique la couleur de fond */ SDL_RenderDrawRect(_renderer, &_winrect); /* (3) On ajoute le rendu principal (si existe) */ if( _texture != NULL) SDL_RenderCopy(_renderer, _texture, NULL, NULL); /* (4) On ajoute toutes les textures pushees */ for( int i = 0 ; i < _sprites.size() ; i++ ) SDL_RenderCopy(_renderer, _sprites[i], _src[i], _dst[i]); /* (n) On affiche le resultat */ SDL_RenderPresent(_renderer); // On debloque l'acces _mutex.unlock(); } /* [ATTACHEVENT] Ajoute une fonction a un type d'evenement =========================================================*/ void xManager::attachEvent(SDL_EventType t, void(*handler)(SDL_Event*)){ // On attache le type d'evenement a la fonction _events.push_back( t ); _handlers.push_back( handler ); } /* [MANAGEEVENTS] Gestion des evenements =========================================================*/ void xManager::manageEvents(SDL_Event *event){ // On lance les evenements en fonction de leur type for( int i = 0 ; i < _events.size() ; i ++ ) if( event->type == _events[i] ) // si type ok (*_handlers[i])(event); // on execute le handler }