STRUCTURER LES OBJETS DE VOTRE PROGRAMME

By jicehel, 5 years ago

Vous avez ajouté votre premier adversaire en lui donnant de l'intelligence artificielle, le jeu est jouable alors commençons à nous structurer pour le prochain qui sera plus compliqué.


Durée :      30 minutes (et plus si affinité)

Niveau :      débutant (mais bon plus tant que ça déjà)

Prérequis :

Dans l'atelier précédent, Artificial intelligence (Pong), vous avez ajouté un adversaire à votre jeu en lui programmant un comportement. Nous avions également rajouté une seconde raquette qui avait les mêmes propriétés que la première mais avec des valeurs différentes.

Avant de compliquer un peu le programme, nous allons voir une autre façon de coder ses propriétés d’un objet : les structures



Les structures

Vous pouvez créer vos propres types de variables. Des « types de variables personnalisés » permettant de de s’y retrouver plus facilement quand on cherche à faire des programmes plus complexes.

En effet dans les tutoriaux, on a bien pris soin d’utiliser des noms parlant comme balle_posX ou balle_posY, mais une autre solution consiste à utiliser un « objet » balle ayant des propriétés définies.



Définir une structure

Une structure est un assemblage de variables qui peuvent avoir différents types : long, char, int, double, …

Une définition de structure commence par le mot-clé struct, suivi du nom de votre structure (par exemple s_balle, ou s_raquette).

On peut également adopter des règles de nommage pour ces structures. Par exemple, on peut choisir de mettre la première lettre en majuscule pour pouvoir faire la différence ou lui mettre un préfixe (par exemple s_).

Après le nom de votre structure, vous ouvrez les accolades et les fermez plus loin, comme pour une fonction.

Attention, ici c'est particulier : vous DEVEZ mettre un point-virgule après l'accolade fermante.

Vous ajoutez ensuite les variables dont est composée votre structure.

Faisons un exemple complet :

Pour la balle, nous utilisions 5 variables :

// Caractéristiques de la balle
int balle_posX = 20;
int balle_posY = 20;
int balle_speedX = 1;
int balle_speedY = 1;
int balle_taille = 3;

Nous allons les transformer en structure, nous allons donc définir son nom en tant que s_balle et y mettre 5 variables de type entier : posX, posY, vitesseX, vitesseY et taille, ce qui nous donne le code suivant :

// Définition des structures balles et raquette
struct s_balle{int posX; int posY; int vitesseX; int vitesseY; int taille;};

Comme vous le voyez, la création d'un type de variable personnalisé n'est pas bien complexe. Toutes les structures que vous verrez sont en fait des « assemblages » de variables de types définis (long, int, double, etc…)

OK, on a défini une structure mais bon on n’a toujours pas de valeur et pour cause, on doit maintenant définir une variable de ce type que l’on pourra alors initialiser, mais voyons ça plus en détail…


Utiliser une structure

Maintenant que notre structure s_balle est définie, on va pouvoir l'utiliser en créant une variable de ce type :

// Définition des objets utilisant les structures définies
s_balle balle;

Nous avons ainsi créé une variable balle de type s_balle. Cette variable est automatiquement composée de cinq sous-variables : posX, posY, vitesseX, vitesseY et taille (respectivement son abscisse, son ordonnée, sa vitesse latérale, sa vitesse horizontale et sa taille en pixels).

Maintenant que notre variable balle est créée, nous voulons modifier ses coordonnées.
Comment accéder aux variable posX et posY de la variable balle?

Comme ceci :

// Caractéristiques de la balle
balle.posX = 20; balle.posY = 20;

On a ainsi modifié balle, en lui donnant une abscisse de 20 et une ordonnée de 20.

Pour accéder donc à chaque composante de la structure, vous devez écrire :

variable.nomDeLaComposante

Le point sert de séparation entre la variable et la composante à laquelle on souhaite accéder.

Pour les structures comme pour les variables, l'initialisation peut également se faire un peu comme pour un tableau en enchainant entre accolades les valeurs des composantes, séparées par des virgules dans l’ordre de leur déclaration.

Pour la balle, cela nous donnerait donc :

// Définition des objets utilisant les structures définies
s_balle balle = {20, 20, 1, 1, 3};


Cela définira, dans l'ordre, de déclaration les composantes de l’objet, c’est-à-dire posX, posY, vitesseX, vitesseY et taille.



Synthèse avec le programme Pong

A vous de jouer: Essayez d’utiliser ce que l’on vient de voir pour déclarer 1 structure raquette et de l'utiliser pour la raquette gauche et la raquette de droite.



Solution

Note: La solution utilise aussi les constantes vues dans le tutoriel: Tap tap


#include 

// Définition des constantes #define EspaceBordRaquette 10 #define HauteurRaquette 10 #define LargeurRaquette 3 #define MargeInitialeBalleX 20 #define MargeInitialeBalleY 20

// Définition des structures balles et raquette struct s_balle{int posX; int posY; int vitesseX; int vitesseY; int taille;}; struct s_raquette{int posX; int posY; int largeur; int hauteur; int vitesse;};

