Avant d'entamer ce défi, assure-toi d'avoir déjà fait ceux-ci:

Aussi, assure-toi que tu sois bien connecté à ton compte Repl.It, et que tu aies ton projet de la fois passée.

Le jeu est trop facile pour l'instant tu ne trouves pas? On pourrait ajouter des piques pour le rendre plus compliqué!

Première étape: dessine tes piques. Tu peux le faire, comme avant, sur pixilart.com, mais si tu préferes un autre site ou télécharger une image, c'est ton choix! Voici mes super piques:

Spike

Ensuite, charge l'image dans ton code, grâce à la commande this.load.image


              this.load.image("NOM DE L'OBJET", "NOM DE L'IMAGE");
            

Ce code doit bien sûr apparaître dans la fonction preload.

Ensuite, on va créer un groupe de piques (spikes en anglais). De cette façon, on pourra facilement en ajouter plusieurs sans devoir trop changer notre code. Te rappelles-tu comment on avait fait pour créer un groupe de plateformes?


                  this.platforms = this.physics.add.staticGroup();
                

Note bien que platforms est au pluriel, car il y a plusieurs plateformes.

Pour créer un groupe de piques, ton code sera très similaire.


                  this.spikes = this.physics.add.staticGroup();
                

Maintenant que le groupe est créé, tu peux créer tes piques individuelles en utilisant this.spikes.create. Il faut indiquer les coordonnées et l'objet à faire apparaître (spawn en anglais).


              this.spikes.create(X, Y, "NOM DE L'OBJET");
            

Normalement, si tu as tout bien fait, les piques apparaîssent sur ton écran mais n'ont aucun effet sur le joueur. Changeons cela!

On va ajouter un chevauchement (overlap en anglais) entre le joueur et les piques, comme on l'avait fait pour la pièce gagnante dans la fiche précédente.


              this.physics.add.overlap(this.player, this.spikes, function(player, coin) {
                // Ce qui se passe lorsqu'on touche une pique
              }, null, this);
            

Que doit-il se passer lorsqu'on touche une pique? Notre joueur doit revenir au début du jeu. Pour cela, tu dois changer ses coordonnées X et Y:


              this.player.x = /*quelque chose*/;
              this.player.y = /*quelque chose*/;
            

Et voilà, on a des piques! Pas si dur que ça au final, n'est-ce pas?

C'est long de devoir écrire une ligne de code par objet qu'on veut faire apparaître sur notre carte, non? Ce serait plus simple si on pouvait dessiner une grille de notre carte que notre programme utiliserait pour créer la carte "automatiquement"...

Regarde cette grille:


              '11111111111111111111111111'+
              '1               c        1'+
              '1    c     c     s     c 1'+
              '1 2  1  s  1  c  1  c  1 1'+
              '1 1     1     1     1    1'+
              '1                        1'+
              '1    c     c     s     s 1'+
              '1 c  1  s  1  c  1  c  1 1'+
              '1 1     1     1     2    1'+
              '1                        1'+
              '1    c     s     c     c 1'+
              '1 s  2  c  1  c  1  s  1 1'+
              '1 1     1     1     1    1'+
              '1                        1'+
              '1   c       c     c   c  1'+
              '11111111111111111111111111';
            

Peux-tu deviner à quoi correspondent les 1, 2, c et les s?

Les c correspondent aux pièces (coin en anglais).

Les s correspondent aux piques (spike en anglais).

Les 1 et les 2 correspondent aux plateformes. On verra à l'étape suivante qu'il peut y avoir plusieurs types de plateformes.

Cette grille est super importante! C'est ce qui va nous permettre de créer un grand monde plus rapidement. Pour un très grand monde, on utilisera encore une autre solution... dans les dernières fiches. La première chose que tu dois faire, c'est créer ta propre grille. Commence avec seulement des plateformes (1).

Sauvegarde ensuite ta grille dans une constante qu'on appellera map (carte en anglais). Tu peux déclarer cette constante tout en haut de ton programme, avant même de déclarer la variable config. Voici mon exemple de grille simple:


              const map = '           ' +
                          '      11   ' +
                          '     1     ' +
                          '1 1       1' +
                          '       1   ';
            

