Vous êtes sur la page 1sur 16

Moudinet Passoret

M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Diagramme Classe UML TP3 (fourni dans le TP) pour la


classe Balle.

Diagramme de classe après ajout de la méthode rebondir() :

a) Ajout d’un constructeur a la classe Balle pour fixer la position initiale de la balle et
son rayon :

Balle::Balle(int x0, int y0, int r)


{
pos_x = x0;
pos_y = y0;
rayon = r;
dx=3;
dy=-2;
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}

int main()
{
sf::RenderWindow Jeu(sf::VideoMode(800, 800), "Jeu de Pong ... M1 3EA"); // La
fenêtre de travail
// Balle B;
//a) Test de la nouvelle fonctionalite avec l'appel du Constructeur d'initialisation
Balle B(100,200,15);

1
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Jeu.clear(sf::Color::Black); //effacer l'aire de jeu


Jeu.display();

//Suite du code…//ajout
}

b) Ajout de la méthode rebondir()

void Balle::rebondir()
{
if (pos_x>=800) {dx = -dx; pos_x = 800-rayon;} //balle a droite
if (pos_y>=800) {dy = -dy; pos_y = 800-rayon;} //balle en bas
if (pos_y<=0) {dy = -dy; pos_y = rayon;} //balle en haut
if (pos_x<=0) {dx = -dx; pos_x = rayon;} //balle a gauche
}

Avec l’ajout de cette méthode dans la méthode move() pour s’assurer qu’à chaque déplacement,
la méthode rebondir() met à jour les paramètres si les conditions sont remplies;

void Balle::move()
{
if (clock.getElapsedTime().asMilliseconds()>=10)
{
pos_x+=dx;
pos_y+=dy;
rebondir();
clock.restart();
}
}

c) Ajout de la classe Raquette{…} : quelques petites modifications ont été apportées a


la classe Balle{} pour adapter a la classe Raquette. Ces modifications sont en gras
ici.

La raquette démarre en position X=15, et Y=0 (haut gauche de l’aire de jeu).

//classe Raquette
class Raquette
{
int dx,dy; //déplacement x, y
int pos_x,pos_y; //position x, y
sf::Clock clock; //pour gérer le temps
sf::Color couleur_trait; // couleur du trait extérieur
sf::Color couleur_remplissage; // couleur de remplissage

2
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
sf::RectangleShape rectangle; // pour le dessin d'un rectangle
//sf::FloatRect boite_englobante; // pour les collision
public:
Raquette();
Raquette(int, int);
void draw(sf::RenderTarget& Jeu);
void move();
void bouger();
};
Raquette::Raquette()
{
pos_x=15;
pos_y=0;
dy=-2;
rectangle.setSize(sf::Vector2f(10,50));
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}
void Raquette::draw(sf::RenderTarget& Jeu)
{
rectangle.setSize(sf::Vector2f(10,50));
rectangle.setFillColor(couleur_remplissage);
rectangle.setOutlineColor(couleur_trait);
rectangle.setOutlineThickness(1);
//rectangle.setOrigin(400, 400); // pour mettre l'origine au centre du cercle, sinon
coin haut gauche carré englobant !
rectangle.setPosition(pos_x, pos_y);
//boite_englobante = rectangle.getGlobalBounds(); // récupère le rectangle englobant pour
gérer les collisions avec la méthode "intersects"
Jeu.draw(rectangle);

void Raquette::move()
{
if (clock.getElapsedTime().asMilliseconds()>=10)
{
bouger();
clock.restart();
}
}

//Constructeur de Raquette permettant de positionner la raquette sur l’aire du Jeu.


Raquette::Raquette(int x0, int y0)
{

3
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
pos_x = x0;
pos_y = y0;
dy=-2;
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}

// rajout de la methode bouger() pour faire deplacer la raquette


void Raquette::bouger()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
pos_y+=dy;
if (pos_y<=0) { pos_y = dy;}//rectangle.getSize().y;} //raquette touche le bord haut
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
pos_y-=dy;
if (pos_y>=Y-rectangle.getSize().y) {pos_y=Y-rectangle.getSize().y;}//raquette touche
le bord bas}
}
};

Après l’exécution, on obtient ceci…

