diff --git a/SDL#4/exe b/SDL#4/exe index 8209a8c..23d508a 100755 Binary files a/SDL#4/exe and b/SDL#4/exe differ diff --git a/SDL#4/main.cpp b/SDL#4/main.cpp index 32e2b0e..99ead22 100644 --- a/SDL#4/main.cpp +++ b/SDL#4/main.cpp @@ -6,6 +6,11 @@ static bool running = true; static xMarioMario *mario = NULL; +static bool left_move = false; +static bool right_move = false; +static bool up_move = false; +static bool down_move = false; + int main(int argc, char* argv[]) { srand(time(0)); @@ -30,6 +35,10 @@ int main(int argc, char* argv[]) { xMarioGrass btmleft(mgr, (SDL_Rect){-1, 20-2, 10, 3} ); btmleft.push("bottom-left"); + // On cree un bout du terrain + xMarioGrass btmcenter(mgr, (SDL_Rect){13, 20-3, 10, 3} ); + btmcenter.push("bottom-center"); + xMarioGrass floattcenter(mgr, (SDL_Rect){10, 10, 5, 5} ); floattcenter.push("float-center"); @@ -44,6 +53,7 @@ int main(int argc, char* argv[]) { // On cree un bloc mystere xMarioMysteryBloc mb(mgr, 5, 20-5); + // mb.push("mystery-bloc"); mb.start("mystery-bloc", 150, SPRITE_ANIM_INFINITE); // On cree un bloc normal @@ -52,19 +62,24 @@ int main(int argc, char* argv[]) { // On cree mario mario = new xMarioMario(mgr, 5, 20-3); + // mb.push("mario"); mario->start("mario", 100, SPRITE_ANIM_INFINITE); - /* [n-1] Boucle infinie =========================================================*/ // Gestion des evenements SDL_Event event; mgr->attachEvent(SDL_KEYDOWN, &keydownEventHandler); + mgr->attachEvent(SDL_KEYUP, &keyupEventHandler); mgr->attachEvent(SDL_QUIT, &quitEventHandler); + left_move = false; + right_move = false; + up_move = false; + down_move = false; // Boucle de traitement mgr->update(); mgr->update(); @@ -76,6 +91,13 @@ int main(int argc, char* argv[]) { while( SDL_PollEvent(&event) != 0 ) mgr->manageEvents(&event); + // Gestion de la gravite + if( !mgr->hit("mario", 0, 5) ) + mario->move(0, 5); + + if( mgr->hit("mystery-bloc", 0, 8) ) + mb.stop(); + mgr->manageFps(); // Gestion des FPS (speed) @@ -95,6 +117,14 @@ int main(int argc, char* argv[]) { } + + + + + + + + /* GESTION DE QUAND ON QUITTE LA FENETRE * * @e Pointeur sur l'evenement appelant @@ -108,67 +138,87 @@ void quitEventHandler(SDL_Event *e){ + + + + + + + + /* GESTION DE QUAND ON APPUIE SUR FLECHE BAS * * @e Pointeur sur l'evenement appelant * */ void keydownEventHandler(SDL_Event *e){ + + switch( (*e).key.keysym.sym ){ + case SDLK_UP: + up_move = true; + mario->moveUp(&up_move); + break; + + case SDLK_LEFT: + left_move = true; + mario->moveLeft(&left_move); + break; + + case SDLK_RIGHT: + right_move = true; + mario->moveRight(&right_move); + break; + + case SDLK_DOWN: + down_move = true; + mario->moveDown(&down_move); + break; + + default: + cout << "UNUSED KEY" << endl; + break; + } + +} + + + + + + + + + + + + +/* GESTION DE QUAND ON APPUIE SUR FLECHE BAS +* +* @e Pointeur sur l'evenement appelant +* +*/ +void keyupEventHandler(SDL_Event *e){ SDL_Rect *mRect = mario->viewport(); - bool hasMoved = false; - int step = 20; switch( (*e).key.keysym.sym ){ case SDLK_UP: - while( !hasMoved && step > 0 ){ - - if( !mgr->hit("mario", 0, -step) ){ - mario->move(0, -step); - hasMoved = true; - } - - step--; - } + up_move = false; break; case SDLK_LEFT: - while( !hasMoved && step > 0 ){ - - if( !mgr->hit("mario", -step, 0) ){ - mario->move(-step, 0); - hasMoved = true; - } - - step--; - } + left_move = false; break; case SDLK_RIGHT: - while( !hasMoved && step > 0 ){ - - if( !mgr->hit("mario", step, 0) ){ - mario->move(step, 0); - hasMoved = true; - } - - step--; - } + right_move = false; break; case SDLK_DOWN: - while( !hasMoved && step > 0 ){ - - if( !mgr->hit("mario", 0, step) ){ - mario->move(0, step); - hasMoved = true; - } - - step--; - } + down_move = false; break; diff --git a/SDL#4/main.h b/SDL#4/main.h index a904dbe..426b654 100644 --- a/SDL#4/main.h +++ b/SDL#4/main.h @@ -28,5 +28,6 @@ =========================================================*/ void quitEventHandler(SDL_Event *e); void keydownEventHandler(SDL_Event *e); + void keyupEventHandler(SDL_Event *e); #endif \ No newline at end of file diff --git a/SDL#4/main.o b/SDL#4/main.o index 15d8504..7c8badc 100644 Binary files a/SDL#4/main.o and b/SDL#4/main.o differ diff --git a/SDL#4/todo.md b/SDL#4/todo.md index 3392e6c..220ce31 100644 --- a/SDL#4/todo.md +++ b/SDL#4/todo.md @@ -1,5 +1,7 @@ A FAIRE ======= +- [ ] Erreur a corriger pour xSpriteAnimation on doit faire start() mais push() puis start() (qui est equivalent) ne marche pas +- [ ] Gestion de l'acceleration - [ ] Gestion de la gravite diff --git a/SDL#4/xMario/xMarioMario.cpp b/SDL#4/xMario/xMarioMario.cpp index 4ab9509..d6a9d92 100644 --- a/SDL#4/xMario/xMarioMario.cpp +++ b/SDL#4/xMario/xMarioMario.cpp @@ -12,6 +12,11 @@ xMarioMario::xMarioMario(xManager *m, int x, int y) } ){ + _left = NULL; + _right = NULL; + _up = NULL; + _down = NULL; + // this->addFrame( (SDL_Rect){2, 0, 19, 29} ); // this->addFrame( (SDL_Rect){33, 0, 19, 29} ); @@ -34,4 +39,214 @@ xMarioMario::xMarioMario(xManager *m, int x, int y) // this->addFrame( (SDL_Rect){82, 0, 18, 32} ); // this->addFrame( (SDL_Rect){103, 0, 18, 32} ); // this->addFrame( (SDL_Rect){125, 0, 18, 32} ); +} + + + +/* [XLEFTMOVEPROCESS] Traitement async de mouvement +=========================================================*/ +void xLeftMoveProcess(xMarioMario *m, bool *run){ + bool hasMoved = false; + int step = 5; + + + while( *run ){ + + hasMoved = false; + step = 5; + + // Tant qu'on a pas bouge et qu'on peut se deplacer + while( !hasMoved && step > 0 ){ + + // Si aucune collision, on deplace + if( !m->manager()->hit("mario", -step, 0) ){ + m->move(-step, 0); + hasMoved = true; + } + + // on reduit la distance de mouvement + step--; + } + + usleep(10000); + + } +} + +/* [MOVELEFT] Deplacement vers la gauche +=========================================================*/ +void xMarioMario::moveLeft(bool *run){ + if( _left != NULL ){ + delete _left; + _left = NULL; + } + // On lance le thread + _left = new thread(xLeftMoveProcess, this, run); + _left->detach(); +} + + + + + + + + + + + +/* [XRIGHTMOVEPROCESS] Traitement async de mouvement +=========================================================*/ +void xRightMoveProcess(xMarioMario *m, bool *run){ + bool hasMoved = false; + int step = 5; + + + while( *run ){ + + hasMoved = false; + step = 5; + + // Tant qu'on a pas bouge et qu'on peut se deplacer + while( !hasMoved && step > 0 ){ + + // Si aucune collision, on deplace + if( !m->manager()->hit("mario", step, 0) ){ + m->move(step, 0); + hasMoved = true; + } + + // on reduit la distance de mouvement + step--; + } + + usleep(10000); + + } +} + + + +/* [MOVERIGHT] Deplacement vers la droite +=========================================================*/ +void xMarioMario::moveRight(bool *run){ + if( _right != NULL ){ + delete _right; + _right = NULL; + } + + // On lance le thread + _right = new thread(xRightMoveProcess, this, run); + _right->detach(); +} + + + + + + + + + + + + +/* [XUPMOVEPROCESS] Traitement async de mouvement +=========================================================*/ +void xUpMoveProcess(xMarioMario *m, bool *run){ + bool hasMoved = false; + int step = 5; + + + while( *run ){ + + hasMoved = false; + step = 5; + + // Tant qu'on a pas bouge et qu'on peut se deplacer + while( !hasMoved && step > 0 ){ + + // Si aucune collision, on deplace + if( !m->manager()->hit("mario", 0, -step) ){ + m->move(0, -step); + hasMoved = true; + } + + // on reduit la distance de mouvement + step--; + } + + usleep(10000); + + } +} + + +/* [MOVEUP] Deplacement vers le haut +=========================================================*/ +void xMarioMario::moveUp(bool *run){ + if( _up != NULL ){ + delete _up; + _up = NULL; + } + + // On lance le thread + _up = new thread(xUpMoveProcess, this, run); + _up->detach(); +} + + + + + + + + + + + + +/* [XDOWNMOVEPROCESS] Traitement async de mouvement +=========================================================*/ +void xDownMoveProcess(xMarioMario *m, bool *run){ + bool hasMoved = false; + int step = 5; + + + while( *run ){ + + hasMoved = false; + step = 5; + + // Tant qu'on a pas bouge et qu'on peut se deplacer + while( !hasMoved && step > 0 ){ + + // Si aucune collision, on deplace + if( !m->manager()->hit("mario", 0, step) ){ + m->move(0, step); + hasMoved = true; + } + + // on reduit la distance de mouvement + step--; + } + + usleep(10000); + + } +} + + + +/* [MOVEDOWN] Deplacement vers le bas +=========================================================*/ +void xMarioMario::moveDown(bool *run){ + if( _down != NULL ){ + delete _down; + _down = NULL; + } + + // On lance le thread + _down = new thread(xDownMoveProcess, this, run); + _down->detach(); } \ No newline at end of file diff --git a/SDL#4/xMario/xMarioMario.h b/SDL#4/xMario/xMarioMario.h index 129ec80..ae46325 100644 --- a/SDL#4/xMario/xMarioMario.h +++ b/SDL#4/xMario/xMarioMario.h @@ -7,9 +7,28 @@ public: xMarioMario(xManager *manager, int x, int y); // Spritesheet avec taille de chaque sprite + void moveLeft(bool *run); // Deplacement a gauche + void moveRight(bool *run); // Deplacement a droite + void moveUp(bool *run); // Deplacement en haut + void moveDown(bool *run); // Deplacement en bas + private: - Uint32 _lastmove; - float _acceleration; + Uint32 _lastmove; + float _acceleration; + + // Gestion du deplacement + thread *_left; + thread *_right; + thread *_up; + thread *_down; + + // Fontions du thread + friend void xLeftMoveProcess(xMarioMario *m, bool *run); + friend void xRightMoveProcess(xMarioMario *m, bool *run); + friend void xUpMoveProcess(xMarioMario *m, bool *run); + friend void xDownMoveProcess(xMarioMario *m, bool *run); + + }; #endif \ No newline at end of file diff --git a/SDL#4/xSDL/xManager.cpp b/SDL#4/xSDL/xManager.cpp index f1082ff..12073e3 100644 --- a/SDL#4/xSDL/xManager.cpp +++ b/SDL#4/xSDL/xManager.cpp @@ -104,7 +104,14 @@ bool xManager::hit(string current, int movex, int movey){ }; SDL_Rect c; - /* (2) On compare avec toutes les autres textures */ + /* (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 @@ -130,6 +137,60 @@ bool xManager::hit(string current, int movex, int movey){ +/* [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 =========================================================*/ @@ -189,7 +250,7 @@ void xManager::push(string index, SDL_Texture *t, SDL_Rect *src, SDL_Rect *dst){ /* [PULL] Retire une texture du rendu principal =========================================================*/ -void xManager::pull(string index, SDL_Texture *t){ +void xManager::pull(string index){ // On bloque l'acces inter-thread _mutex.lock(); @@ -214,6 +275,33 @@ void xManager::pull(string index, SDL_Texture *t){ } +/* [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(); +} + + diff --git a/SDL#4/xSDL/xManager.h b/SDL#4/xSDL/xManager.h index 8e62594..cb4f710 100644 --- a/SDL#4/xSDL/xManager.h +++ b/SDL#4/xSDL/xManager.h @@ -13,12 +13,15 @@ bool setImage(const char *url); bool hit(string current, int movex=0, int movey=0); // Gestion des collisions + bool hit(SDL_Texture *current, int movex=0, int movey=0); // Gestion des collisions SDL_Texture *getTexture(string index); SDL_Rect *getSrc(string index); SDL_Rect *getDst(string index); + void push(string index, SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest); - void pull(string index, SDL_Texture *t); + void pull(string index); + void pull(SDL_Texture *t); void update(); diff --git a/SDL#4/xSDL/xSprite.cpp b/SDL#4/xSDL/xSprite.cpp index 5d73941..15c5404 100644 --- a/SDL#4/xSDL/xSprite.cpp +++ b/SDL#4/xSDL/xSprite.cpp @@ -110,7 +110,13 @@ void xSprite::push(string index){ /* [PULL] Retire une sprite du rendu =========================================================*/ void xSprite::pull(string index){ - _manager->pull( index, _texture ); + _manager->pull( index ); +} + +/* [PULL] Retire une sprite du rendu +=========================================================*/ +void xSprite::pull(){ + _manager->pull( _texture ); } /* [UPDATE] Mise a jour du rendu diff --git a/SDL#4/xSDL/xSprite.h b/SDL#4/xSDL/xSprite.h index 295576a..35246db 100644 --- a/SDL#4/xSDL/xSprite.h +++ b/SDL#4/xSDL/xSprite.h @@ -17,6 +17,7 @@ void push(string index); // Ajoute a l'affichage void pull(string index); // Retire de l'affichage + void pull(); // Retire de l'affichage void update(); // Fait renmonter la mise a jour du manager diff --git a/SDL#4/xSDL/xSpriteAnimation.cpp b/SDL#4/xSDL/xSpriteAnimation.cpp index a5eab5c..f8f6d20 100644 --- a/SDL#4/xSDL/xSpriteAnimation.cpp +++ b/SDL#4/xSDL/xSpriteAnimation.cpp @@ -47,25 +47,33 @@ xSpriteAnimation::xSpriteAnimation(xManager *manager, SDL_Texture *t, SDL_Rect v /* [MOVE] Modification de la position/taille du sprite =========================================================*/ void xSpriteAnimation::move(SDL_Rect newpos){ - if( newpos.x != 0 ) - _viewport.x = newpos.x; - if( newpos.y != 0 ) - _viewport.y = newpos.y; + if( !_manager->hit(_texture, newpos.x, newpos.y) ){ - if( newpos.w != 0 ) - _viewport.w = newpos.w; + if( newpos.x != 0 ) + _viewport.x = newpos.x; - if( newpos.h != 0) - _viewport.h = newpos.h; + if( newpos.y != 0 ) + _viewport.y = newpos.y; + + if( newpos.w != 0 ) + _viewport.w = newpos.w; + + if( newpos.h != 0) + _viewport.h = newpos.h; + + } } /* [MOVE] Deplacement de la position/taille du sprite =========================================================*/ void xSpriteAnimation::move(int x, int y){ - _viewport.x += x; - _viewport.y += y; + + if( !_manager->hit(_texture, x, y) ){ + _viewport.x += x; + _viewport.y += y; + } } @@ -96,6 +104,41 @@ SDL_Rect *xSpriteAnimation::viewport(){ return &_viewport; } + + + + + + +/* [PUSH] Ajoute au rendu +=========================================================*/ +void xSpriteAnimation::push(string index){ + /* (1) On ajoute le sprite au rendu */ + _manager->push(index, _texture, &_frame, &_viewport); +} + + +/* [PULL] Retire du rendu +=========================================================*/ +void xSpriteAnimation::pull(string index){ + /* (2) On retire le sprite du rendu */ + _manager->pull(index); +} + + +/* [PULL] Retire du rendu +=========================================================*/ +void xSpriteAnimation::pull(){ + /* (2) On retire le sprite du rendu */ + _manager->pull(_texture); +} + + + + + + + /* [TRHEAD] Process de l'animation =========================================================*/ void xSpriteAnimationProcess(xSpriteAnimation *xSA, int t, int flags){ @@ -142,15 +185,12 @@ void xSpriteAnimationProcess(xSpriteAnimation *xSA, int t, int flags){ - - /* [START] Ajoute l'animation au rendu =========================================================*/ void xSpriteAnimation::start(string index, int t, int flags){ - /* (1) On ajoute le sprite au rendu */ - _manager->push(index, _texture, &_frame, &_viewport); + this->push(index); - /* (2) On lance l'animation */ + /* (1) On lance l'animation */ _animation = new thread(xSpriteAnimationProcess, this, t, flags); // On attends pas le thread @@ -161,10 +201,9 @@ void xSpriteAnimation::start(string index, int t, int flags){ /* [STOP] Arrete l'animation =========================================================*/ -void xSpriteAnimation::stop(string index){ +void xSpriteAnimation::stop(){ + this->pull(); + /* (1) On arrete l'animation */ delete _animation; - - /* (2) On retire le sprite du rendu */ - _manager->pull(index, _texture); } \ No newline at end of file diff --git a/SDL#4/xSDL/xSpriteAnimation.h b/SDL#4/xSDL/xSpriteAnimation.h index 7f293fc..6dbffd8 100644 --- a/SDL#4/xSDL/xSpriteAnimation.h +++ b/SDL#4/xSDL/xSpriteAnimation.h @@ -18,9 +18,14 @@ xManager *manager(); SDL_Rect *viewport(); + // Gestion de l'ajout au rendu + void push(string index); // Ajout au rendu + void pull(string index); // Retrait du rendu + void pull(); // Retrait du rendu + // Gestion de l'animation void start(string index, int t, int flags=SPRITE_ANIM_ONCE); - void stop(string index); + void stop(); diff --git a/SDL#4/xSDL/xSpriteGroup.cpp b/SDL#4/xSDL/xSpriteGroup.cpp index 86287d0..073d334 100644 --- a/SDL#4/xSDL/xSpriteGroup.cpp +++ b/SDL#4/xSDL/xSpriteGroup.cpp @@ -69,6 +69,13 @@ void xSpriteGroup::pull(string index){ } } +/* [PULL] Retire une sprite de la surface parents +=========================================================*/ +void xSpriteGroup::pull(){ + for( int i = 0 ; i < _sprites.size() ; i++ ) + _sprites[i]->pull(); +} + /* [UPDATE] Mise a jour du rendu diff --git a/SDL#4/xSDL/xSpriteGroup.h b/SDL#4/xSDL/xSpriteGroup.h index 775d8b4..5800fd7 100644 --- a/SDL#4/xSDL/xSpriteGroup.h +++ b/SDL#4/xSDL/xSpriteGroup.h @@ -17,6 +17,7 @@ void push(string index); // Ajoute les sprites a l'affichage void pull(string index); // Retire les sprites de l'affichage + void pull(); // Retire les sprites de l'affichage void update(); // Fait renmonter la mise a jour du manager