Avant de t'attaquer à ce défi, on te conseille de compléter les défis suivants:

  1. En 2020 je serai...
  2. Ça va bien aller
  3. Péter ta balloune

Première chose avant de commencer à travailler sur n'importe quel projet p5.js: connecte-toi à ton compte en cliquant sur "Log in".

Renomme ton projet en cliquant sur le petit crayon .

En cliquant par ici, tu trouveras un aperçu de ce qu'on va coder. À vrai dire, tu viens de voir la solution du défi! Est-ce que c'est tricher? Pas du tout! Lire le code de devs plus avancés fait partie de l'apprentissage!

Ce code contient de nombreuses fonctions. Les fonctions servent à donner des instructions à l'ordinateur et sont très utiles pour ne pas avoir à répéter toujours les mêmes instructions. Tu utilises déjà plein de fonctions dans tes programmes. color(), par exemple, est une fonction qui permet de créer une couleur grâce à la librairie p5.js. ellipse() est une fonction qui dessine une ellipse (ou un cercle). Te souviens-tu de la fonction pour dessiner une ligne?

Eh oui, c'est line().

Tu as peut-être noté que lorsqu'on parle de fonctions, on ajoute des parenthèses ( ) après le nom de la fonction. C'est que les fonctions peuvent prendre des paramètres, que l'on va mettre entre les parenthèses. Voici un exemple:

              
                textSize(50);
              
            

Entre les parenthèses, j'ai ajouté le nombre 50. Ce nombre représente la taille de mon texte. Si j'avais codé

              
                textSize(100);
              
            

mon texte serait deux fois plus grand! Les paramètres sont importants car ils peuvent faire une grosse différence sur le résultat de ma fonction.

Certaines fonctions prennent plusieurs paramètres:

              
                ellipse(150, 130, 100);
              
            

Ici, il y avait trois paramètres 150, 130 et 100. Finalement, certaines fonctions ne prennent aucun paramètre:

              
                noStroke();
              
            

La fonction noStroke() ne prend pas de paramètres, mais on garde quand même les parenthèses pour indiquer que si la fonction prenait des paramètres, c'est là où ils iraient. Et puis, pour nous devs, c'est un bon indice pour savoir que c'est une fonction (et non pas une variable, par exemple).

La plupart du temps, on utilise des fonctions qui existent déjà dans la librairie p5.js. color(), noStroke(), ellipse(), etc. sont toutes des fonctions qui existent déjà!