// Définition des objets utilisant les structures définies s_balle balle = {MargeInitialeBalleX,MargeInitialeBalleY,1,1,3}; s_raquette raquetteAGauche = {EspaceBordRaquette,((gb.display.height()-HauteurRaquette) / 2),LargeurRaquette,HauteurRaquette,0}; s_raquette raquetteADroite = {(gb.display.width() - EspaceBordRaquette - LargeurRaquette),((gb.display.height()-HauteurRaquette) / 2),LargeurRaquette,HauteurRaquette,0};

// Scores int scoreGauche; // Score du joueur 1 int scoreDroite; // Score du joueur 2

int difficulte = 3; // Niveau de difficulté. 3 = FACILE et 2 = DIFFICILE

void setup() { gb.begin(); }

void loop() { while (!gb.update()); gb.display.clear();

// Changement de difficulté if (gb.buttons.pressed(BUTTON_MENU)) { if (difficulte == 3) { // Facile difficulte = 2; // Changer de difficulté } else { // Difficile difficulte = 3; // Changer de difficulté } }

// MAJ raquetteAGauche if (gb.buttons.repeat(BUTTON_UP, 0)) { raquetteAGauche.posY = raquetteAGauche.posY - 1; }

if (gb.buttons.repeat(BUTTON_DOWN, 0)) { raquetteAGauche.posY = raquetteAGauche.posY + 1; }

// MAJ raquetteADroite - Intelligence Artificielle if (balle.posY > raquetteADroite.posY + raquette_hauteur / 2 && random(0, difficulte) == 1) { raquetteADroite.vitesse = 2; } else if (balle.posY < raquetteADroite.posY + raquette_hauteur / 2 && random(0, difficulte) == 1) { raquetteADroite.vitesse = -2; } raquetteADroite.posY = raquetteADroite.posY + raquetteADroite.vitesse; // Mettre à jour la position de la raquetteADroite

// MAJ balle balle.posX = balle.posX + balle.vitesseX; balle.posY = balle.posY + balle.vitesseY;

// Collisions avec les murs (haut et bas) if (balle.posY < 0) { balle.vitesseY = 1; } if (balle.posY > gb.display.height() - balle_taille) { balle.vitesseY = -1; }

// Collision balle/raquetteAGauche if ( (balle.posX == raquetteAGauche.posX + raquette_largeur) && (balle.posY + balle_taille >= raquetteAGauche.posY) && (balle.posY <= raquetteAGauche.posY + raquette_hauteur) ) { balle.vitesseX = 1; } // Collision balle/raquetteADroite if ( (balle.posX + balle_taille == raquetteADroite.posX) && (balle.posY + balle_taille >= raquetteADroite.posY) && (balle.posY <= raquetteADroite.posY + raquette_hauteur) ) { balle.vitesseX = -1; }

// Vérifier si la balle est sortie de l'écran if (balle.posX < 0) { // Replacer la balle sur l'écran balle.posX = MargeInitialeBalleX; balle.posY = random(MargeInitialeBalleY, gb.display.height() - MargeInitialeBalleY); // Position aléatoire au centre de l'écran balle.vitesseX = 1; if (random(0, 2) == 1) { // 50% du temps balle.vitesseY = 1; } else { // 50% du temps balle.vitesseY = -1; }

// incr&eacute;menter le score du joueur 2
scoreDroite = scoreDroite + 1;

} if (balle.posX > gb.display.width()) { // Replacer la balle sur l'écran balle.posX = MargeInitialeBalleX; balle.posY = random(MargeInitialeBalleY, gb.display.height() - MargeInitialeBalleY); // Position aléatoire au centre de l'écran balle.vitesseX = 1; if (random(0, 2) == 1) { // 50% du temps balle.vitesseY = 1; } else { // 50% du temps balle.vitesseY = -1; }

// incr&eacute;menter le score du joueur 1
scoreGauche = scoreGauche + 1;

}

// Afficher la balle gb.display.fillRect(balle.posX, balle.posY, balle_taille, balle_taille); // Afficher la raquetteAGauche gb.display.fillRect(raquetteAGauche.posX, raquetteAGauche.posY, raquetteAGauche.largeur, raquetteAGauche.hauteur); // Afficher la raquetteADroite gb.display.fillRect(raquetteADroite.posX, raquetteADroite.posY, raquetteADroite.largeur, raquetteADroite.hauteur);

// Afficher les scores gb.display.setCursor(35, 5); gb.display.print(scoreGauche); gb.display.setCursor(42, 5); gb.display.print(scoreDroite);

// Afficher la difficulté gb.display.setCursor(33, gb.display.height() - 5); if (difficulte == 3) { gb.display.print("Facile"); } else { gb.display.print("Difficile"); } }

Last comments

avatar
2 years ago

Merci @Jicehel ,
On a jamais trop de tutos !

avatar
Jicehel
2 years ago

Je suis tombé sur ce petit tuto que j’avais fait il y a 3 ans… alors je le ressort du chapeau si ça intéresse quelqu’un :slight_smile: