Academy
Blockbreaker (C++ 5/5)
Des trucs dans des trucs
This content is not fully available in your language 😕

Des trucs dans des trucs

Step 2

Comment représenter le reste des briques ?

Pour avoir plusieurs lignes, on pourrait copier-coller le code qui nous a permis de faire une rangĂ©e. 8 copier-coller = 8 rangĂ©es. Mais, comme nous l'avons dit plusieurs fois auparavant, si on se retrouve Ă  copier-coller, c'est que ce n'est pas la bonne approche. Alors comment allons-nous mĂ©moriser une grille de briques ?

Pour trouver la rĂ©ponse il faut penser Ă  ce que nous avons fait jusqu'Ă  prĂ©sent, et ce qu'il nous manque. Nous avons une rangĂ©e de briques. Il nous faut un certain nombre de rangĂ©es. Logiquement, on devrait crĂ©er un tableau de rangĂ©es. Or chaque rangĂ©e est elle-mĂȘme un tableau. Nous allons donc crĂ©e un tableau de tableaux.

/ Tableau de tableaux d'entiers


int tabDetab[5][3] = { 
    {00, 01, 02}, 
    {10, 11, 12}, 
    {20, 21, 22}, 
    {30, 31, 32},
    {40, 41, 42} };

On peut comprendre pourquoi un tableau de tableaux est souvent appelé tableau 2D, quand on les déclare. Ces tableaux ressemblent à des grilles ou des quadrillages. Et ça tombe bien, nous cherchons justement à faire une "grille" de briques !

// Breakout.ino //

// Raquette //
// Balle //


// Briques. Chaque entier correspond Ă  une couleur
const int GRILLE_TAILLE = 8;  // Grille carré
int briques[GRILLE_TAILLE][GRILLE_TAILLE];  // Tableau 2D
const int BRIQUE_LARGEUR = gb.display.width() / GRILLE_TAILLE - 2;
const int BRIQUE_HAUTEUR = 3;

// setUp() //
// loop() //

Pour ne pas s'emmĂȘler les pinceaux, nous allons travailler avec une grille carrĂ©e de 8 par 8 briques. Chaque brique aura une hauteur de 3 pour ne pas occuper trop de place. Mais les plus gros changements sont dans l'affichage et les dĂ©tections de collisions.

// affichage.ino //
void affichage() {
  for (int rangee = 0; rangee < GRILLE_TAILLE; rangee += 1) {
    for (int colonne = 0; colonne < GRILLE_TAILLE; colonne += 1) {
      if (briques[rangee][colonne] == 0) {
        continue;
      }

      int briqueX = colonne * (BRIQUE_LARGEUR + 2) + 1;
      int briqueY = rangee * (BRIQUE_HAUTEUR + 2) + 1;
      gb.display.fillRect(briqueX, briqueY, BRIQUE_LARGEUR, BRIQUE_HAUTEUR);
    }
  }
}

Et oui ! Pour traverser tous les Ă©lĂ©ments d'un tableau 2D, il faut placer une boucle dans une boucle ! Ça s'appelle des boucles imbriquĂ©es. Ici, nous allons parcourir toutes les rangĂ©es, et pour chaque rangĂ©e, nous allons passer par chacun de ses Ă©lĂ©ments. La tĂąche qui prĂȘte Ă  confusion chez les dĂ©butants est d'accĂ©der au bon Ă©lĂ©ment du tableau 2D.** Pour les tableaux 2D, on place d'abord la rangĂ©e, puis la colonne.** Une maniĂšre de s'en rappeler est de se demander "Que reprĂ©sente briques[0]?" C'est le tout premier Ă©lĂ©ment de notre tableau, c'est une rangĂ©e.

L'autre chose qui change par rapport à la derniÚre fois est la valeur de briqueY. Nos briques ne sont plus toutes alignées. Mais la logique de la formule est analogique à celle pour briqueX.

// miseAJour.ino //
void miseAJour() {
  // MAJ Balle //
  // Collisions avec les murs et raquette //

  // Collisions avec les briques
  for (int rangee = 0; rangee < GRILLE_TAILLE; rangee += 1) {
    for (int colonne = 0; colonne < GRILLE_TAILLE; colonne += 1) {
      if (briques[rangee][colonne] == 0) {  // Ignorer les briques nulles
        continue;
      }

      int briqueX = colonne * (BRIQUE_LARGEUR + 2) + 1;
      int briqueY = rangee * (BRIQUE_HAUTEUR + 2) + 1;
      if (gb.collide.rectRect(balleX, balleY, BALLE_TAILLE, BALLE_TAILLE,
                              briqueX, briqueY, BRIQUE_LARGEUR, BRIQUE_HAUTEUR)) {
        balleVY *= -1;
        briques[rangee][colonne] = 0;  // DĂ©truire la brique

        // Verifier qu'il reste encore des briques
        bool plusDeBriques = true;  // Si cet entier reste vrai, alors il n'y a plus de briques
        for (int x = 0; x < GRILLE_TAILLE; x += 1) {
          for (int y = 0; y < GRILLE_TAILLE; y += 1) {
            if (briques[y][x] == 0) {  // On a trouvé une brique!
              plusDeBriques = false;  // ne pas reinitialiser
            }
          }
        }

        if (plusDeBriques) {
            reinitialiser();
        }
      }

    }
  }


}

void reinitialiser() {
  // Remise Ă  zero de la balle //

  for (int rangee = 0; rangee < GRILLE_TAILLE; rangee += 1) {
    for (int colonne = 0; colonne < GRILLE_TAILLE; colonne += 1) {
      briques[rangee][colonne] = 1;  // Faire réapparaitre toutes les briques
    }
  }
}

Les changements de miseAJour.ino sont les mĂȘmes que ce de affichage.ino. Si vous avez tout suivi jusqu'Ă  prĂ©sent, vous devriez avoir ceci sur votre console :

Maintenant, vous avez un jeu de casse-briques complet, mais avant de vous passer la main, ajoutons deux petites choses dans notre code.

Next step