Academy
Blockbreaker (C++ 5/5)
Nos premières briques
This content is not fully available in your language 😕

Nos premières briques

Step 1

Apprendre à représenter les briques.

Pour comprendre comment nous allons parvenir à avoir une grille de briques, commençons par afficher une simple ligne horizontale sans couleurs, comme ceci :

Des briques alignées ? Cela ressemble beaucoup à notre jeu de TapTap. Pour ce jeu-là, nous avions créé un tableau d'entiers qui représentait les briques.

La différence ici, c'est que nous ne voulons pas savoir si la brique est 'à gauche' ou 'à droite'. Mais plutôt, si la brique existe ou pas ! Et nous n'allons pas nous casser la tête, au début, notre tableau sera rempli de 1, et puis à chaque fois que la balle viendra frapper une brique, sa valeur passera à 0.

// Breakout.ino //

// Raquette //
// Balle //


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

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

Nous allons devoir afficher une ligne de 8 briques. Et à la place de bricoler pour obtenir la largeur parfaite pour que toutes les briques rentrent dans l'écran, on peut tout simplement la calculer ! Enfin, "tout simplement"... Il faut réfléchir pour trouver la bonne formule. En divisant la largeur de l'écran par le nombre de briques on obtient la largeur maximale des briques pour qu'elles rentrent toutes. Mais pour mieux les discerner, on place un trou de 2 pixels entre chaque brique. C'est comme ça qu'on obtient BRIQUE_LARGEUR = gb.display.width() / GRILLE_TAILLE - 2;.

// miseAJour.ino //
void miseAJour() {
  // MAJ balle //
  // Collisions avec murs //
  // Collision avec raquette //

  // Collision avec les briques
  for (int x = 0; x < GRILLE_TAILLE; x += 1) {
    if (briques[x] == 0) {  // Ignorer les briques nulles
      continue;  // 'Continue' force la boucle à passer a recommencer (et donc incrémenter)
    }

    int briqueX = x * (BRIQUE_LARGEUR + 2) + 1;
    int briqueY = 10;  // Hauteur des briques
    if (gb.collide.rectRect(balleX, balleY, BALLE_TAILLE, BALLE_TAILLE,
                            briqueX, briqueY, BRIQUE_LARGEUR, BRIQUE_HAUTEUR)) {
      balleVY *= -1;
      briques[x] = 0;  // Détruire la brique

      // Verifier qu'il reste encore des briques
      bool encoreDesBriques = false;  // Si ce booléen reste faux, alors il n'y a plus de briques
      for (int i = 0; i < GRILLE_TAILLE; i += 1) {
        if (briques[x] == 0) {  // On a trouver une brique!
          encoreDesBriques = true;  // Il reste encore au moins une brique
        }

      }

      if (encoreDesBriques == false) {  // S'il n'y a plus de briques
        reinitialiser();
      }
    }

  }
}

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

  for (int i = 0; i < GRILLE_TAILLE; i += 1) {
    briques[i] = 1;  // Faire réapparaitre toutes les briques
  }
}
// affichage.ino //




void affichage() {
  // raquette //
  // Balle //


  // Briques
  for (int x = 0; x < GRILLE_TAILLE; x += 1) {
    if (briques[x] == 0) {
      continue;  // Passer à la brique suivante
    }


int briqueX = x * (BRIQUE_LARGEUR + 2) + 1;
int briqueY = 20;
gb.display.fillRect(briqueX, briqueY, BRIQUE_LARGEUR, BRIQUE_HAUTEUR);
  



  }
}

Afin de pouvoir afficher et calculer les collisions des briques, il nous faut leur taille et leur position. Toutes les briques ont la même taille (BRIQUE_LARGEUR et BRIQUE_HAUTEUR). Il reste donc la position. Pour cela, nous allons calculer les coordonnées du coin en haut à gauche de chaque brique. Je les ai appelées briqueX et briqueY. Ces variables sont déclarées dans les accolades de notre boucle. Donc **elles n'existent pas **en dehors de ces accolades. Ce fait n'est pas seulement vrai pour les boucles, c'est vrai à chaque fois qu'il y a des accolades. Toutes variables déclarées à l'intérieur de deux accolades n'existent pas à l'extérieur de ces accolades, on appelle ça "la portée" d'une variable.

Il y a deux exceptions. Tout d'abord, les variables statiques, nous vous laissons explorer ce que c'est si vous êtes curieux ;). L'autre exception se trouve dans la boucle for, quand on écrit for (int i = 0; i < var; i += 1) { ... }, on considère que i est déclaré dans les accolades de la boucle.

Pour en revenir au calcul de nos briques, nous pouvons directement définir la position Y des briques. Vu qu'elles sont toutes alignées, on peut simplement leur donner une hauteur de 10 (plus tard, quand nous ajouterons d'autres briques, cette valeur changera). Pour briqueX, il faut pouvoir déterminer sa position en fonction de son indice dans notre tableau. Dans mon code, l'indice s'appelle x. Donc quand x vaut 0, on veut que la brique s'affiche tout à gauche. La brique d'après s'affiche à sa droite, avec un espace de deux pixels, etc. Dans ce cas briqueX = x * (BRIQUE_LARGEUR + 2);. Dans mon code, j'ai ajouté 1 à la position de toutes les briques pour que la première brique ne soit pas collée au bord de l'écran.

Dernière chose à propos de ces deux fichiers. J'utilise le mot clé continue au début de mes boucles. Continue force la boucle ignorer le reste de son code. En termes plus concrets, continue passe à l'indice suivant. Je l'appelle quand il n'y a pas de brique (i.e. brique[x] = 0), car c'est inutile de calculer la position d'une brique inexistante ;)

Et voilà, nous avons complété notre casse-briques ! Mais il n'a qu'une seule rangée de briques... Que dites-vous d'améliorer ça dans la prochaine étape ?

Next step