4
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
d) Modification des classes Balle et Raquette pour gérer les collisions entre une balle et
une raquette.
L’utilisation d’un pointeur sur une balle assure qu’on ne copie pas de balle, mais qu’on pointe
sur l’adresse de la balle sur l’aire de jeu.
Les classes Balle et Raquette ont été modifiées avec l’ajout de accesseurs et modificateurs pour
pouvoir obtenir leurs membres privés. Une méthode get_boite_englobante() est ajoutée à
chacune des classes pour permettre d’obtenir leur membre boite_englobante.

//gestion de la collision entre une balle et une raquette


bool collision(Balle* balle, Raquette& raquette)
{
if(balle->get_boite_englobante().intersects(raquette.get_boite_englobante()))
{
balle->set_pos_x(balle->get_rayon()+raquette.get_pos_x());
balle->set_dx(-balle->get_dx());

return true;
}
return false;
}

e) Affichage des points - coder dans le main()

int score = 0; //pour comptabiliser les points


string msg;
sf::Font font; // utilisation de la police venant de la namespace sf.
font.loadFromFile("arial.ttf"); // utilisation de la police « Arial »
// Create a text
sf::Text text("--", font);
text.setCharacterSize(30); //police de taille 30
text.setStyle(sf::Text::Bold); //police en gras
text.setFillColor(sf::Color::White);

//Code pour tester la collision entre Balle et Raquette


//Test de collision entre Balle et raquettes
if(collision(&B,R)){
score++;
msg = to_string(score);
text.setString(msg);
};
//Game Over
if(B.balle_traverse_mur_gauche()){
Jeu.clear();
gameOver.setString("GAME OVER!");
Jeu.draw(gameOver);

5
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
//break;
}
L’acceleration est obtenue en augmentant la valeur de dx, chaque fois que la balle rebondit.
void Balle::rebondir()
{ acceleration+=1;
if (pos_x>=X) {dx = -dx; pos_x = X-rayon;} //balle a droite
if (pos_y>=Y) {dy = -dy; pos_y = Y-rayon;} //balle en bas
if (pos_y<=0) {dy = -dy; pos_y = rayon;} //balle en haut
if (pos_x==0) {dx = -dx-acceleration; pos_x = rayon;} //balle a gauche
}

6
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Defi 2 –
Quelques modifications légères ont été apportées au jeu à une seule raquette pour l’adapter à un
jeu à 2 raquettes.
Cette fois-ci la balle peut traverser aussi le mur droit, et faire un - Game Over !. La méthode
balle_tranverse_mur_gauche() a été modifiée en balle_traverse_mur_gauche_droite() pour tenir
compte du mur droit lorsqu’il y a 2 raquettes.

Le déplacement s’effectue différemment pour les deux raquettes –


Touches gauche / droite pour la raquette de gauche
Touches haut / bas pour la raquette de droite.
Chaque score est affiché.

7
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Diagramme UML final des Classes Balle et Raquette

8
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Code source complet


/////////////////////////////////////////////////////////////////////////////////
int X = 800; //longueur du terrain //
int Y = 800; //largeur du terrain //
//
class Balle;
class Raquette;
bool collision(Balle*, Raquette&); //
//
/////////////////////////////////////////////////////////////////////////////////

//classe Balle
class Balle
{
int dx,dy; //déplacement x, y
int pos_x,pos_y; //position x, y
int rayon; //rayon
sf::Clock clock; //pour gérer le temps
sf::Color couleur_trait; // couleur du trait extérieur
sf::Color couleur_remplissage; // couleur de remplissage
sf::CircleShape circle; // pour le dessin
sf::FloatRect boite_englobante; // pour les collision
int acceleration;
public:
Balle();
Balle(int, int, int);
void draw(sf::RenderTarget& Jeu);
void move();
void rebondir();
sf::FloatRect get_boite_englobante();
int get_pos_x();
int get_pos_y();
int get_rayon();
void set_pos_x(int);
void set_pos_y(int);
void set_dx(int);
int get_dx();
void set_dy(int);
int get_dy();
bool balle_traverse_mur_gauche_droite();
};

Balle::Balle()
{
pos_x=X/2;

9
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
pos_y=Y/2;
dx=3;
dy=-2;
rayon=10;
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}
void Balle::draw(sf::RenderTarget& Jeu)
{
circle.setRadius(rayon);
circle.setFillColor(couleur_remplissage);
circle.setOutlineColor(couleur_trait);
circle.setOutlineThickness(1);
circle.setOrigin(rayon, rayon); // pour mettre l'origine au centre du cercle, sinon coin
haut gauche carré englobant !
circle.setPosition(pos_x, pos_y);
boite_englobante = circle.getGlobalBounds(); // récupère le rectangle englobant pour gérer
les collisions avec la méthode "intersects"
Jeu.draw(circle);

}
void Balle::move()
{
if (clock.getElapsedTime().asMilliseconds()>=10)
{
pos_x+=dx;
pos_y+=dy;
rebondir();
clock.restart();
}
}
//a) ajout de constructeur pour fixer la position et le rayon de la balle
Balle::Balle(int x0, int y0, int r)
{
pos_x = x0;
pos_y = y0;
rayon = r;
dx=3;
dy=-2;
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}

10
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
//b) Rajout de la méthode rebondir
/*
a. Elle touche le mur droit … on inverse son déplacement « dx » et on fixe pox_x avec la valeur
« 800-rayon »
b. Elle touche le mur bas … on inverse son déplacement « dy » et on fixe pox_y avec la valeur «
800-rayon »
c. Elle touche le mur haut … on inverse son déplacement « dy » et on fixe pox_y avec la valeur «
rayon »
d. Elle touche le mur gauche … on inverse son déplacement « dx » et on fixe pox_x avec la
valeur « rayon »
*/
void Balle::rebondir()
{ acceleration+=1;
if (pos_x==X) {dx = -dx; pos_x = X-rayon;} //balle a droite
if (pos_y>=Y) {dy = -dy; pos_y = Y-rayon;} //balle en bas
if (pos_y<=0) {dy = -dy; pos_y = rayon;} //balle en haut
if (pos_x==0) {dx = -dx-acceleration; pos_x = rayon;} //balle a gauche
}

bool Balle::balle_traverse_mur_gauche_droite()
{
if(pos_x<=0 || pos_x>=X){return true;}
return false;
}
//recuperation de la boite englobante de Balle
sf::FloatRect Balle::get_boite_englobante() {return boite_englobante;}

//getters et setters de la classe Balle


int Balle::get_pos_x(){return pos_x;}
int Balle::get_pos_y(){return pos_y;}
int Balle::get_rayon(){return rayon;}
void Balle::set_pos_x(int x) {pos_x = x;}
void Balle::set_pos_y(int y) {pos_y = y;}
void Balle::set_dx(int x){dx=x;}
int Balle::get_dx(){return dx;}
void Balle::set_dy(int y){dy=y;}
int Balle::get_dy(){return dy;}

//classe Raquette
class Raquette
{
int dx,dy; //déplacement x, y
int pos_x,pos_y; //position x, y
sf::Clock clock; //pour gérer le temps
sf::Color couleur_trait; // couleur du trait extérieur
sf::Color couleur_remplissage; // couleur de remplissage

11
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
sf::RectangleShape rectangle; // pour le dessin d'un rectangle
sf::FloatRect boite_englobante; // pour les collisions
bool raquette_droit;
public:
Raquette();
Raquette(int, int, bool);
void draw(sf::RenderTarget& Jeu);
void move();
void bouger();
sf::FloatRect get_boite_englobante();
int get_pos_x();
};
Raquette::Raquette()
{
pos_x=15; //position raquette a 15pts, en haut
pos_y=0;
dy=-2;
//rectangle.setSize(sf::Vector2f(10,100));
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}
void Raquette::draw(sf::RenderTarget& Jeu)
{
rectangle.setSize(sf::Vector2f(10,50));
rectangle.setFillColor(couleur_remplissage);
rectangle.setOutlineColor(couleur_trait);
rectangle.setOutlineThickness(1);
//rectangle.setOrigin(400, 400); // pour mettre l'origine au centre du cercle, sinon
coin haut gauche carré englobant !
rectangle.setPosition(pos_x, pos_y);
boite_englobante = rectangle.getGlobalBounds(); // récupère le rectangle englobant pour
gérer les collisions avec la méthode "intersects"
Jeu.draw(rectangle);

}
void Raquette::move()
{
if (clock.getElapsedTime().asMilliseconds()>=10)
{
bouger();
clock.restart();
}
}

12
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE

Raquette::Raquette(int x0, int y0, bool a_droite=false)