Dans la fonction create, tu peux mettre en commentaire (avec les //) la partie où tu faisais apparaître toutes tes plateformes. Si tu lances ton programme, elles ont disparu... c'est normal!

              
              this.platforms = this.physics.add.staticGroup();
              // this.platforms.create(500, 200, "platform");
              // this.platforms.create(300, 100, "platform");
              // this.platforms.create(100, 564, "platform");
              
            

On va faire apparaître nos plateformes en fonction de notre grille sauvegardée dans notre constante map. L'ordinateur va analyser notre grille, ligne par ligne et colonne par colonne. Dans une case, si l'ordinateur voit un espace, il ne fera rien. Par contre, si l'ordinateur voit un 1, il créera une plateforme à cet endroit.

Pour que l'ordinateur sache où positionner exactement les plateformes sur l'écran, on va créer une variable "X" et une variable "Y" . Dans la fonction create, ajoute tes variables:


              let X = 40;
              let Y = 40;
            

Ensuite, on va ajouter deux boucles for... l'une dans l'autre 🤯. Pourquoi???

C'est parce qu'on veut que l'ordinateur analyse chaque ligne de notre grille (première boucle), et pour chaque ligne, on veut qu'il analyse chaque colonne (deuxième boucle).

Commençons par la première boucle (pour analyser chaque ligne de notre grille):


              for (let l = 0; l < 5; l++) {
                // faire quelque chose pour chaque ligne
              }
            

Pourquoi ma boucle se répète-t-elle 5 fois?

Parce que dans mon grille (map), il y a 5 lignes. Si ta grille a 7 lignes, ta boucle ressemblera plutôt à ceci:


                for (let l = 0; l < 7; l++) {
                  // faire quelque chose pour chaque ligne
                }
              

À la fin de chaque ligne, que doit-on faire? Eh oui, passer à la ligne suivante! Pour l'ordinateur, ça veut dire que les coordonnées en Y doivent changer. Comment faire pour faire "descendre" les coordonnées en Y?

On ajoute 40 à notre variable Y


                  for (let l = 0; l < 5; l++) {
                    // faire quelque chose pour chaque ligne

                    // descendre à la ligne suivante:
                    Y += 40;
                  }
                

Nous sommes maintenant prêts à analyser chacune de nos lignes, colonne, par colonne. Or dans chaque ligne, il y a le même nombre de colonnes (11 dans mon grille). Je vais donc ajouter ma deuxième boucle de cette manière:


              for (let l = 0; l < 5; l++) {

                for (let c = 0; c < 11; c++) {
                  // Analyser chacune des case de la grille
                }

                // descendre à la ligne suivante:
                Y += 40;
              }
            

Dans la deuxième boucle, on va dessiner les plateformes. Mais attention! L'ordinateur doit créer une plateforme uniquement si le caractère dans la case qu'il analyse est un 1. On va donc créer une variable pour ce caractère et ensuite on dessine un bloc s'il vaut "1".


              let ca = map[11*l + c];
              if (ca === '1') {
                this.platforms.create(X, Y, "platform");
              }
            

              let ca = map[11*l + c];
              if (ca === '1') {
                this.platforms.create(X, Y, "platform");
              }
            

De nouveau, si tu n'as pas 11 colonnes (ou caractères) par ligne, change le 11 en un autre nombre.

Pour passer à la case suivante, il suffit d'incrémenter notre valeur en X:


              let ca = map[11*l + c];
              if (ca === '1') {
                this.platforms.create(X, Y, "platform");
              }
              let ca = map[11*l + c];
              if (ca === '1') {
                this.platforms.create(X, Y, "platform");
              }

              // passer à la case suivante:
              X += 40;
            

Dernière étape: quand on change de ligne, on doit aussi remettre la coordonnée X au début de la ligne.


              for (let l = 0; l < 5; l++) {

                for (let c = 0; c < 11; c++) {
                  // Analyser la case et dessiner une plateforme si nécessaire
                  let ca = map[11*l + c];
                  if (ca === '1') {
                    this.platforms.create(X, Y, "platform");
                  }

                  // passer à la case suivante:
                  X += 40;
                }

                // passer à la ligne suivante:
                Y += 40;
                // aller au début de la ligne suivante:
                X = 40;
              }
            

Maintenant ton code va dessiner toutes les plateformes tout seul!

On pourrait aussi ajouter nos piques dans la carte directement. Pour ce faire, écris un "p" la où tu veux tes piques, et ajoute un else if dans ton code


              if (ca === '1') {
                // ...
              } else if (ca === 'p') {
                // Dessiner une pique aux coordonnées X et Y
              }
            

Challenge: Fais la même chose pour tes pièces!

Tu te demandes sûrement pourquoi on a mis "1" pour les plateformes et non "p" (ou une autre lettre)? C'est parce qu'on pourrait avoir différents types de plateformes. Crée une deuxième plateforme et load-la correctement dans ton code, sous le nom de "platform2"

Ensuite, si le carctère est égal à "2", tu vas simplement créer cette deuxième plateforme.


              if (c === '1') {
                // ...
              } (c === '2') {
                this.platforms.create(X, Y, "platform2");
              }
            

Maintenant, tu peux créer un joli long monde, avec différentes plateformes et obstacles.

Ce serait cool de pouvoir changer l'arrière-plan aussi non? Noir c'est un peu déprimant...

Commence par soit dessiner, soit trouver une image d'arrière-plan qui te plaît! Lorsque c'est le cas, load cette image comme tu as chargé toutes les autres.

Ensuite, dans la fonction create, on va afficher cette image. Assure-toi que c'est la première chose que tu fais, pour qu'elle apparaisse bien derrière tout le reste.


              this.add.image(400, 250, 'background').setDisplaySize(800, 500);
            

On fait apparaître l'image au milieu de l'écran, et on change la taille pour remplir tout l'écran.

Tu verras sûrement que cela ne couvre quand même pas tout l'écran. Pour ce changer, on fait simplement apparaître plusieurs images:


              this.add.image(-1200, 250, 'background').setDisplaySize(800, 500);
              this.add.image(-400, 250, 'background').setDisplaySize(800, 500);
              this.add.image(400, 250, 'background').setDisplaySize(800, 500);
              this.add.image(1200, 250, 'background').setDisplaySize(800, 500);
              this.add.image(1600, 250, 'background').setDisplaySize(800, 500);
            

Voilà, tu as maintenant un joli arrière-plan! Tu peux alors rendre ton jeu aussi long que tu le souhaites :)