STRUCTURER LES OBJETS DE VOTRE PROGRAMME

Creations

jicehel

1 week 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é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é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");
  }
}

View full creation

clement

NEW 1 week ago

juste my two cent : 

tu dit a la fin 

A vous de jouer: Essayez d’utiliser ce que l’on vient de voir pour déclarer 3 objets (la balle mais ça on l’a déjà fait dans l’exemple), la raquette de gauche, la raquette de droite pour l’ordinateur.


mais il serais plus judicieux de dire 

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 

cela amene a la réutilisation de son code

jicehel

NEW 1 week ago

Pas faux, je modifie  ;)

Please log in to join the discussion!

Log in