/* [CONSTRUCTOR] Construction d'un xMarioMario =========================================================*/ xMarioMario::xMarioMario(xManager *m, int x, int y) : xSpriteAnimation( m, "src/mario.png", (SDL_Rect){ (int) (BLOC_SIZE*x+BLOC_SIZE*.1), BLOC_SIZE*y, (int) (BLOC_SIZE*.8), BLOC_SIZE } ){ _left = false; _right = false; _up = false; _down = false; _jumps = 0; // Position frame par defaut _pos = "NR"; // bottom-center _gravity = 19; // Constantes de mouvement sur X _velocity[0] = 0.0; _mult[0] = 10; _dec[0] = .7; _acc[0] = .6; _min_vel[0] = 0.1; _max_vel[0] = 10; // Constantes de mouvement sur Y _velocity[1] = 0.0; _mult[1] = 50; _dec[1] = .3; _acc[1] = 2; _min_vel[1] = 0.2; _max_vel[1] = 100; // On definit les frames de l'animation par defaut this->addFrame( (SDL_Rect){238, 0, 19, 29} ); this->addFrame( (SDL_Rect){329, 0, 19, 29} ); } /* [MOVEFROMVELOCITY] Applique la velocite au deplacement =========================================================*/ void xMarioMario::moveFromVelocity(){ /* (1) Si aucune collision, on deplace */ vector after = this->move(_velocity[0], _velocity[1]); // if( _velocity[0] != after[2] && after[0] != 0 ) // cerr << "collision from " << ((after[0]==1)?"right":"left") << " at " << (_dst.x+after[2]) << endl; // if( _velocity[1] != after[3] && after[1] != 0 ) // cerr << "collision from " << ((after[1]==1)?"bottom":"top") << " at " << (_dst.y+after[3]) <turn(); /* (4) Gestion de touche encore enfoncee */ if( _left ) this->velocity(-1, 0); else if( _right ) this->velocity(1, 0); // diminution de l'acceleration quand on lache <- ET -> else _velocity[0] *= ( 1 - _dec[0] ); // Si touche haut if( _up ){ // Si au sol et premier saut ou autre saut (pour la hauteur) if( this->onFloor() && _jumps == 0 || _jumps == 1 ){ this->velocity(0, -1); _jumps++; } }else _jumps = 0; /* (5) On diminue la gravite */ _velocity[1] *= ( 1 - _dec[1] ); /* (6) Gestion de la gravite */ if( !this->onFloor() ) this->move(0, _gravity); /* (7) Si velocite sous borne min, on met a 0 */ if( abs(_velocity[0]) < _min_vel[0] ) // sur x _velocity[0] = 0; if( abs(_velocity[1]) < _min_vel[1] ) // sur y _velocity[1] = 0; /* (8) Gestion du temps */ // if( abs(_velocity[0]) > 0 ) // cerr << "x -> " << _velocity[0] << endl; // if( abs(_velocity[1]) > 0 ) // cerr << "y -> " << _velocity[1] << endl; // cout << endl; // usleep(20000); } /* [VELOCITY] Retourne un pointeur sur la velocite =========================================================*/ double xMarioMario::velocity(bool way){ // (way) ? HORIZONTAL : VERTICAL return (way) ? _velocity[0] : _velocity[1]; } /* [VELOCITY] Modifie la velocite =========================================================*/ void xMarioMario::velocity(double x, double y){ double last[] = { _velocity[0], _velocity[1] }; // Vrai si on change pas de sens sur X bool sameway_x = (last[0]*x) > 0; // Vrai si on change pas de sens sur y bool sameway_y = (last[1]*y) > 0; /* (1) Gestion velocite axe X */ if( sameway_x ) // Si meme sens, on accelere _velocity[0] *= (1+_acc[0]); else _velocity[0] += x * _mult[0]; /* (2) Gestion velocite axe Y */ if( sameway_y ) // Si meme sens, on accelere _velocity[1] *= (1+_acc[1]); else _velocity[1] += y * _mult[1]; /* (3) On borne la velocite aux max */ if( abs(_velocity[0]) > _max_vel[0] ) // Si max x _velocity[0] = _max_vel[0] * (_velocity[0] / abs(_velocity[0]) ); if( abs(_velocity[1]) > _max_vel[1] ) // Si max y _velocity[1] = _max_vel[1] * (_velocity[1] / abs(_velocity[1]) ); } bool xMarioMario::onFloor(){ return _manager->hit((xSprite*)this, 0, 1); } /* [TURN] Gestion des sprites en fonction du mouvement =========================================================*/ void xMarioMario::turn(){ /* (0) Variables utiles */ bool left = _velocity[0] < 0; // si vers la gauche bool up = _velocity[1] < 0; // si vers le haut bool centerx = _velocity[0] == 0; // centre sur x bool centery = _velocity[1] == 0; // centre sur y /* (1) Vers le haut */ if( up && !this->onFloor() ){ /* (1.2) HAUT - CENTRE */ if( centerx ){ // tc if( _pos != "TC" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){300, 0, 19, 29} ); this->addFrame( (SDL_Rect){300, 0, 19, 29} ); this->push(_index); _pos = "TC"; return; } /* (1.1) HAUT - GAUCHE */ }else if( left ){ // tl if( _pos != "TL" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){31, 0, 19, 29} ); this->addFrame( (SDL_Rect){31, 0, 19, 29} ); this->push(_index); _pos = "TL"; return; } /* (1.2) HAUT - DROITE */ }else{ // tr if( _pos != "TR" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){300, 0, 19, 29} ); this->addFrame( (SDL_Rect){300, 0, 19, 29} ); this->push(_index); _pos = "TR"; return; } } /* (2) Vers le bas */ }else if( !centery ){ /* (2.2) BAS - CENTRE */ if( centerx && !this->onFloor() ){ // bc if( _pos != "BC" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){122, 160, 19, 29} ); this->addFrame( (SDL_Rect){122, 160, 19, 29} ); this->push(_index); _pos = "BC"; return; } /* (2.1) BAS - GAUCHE */ }else if( left ){ // bl if( _pos != "BL" ){ return; } /* (2.2) BAS - DROITE */ }else{ // br if( _pos != "BR" ){ return; } } /* (3) Droit */ }else{ /* (3.2) NORMAL - CENTRE */ if( centerx ){ // nc if( _pos != "NR" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){238, 0, 19, 29} ); this->addFrame( (SDL_Rect){329, 0, 19, 29} ); this->push(_index); _pos = "NR"; return; } /* (3.1) NORMAL - GAUCHE */ }else if( left ){ // nl if( _pos != "NL" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){2, 0, 19, 29} ); this->addFrame( (SDL_Rect){93, 0, 19, 29} ); this->push(_index); _pos = "NL"; return; } /* (3.2) NORMAL - DROITE */ }else{ // nr if( _pos != "NR" ){ this->pull(); this->clear(); this->addFrame( (SDL_Rect){238, 0, 19, 29} ); this->addFrame( (SDL_Rect){329, 0, 19, 29} ); this->push(_index); _pos = "NR"; return; } } } }