lab.cpp/SDL#4/xMario/xMarioMario.cpp

350 lines
6.8 KiB
C++

/* [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
}
){
this->setType("Mario");
_left = false;
_right = false;
_up = false;
_down = false;
_jumps = 0;
// Position frame par defaut
_pos = "NR"; // bottom-center
_gravity = 8;
// Constantes de mouvement sur X
_velocity[0] = 0.0;
_mult[0] = 10;
_dec[0] = .7;
_acc[0] = 1.6;
_min_vel[0] = 0.1;
_max_vel[0] = 10;
// Constantes de mouvement sur Y
_velocity[1] = 0.0;
_mult[1] = 40;
_dec[1] = .3;
_acc[1] = 3;
_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<int> after;
after = this->move(_velocity[0], _velocity[1]);
/* (2) On modifie la velocite en fonction des collisions */
_velocity[0] = (double) after[2];
_velocity[1] = (double) after[3];
/* (3) Modification du sprite en fonction du mouvement */
this->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 */
// TROUBLE
// TROUBLE
// TROUBLE
if( !this->onFloor() )
_velocity[1] += _gravity;
cout << "ON FLOOR: " << this->onFloor() << endl;
// TROUBLE
// TROUBLE
// TROUBLE
/* (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] *= _acc[0];
else
_velocity[0] += x * _mult[0];
/* (2) Gestion velocite axe Y */
if( sameway_y ) // Si meme sens, on accelere
_velocity[1] *= _acc[1];
else
_velocity[1] += (y>0) ? y : 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;
}
}
}
}
/* [ONCOLLIDE] Gestion des collisions
=========================================================*/
void xMarioMario::onCollide(vector<int> from, xSprite* by){
/* (1) Mort par carapace */
if( by->getType() == "green-shell" && from[0] != 0 )
cout << "MORT" << endl;
/* (2) Casse la carapace */
if( by->getType() == "green-shell" && from[1] == -1 )
by->pull();
}