{
pos_x = x0;
pos_y = y0;
dy=-2;
raquette_droit = a_droite;
couleur_trait=sf::Color::White;
couleur_remplissage=sf::Color::White;
clock.restart();
}
// rajout de la methode bouger() pour faire deplacer la raquette
void Raquette::bouger()
{ if(this->raquette_droit){

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
pos_y+=dy;
if (pos_y<=0) { pos_y = dy;}//rectangle.getSize().y;} //raquette touche le bord haut
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
pos_y-=dy;
if (pos_y>=Y-rectangle.getSize().y) {pos_y=Y-rectangle.getSize().y;}//raquette touche
le bord bas}
}

}
else{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
pos_y+=dy;
if (pos_y<=0) { pos_y = dy;}//rectangle.getSize().y;} //raquette touche le bord haut
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
pos_y-=dy;
if (pos_y>=Y-rectangle.getSize().y) {pos_y=Y-rectangle.getSize().y;}//raquette touche
le bord bas}
}
}
}

//recuperation de la boite englobante de Raquette


sf::FloatRect Raquette::get_boite_englobante() {return boite_englobante;}

13
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
//getter et setter de la callse Raquette
int Raquette::get_pos_x(){return pos_x;}

//gestion de la colliision entre une balle et une raquette


bool collision(Balle* balle, Raquette& raquette)
{ //static int score=0;
if(balle->get_boite_englobante().intersects(raquette.get_boite_englobante()))
{
balle->set_pos_x(balle->get_rayon()+raquette.get_pos_x());
balle->set_dx(-balle->get_dx());

return true;
}
return false;
}

//Dans le programme principal

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <string> //pour permettre de convertir les nombre en chaine de caracteres
#include "headers.h" // contient les fichiers d'implementation

using namespace std;

int main()
{ //Code pour l'affichage des points
int score1 = 0; //pour comptabiliser les points
int score2 = 0; //pour comptabiliser les points
string msg1;
string msg2;
sf::Font font;
font.loadFromFile("arial.ttf");
// formatage du text
sf::Text text1("--", font);
sf::Text text2("--", font);
sf::Text gameOver("",font);
text1.setCharacterSize(30);
text1.setStyle(sf::Text::Bold);
text1.setFillColor(sf::Color::White);
text2.setCharacterSize(30);
text2.setStyle(sf::Text::Bold);
text2.setFillColor(sf::Color::White);
gameOver.setCharacterSize(50);

14
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
gameOver.setStyle(sf::Text::Bold);
gameOver.setFillColor(sf::Color::Red);
//Fin de code pour afficher

sf::RenderWindow Jeu(sf::VideoMode(X,Y), "Jeu de Pong ... M1 3EA"); // La fenêtre de


travail
Balle B;
Raquette R1;
Raquette R2(785,0);

//Raquette R2(785,400); //pour la deuxieme raquette


//a) Test de la nouvelle fonctionalite avec l'appel du Constructeur d'initialisation
//Balle B(200,300,10);

Jeu.clear(sf::Color::Black); //effacer l'aire de jeu


Jeu.display();

while (Jeu.isOpen()) // Tant que la fenêtre de travail n'est pas fermée


{
sf::Event event;
while (Jeu.pollEvent(event)) // tant qu'il y a des évènements à traiter...
{
switch (event.type) // quel type d'évènement ?
{
case sf::Event::Closed:
Jeu.close();
break;
case sf::Event::KeyPressed:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{

}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{

}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Add))
{

}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Subtract))
{

}
default :
break;

15
Moudinet Passoret
M2-E3A 2022 UPJV TP3 – GENIE INFORMATIQUE
}
}

Jeu.clear(sf::Color::Black); //effacer l'aire de jeu


B.move();
R1.move();
R2.move();
//Ecrire le score a l'ecran
text1.setPosition(50,20);
text2.setPosition(750,20);
gameOver.setPosition(220,350);
//Test de collision entre Balle et raquettes
if(collision(&B,R1)){
score1++;
msg1 = to_string(score1);
text1.setString(msg1);
};
if(collision(&B,R2)){
score2++;
msg2 = to_string(score2);
text2.setString(msg2);
};
if(B.balle_traverse_mur_gauche_droite()){
Jeu.clear();
gameOver.setString("GAME OVER!");
Jeu.draw(gameOver);
//break;
}
R1.draw(Jeu);
R2.draw(Jeu);
Jeu.draw(text1);
Jeu.draw(text2);
B.draw(Jeu);// puis, dans la boucle de dessin, entre window.clear() et window.display()
Jeu.display(); //afficher l'aire de jeu

}
return 0;
}

16

Vous aimerez peut-être aussi