Tu peux toujours vérifier si une fonction existe dans la librairie p5.js en allant chercher dans la documentation (la documentation, c'est comme une dictionnaire qui recense toutes les fonctions de la libriarie).

Dans la documentation, tu peux cliquer sur chaque fonction individuellement pour obtenir une description et des exemples (en anglais).

À partir de maintenant, tu devrais toujours avoir un onglet ouvert dans ton navigateur avec la documentation de p5.js. C'est suuuuuuuuper utile!

Parfois, on veut coder nos propres fonctions car elles n'existent pas dans la librairie p5.js ou en JavaScript. Dans ce cas-là, on doit d'abord définir notre fonction en utilisant le mot clé... attention... ça va être très surprenant... le mot clé function!

              
                function drawBubble(positionX, color, letter) {
                fill(color);
                ellipse(positionX, 130, 100);

                // lettre
                textStyle(BOLD);
                textSize(50);
                fill(0,0,0);
                text(letter, positionX-15, 145);
              }
            
          

Ici, j'ai défini la fonction drawBubble() avec trois paramètres (positionX, color et letter. J'ai ensuite ouvert les accolades { } et à l'intérieur j'ai mis les instructions de ma fonction. Note que j'ai utilisé d'autres fonctions à l'intérieur de ma fonction drawBubble() 🤯

Après cette longue introduction, revenons à nos moutons 🐑 🐑 🐑 🐑! Notre code contient de nombreuses fonctions. Seize (16) pour être exact! Peux-tu les trouver toutes? Insère-les dans le formulaire suivant et clique sur Corriger.

Pour donner un peu de peps à notre animation, on va insérer une image en arrière-plan. Voici les étapes:

  1. trouver une photo sur internet;
  2. télécharger la photo sur ton ordinateur;
  3. importer le fichier de ta photo dans ton projet p5.js;
  4. insérer la photo dans ton code.

Pour trouver une belle image (gratuite!) tu peux aller sur le site Unsplash et taper soap bubbles (bulle de savon en anglais).

Tu peux bien entendu aussi trouver une image en allant dans un moteur de recherche de ton choix. Télécharge l'image sur le Bureau de ton ordinateur, par exemple.

Pour importer le fichier de ta photo dans ton projet p5.js, tu peux créer un dossier "assets":

Dans le dossier assets, charge ton image.

Dernière étape: le JavaScript! Dans ton code, rajoute les lignes suivantes:

            
              let img;

              function preload() {
                img = loadImage('assets/XXXX');
              }

              function setup() {
                createCanvas(400, 400);
                image(img, 0, 0);
              }
            
          

Si l'image est trop grande, tu peux changer sa taille avec la fonction resize():

        
          function setup() {
          createCanvas(400, 400);
          img.resize(400, 0);
          image(img, 0, 0);
        }
      
    

Rappelle-toi que tu peux également changer la taille du canevas grâce à la fonction createCanvas().

Crée ta première bulle dans la fonction draw()! Quelle fonction peux-tu utiliser dessiner un cercle?

Tu peux soit utiliser la fonction circle() ou la fonction ellipse().

Fais en sorte qu'on ne voit pas les contours de la bulle.

Tu peux utilser la fonction noStroke()

Tu peux utiliser la fonction fill() pour donner une couleur à ta bulle. Pour donner un aspect plus "véridique" à ta bulle, essaye de lui donner une couleur légèrement transparente.

Pour une couleur transparente, il faut d'abord trouver le code de la couleur en RGB (RED, GREEN, BLUE):

        
          
          rgb(0, 255, 0)
        
      

Pour ajouter de la transparence, on utilise le code RGBA, c'est à dire le code RGB avec en plus un quatrième nombre entre 0 et 1. Ce quatrième nombre détermine l'opacité de notre couleur.

        
          
          rgba(0, 255, 0, 0.6)
        
      

Combiné avec la fonction color() de p5.js, on obtient une couleur qu'on stocke dans la variable bubbleColor et qu'on utilise ensuite dans la fonction fill():

        
          
          let bubbleColor = color('rgba(0, 255, 0, 0.6)');
          fill(bubbleColor);
        
      

En t'inspirant de l'étape 8 du défi Péter ta balloune, peux-tu faire bouger la bulle vers la gauche ou vers la droite?

Tu auras besoin d'une variable pour stocker la position sur l'axe des x de ta bulle. Tu devras également changer la valeur de la position en x à chaque fois que la fonction draw() est appelée (c'est à dire au moins 30 fois par secondes).

Ton code aura l'air de ceci:

            
            let positionX = 200;

            function setup() {
              // ton code merveilleux
            }

            function draw() {
              // ton code merveilleux

              // pour dessiner le cercle de la bulle:
              circle(positionX, 130, 100);

              // pour faire bouger la bulle (remplace les ????)
              positionX ????;
            }
            
          

Comment afficher une lettre dans la bulle?

Tu auras besoin de la fonction text().

Si j'ajoute ceci à la foncton draw(), je vais avoir une lettre statique (qui ne bouge pas):

        
        function draw() {
          // le reste de ton merveilleux code

          //pour dessiner la bulle
          circle(positionX, 130, 100);

          // pour faire bouger la bulle
          positionX--;

          // pour afficher une lettre
          text("S", 200, 200);
        }
        
      

Non seulement la lettre ne bouge pas, mais en plus elle est toute petite! Il nous faut une loupe pour la voir! 🔎

A. Agrandir et changer la couleur de la lettre

En consultant la documentation, peux-tu trouver une fonction qui te permette de choisir la taille du texte (en anglais, le mot taille se dit size)?

C'est la fonction textSize(). Le code suivant aggrandira le texte à la taille 50, par exemple:

            
            textSize(50);
            text("S", 300, 50);
            
          

Tu peux également mettre ta lettre en gras grâce à la fonction textStyle(BOLD);

Finalement, change la couleur de la lettre grâce à la fonction...

fill()

Pour que la couleur de ta lettre soit noire, tu peux coder ceci: fill("black");

B. Positionner la lettre au centre de la bulle

Pour réussir cette étape, il vaut mieux que notre bulle soit immobile, dans sa position de départ. Quelle ligne de ton code dois-tu commenter pour immobiliser ta bulle?

            
            // positionX--;
            
          

Maintenant, il te sera plus aisé de positionner ta lettre dans la bulle. En changeant les paramètres x et y de ta fonction text(), tu devrais y arriver!

À ton avis, pourquoi ai-je choisi les valeurs 320 et 130?

Parce que ce sont les coordonnées de départ de mon cercle!

C. Faire bouger la lettre avec la bulle

Maintenant que la lettre est dans la bulle, comment la faire bouger avec la bulle?

Observe bien ma fonction circle():

        
        circle(positionX, 130, 100);
        
      

Remarque que dans mon code, le premier argument est la variable positionX. L'ordinateur va remplacer la variable avec la valeur qui s'y trouve. Si on a stocké la valeur 320, l'ordinateur va exécuter l'instruction circle(320, 130, 100);

Si on a stocké dans la variable positionX la valeur 69, l'ordinateur va exécuter l'instruction circle(69, 130, 100); et ainsi de suite...

En combinaison avec l'instruction positionX--; tu obtiens un cercle qui se déplace vers la gauche.

Pour ta lettre, tu peux aussi faire la même chose! Au lieu d'écrire text("S", 320, 130); tu peux remplacer le 320 par une variable: text("S", ????, 130);. Quelle est cette variable?

Tu n'as pas besoin de créer une nouvelle variable! Tu peux utiliser une variable qui te donne la position sur l'axe des x...

            
            text("S", positionX, 130);
            
          

Ajoutons une deuxième bulle avec une couleur et une lettre différentes.

Dans ta fonction draw(), tu peux commencer par ajouter une bulle immobile.

            
            function draw() {
              image(img, 0, 0);

              noStroke();

              // bulle blanche
              bubbleColor = color('rgba(255, 255, 255, 0.6)');
              fill(bubbleColor);
              circle(positionX, 130, 100);

              // lettre de la bulle blanche
              textStyle(BOLD);
              textSize(50);
              fill("black");
              text("S", positionX, 130);

              // faire bouger la bulle blanche et sa lettre
              positionX --;

              // bulle rouge
              bubbleColor = color('rgba(XXXX, YYYY, ZZZZ, 0.6)');
              fill(bubbleColor);
              circle(320, 130, 100);
            }
            
          

Remplace les XXXX, YYYY et ZZZZ par les valeurs appropriées pour créer la couleur rouge.

Comment faire bouger cette bulle? On pourrait utiliser la variable positionX, comme pour la première bulle:

        
        // bulle rouge
        bubbleColor = color('rgba(255, 0, 0, 0.6)');
        fill(bubbleColor);
        circle(positionX, 130, 100);
        
      

Le problème, c'est que les deux bulles ont la même position en sur l'axe horizontal et vertical... en conséquence, on les voit superposées:

Conclusion: les positions sur l'axe horizontal (x) doivent être indépendantes. Ceci veut dire qu'on doit avoir deux variables différentes.

À ton avis, comment créer une variable pour notre deuxième bulle?

            
            let positionX = 320;
            let positionRedX = 320;

            function setup() {
              // le code de la fonction setup()
            }

            function draw() {
              // le code de la première bulle

              // code de la deuxième bulle (rouge)
              bubbleColor = color('rgba(255, 0, 0, 0.6)');
              fill(bubbleColor);
              circle(positionRedX, 130, 100);

              // faire bouger la bulle rouge
              ????
            }
            
          

Arrives-tu à deviner comment faire bouger la deuxième bulle?

Pour faire bouger ta deuxième bulle, tu peux ajouter la ligne suivante:

            
            positionRedX--;
            
          

On a deux variables, mais les bulles sont encore superposées! Et si la bulle rouge avançait deux fois plus vite que la première bulle?

Essaie avec ceci:

            
            positionRedX -= 2;
            
          

Bon, ça ne règle pas notre problème, mais au moins, les deux bulles sont indépendantes!

Pour que la bulle rouge parte après la première bulle, il faut utiliser une condition. Si la première bulle a déjà fait assez de chemin, alors on dessine la bulle rouge et on la fait bouger. Comment traduire cela en code?

            
            if (positionX < ???) {
            // code de la deuxième bulle (rouge)
              bubbleColor = color('rgba(255, 0, 0, 0.6)');
              fill(bubbleColor);
              circle(positionRedX, 130, 100);

              // faire bouger la bulle rouge
              positionRedX--;
            }
            
          

Il ne te reste plus qu'à ajouter une lettre dans ta deuxième bulle et le tour est joué!

Tu peux maintenant créer autant de bulles que tu veux!

Pour faire en sorte que les bulles ne se superposent pas, tu devras créer une variable pour stocker la position en x de chacune des bulles.

Tu auras également besoin de plusieurs conditions!

Tes bulles s'affichent correctement avec une lettre dans chaque? Chouette! Il est maintenant temps de refactorisé ton code en utilisant... au moins une fonction!

Observe ton code. Quelles lignes se répètent? Quand des lignes de code se répètent, c'est souvent une bonne idée de créer une fonction qui contient ces lignes et que l'on pourra appeler (utiliser) à plusieurs endroits.