Cette traduction est incomplète. Aidez à traduire cet article depuis l'anglais.

Dans l'article précédent , nous avons passé en revue, l'essentiel de la théorie de l'objet Javascript et sa syntaxe détaillée,vous donnant ainsi des bases solides sur lesquelles commencer.Dans le présent article nous plongeons dans un exercice pratique afin d'accroître votre savoir-faire dans la construction d'objets entièrement personnalisés donnant un résultat  plutôt amusant et très coloré.

Pré-requis:

Connaissance basique de l'informatique,une compréhension basique du HTML et du CSS,une familiarité avec  les bases du JavaScript(voir Premiers pas et Les blocs de construction ) et les bases JSOO(voir  Introduction aux objets). 

Objectif:

Acquérir plus de pratique dans l'utilisation des objets et des techniques orientées objet dans le contexte du monde réel.

Faisons bondir quelques balles

Dans cet article,nous écrirons une démo classique de "balles bondissantes",pour vous montrer à quel point les objets peuvent être utiles en JavaScript.Nos petites balles bondiront partout sur notre écran et changeront de couleurs lorsqu'elles se toucheront.L'exemple finalisé ressemblera un peu à ceci: 

Cet exemple utilisera l'API Canvas  pour dessiner les balles sur l'écran, et L'API requestAnimationFrame  pour animer l'ensemble de l'affichage — Vous n'avez aucunement besoin d'avoir une connaissance antérieure de ces APIs  et nous expérons qu'une fois cet article terminé, vous aurez envie d'en faire une exploration approfondie.Tout le long du parcours nous utiliserons certains objets formidables et vous montrerons nombre de techniques sympathiques comme des balles bondissantes sur les murs et la vérification de balles qui s'entrechoquent (encore connue sous l'appelation détection de collision).

Pour commencer, faites des copies locales de nos fichiers index.html, style.css, et main.js .Ces fichiers contiennent respectivement  :

  1. Un très simple document  HTML  contenant un élément <h1> , un élément <canvas> pour dessiner nos balles dessus et des élements  pour appliquer notre CSS et notre JavaScript à notre  HTML.
  2. Quelques styles très simples qui servent principalement à styliser et positionner le <h1>, et se débarasser de toutes barres de défilement ou de marges autour du pourtour de notre page( afin que cela paraisse plus sympathique et élégant) 
  3. Un peu de JavaScript qui sert à  paramétrer l'élément  <canvas> et fournir les fonctions globalles que nous utiliserons .

La première partie du script ressemble à ceci:

var canvas = document.querySelector('canvas');

var ctx = canvas.getContext('2d');

var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;

Ce script prend une référence  à l'lément  <canvas> et ensuite invoque la méthode  getContext()  sur lui nous donnant ainsi un contexte sur lequel nous pouvons commencer à dessiner. La variable résultante  (ctx)  est l'objet qui représente directement la surface du Canvas où nous pouvons dessiner et qui nous permet de dessiner des formes 2D sur ce dernier. 

Après nous configurons  les variables width (largeur) et height(hauteur),  et la largeur et la hauteur de l'élément canvas (représentés par les propriétés  canvas.width et canvas.height )  afin qu'elles soient identiques à la fenêtre du navigateur( la surface sur laquelle apparaît la page web— Ceci peut être tiré des propriétés Window.innerWidth et Window.innerHeight ).

Vous verrez qu'ici nous enchaînons les assignations des valeurs des différentes variables ensembles à des fins de rapidité.Ceci est parfaitement  autorisé.

Le dernier morceau du script ressemble à ceci:

function random(min, max) {
  var num = Math.floor(Math.random() * (max - min + 1)) + min;
  return num;
}

Cette fonction prend deux nombres comme arguments , et renvoie un nombre compris entre les deux. 

Modéliser une balle dans notre programme

Notre programme  comprendra beaucoup de balles bondissant partout sur l'écran.Comme  nos balles se comporteront toutes de la même façon, cela semble tout à fait sensé de les représenter avec un objet.Commençons donc en ajoutant le constructeur suivant à la fin de notre code.

function Ball(x, y, velX, velY, color, size) {
  this.x = x;
  this.y = y;
  this.velX = velX;
  this.velY = velY;
  this.color = color;
  this.size = size;
}

Ici, nous  incluons des paramètres qui définissent  des propriétés dont chaque balle aura besoin pour fonctionner dans notre programme :

  • Les coordonnées x et y  — les coordonnées verticales et horizontales où la balle débutera sur l'écran.Ceci peut se trouver entre 0 (coin à gauche en haut) à la hauteur et à la largeur de la fenêtre du navigateur  (coin en bas à droite).
  • Une vélocité( vitesse) horizontale et verticale (velX et velY) — à chaque balle est attribuée une vitesse horizontale  et verticale ; en termes réels ces valeurs seront régulièrement  ajouter aux valeurs de  la coordonnée x/y quand nous commencerons à animer les balles , afin de les faire bouger un peu plus sur chaque vignette(frame)  .
  • color — chaque balle a une couleur.
  • size — chaque balle a une taille — Ce sera son rayon mesuré en pixels.

Ceci règle le problème des propriétés mais qu'en est il des méthodes ? Nous voulons maintenant amener nos balles à faire quelque chose dans notre programme.

Dessiner la balle

En premier lieu ajouter la méthode  draw() au prototype de Ball() :

Ball.prototype.draw = function() {
  ctx.beginPath();
  ctx.fillStyle = this.color;
  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
  ctx.fill();
}

Utilisant cette fonction, nous pouvons dire à notre balle de se dessiner sur l'écran en appelant une série de membres du contexte 2D du canvas que nous avons défini plus tôt  (ctx).Le contexte est comme le papier et maintenant nous allons demander à notre stylo d'y dessiner quelque chose:

  • Premièrement, nous utilisons  beginPath()  pour spécifier  que nous voulons dessiner une forme sur le papier.
  • Ensuite, nous utilisons  fillStyle  pour définir de quelle couleur nous voulons que la forme soit— Nous lui attribuons la valeur de la propriété   color de notre balle.
  • Après ,nous utilisons la méthode arc()  pour tracer une forme en arc sur le papier.Ses paramètres sont:
    • Les positions x et y du centre de l'arc— Nous specifions donc  les propriétés x et y de notre balle.
    • Le rayon de l' arc —Nous specifions la propriété size de notre balle.
    • Les deux derniers paramètres spécifient  l'interval de début et de fin en degrés pour dessiner l'arc . Ici nous avons spécifié 0 degrés et 2 * PI qui est l'équivalent de  360 degrés en radians (malheureusement  vous êtes  obligés  de spécifier ces valeurs en radians et non en degrés).Cela nous donne un cercle complet.Si vous aviez spécifié   seulement  1 * PI, vous auriez eu un demi-cercle (180 degrés).
  • En dernière position nous utilisons la méthode  fill()  qui est habituellement utilisée pour spécifier que nous souhaitons mettre fin au dessin que nous avons commencé avec beginPath(),et remplir la surface délimitée  avec la couleur que nous avions spécifiée plus tôt avec  fillStyle."

Vous pouvez déjà commencer  à tester votre objet .

  1. Sauvegarder le code et charger le fichier html dans un navigateur.
  2. Ouvrez la console JavaScript du navigateur et actualiser la page afin que la taille du canvas change et prenne la petite taille restante de la fenêtre lorsque la console est ouverte.
  3. Taper dans la console ce qui suit afin de créer une nouvelle instance de balle :
    var testBall = new Ball(50, 100, 4, 4, 'blue', 10);
  4. Essayer d'appeler ses membres:
    testBall.x
    testBall.size
    testBall.color
    testBall.draw()
  5. Lorsque vous entrerez la dernière ligne, vous devriez voir la balle se dessiner quelque part sur votre canvas.

Mettre à jour les données de la balle

Nous pouvons dessiner la balle dans n'importe quelle position,mais actuellement pour commencer à la bouger nous aurons besoin d'une sorte de fonction de mise à jour. Insérer donc le code suivant à la fin de votre fichier  JavaScript pour ajouter une méthode  update() au prototype de  Ball() :

Ball.prototype.update = function() {
  if ((this.x + this.size) >= width) {
    this.velX = -(this.velX);
  }

  if ((this.x - this.size) <= 0) {
    this.velX = -(this.velX);
  }

  if ((this.y + this.size) >= height) {
    this.velY = -(this.velY);
  }

  if ((this.y - this.size) <= 0) {
    this.velY = -(this.velY);
  }

  this.x += this.velX;
  this.y += this.velY;
}

Les quatre premières parties de la fonction vérifient si la balle a atteint le rebord  du canvas .Si c'est le cas, nous  inversons la polarité de la vitesse appropriée pour faire bouger la balle dans le sens opposé.Donc par exemple,si la balle se déplaçait vers le haut (positif velY) alors la vitesse verticale est changée afin qu'elle commence à bouger plutôt vers le bas (negatif velY).

Dans les quatre cas nous :

  • Verifions si la coordonnée x est plus grande que la largeur du canvas  (la balle est entrain de sortir du côté droit).
  • Verifions si la coordonnée x est plus petite que 0  (la balle est entrain de sortir du côté gauche).
  • Verifions si la coordonnée y est plus grande que la hauteur du canvas  (la balle est entrain de sortir par le bas).
  • Verifions si la coordonnée y est plus petite que 0  (par le  haut).

Dans chaque cas , nous incluons la taille size de la balle dans les calculs parce que les coordonnées   x/y  sont situées au centre de la balle  mais nous  voulons que le pourtour de la balle  bondissent sur le rebord  — Nous ne voulons pas que la balle aille à mi-chemin de l'écran avant de commencer à rebondir vers l'arrière .

Les deux dernières lignes ajoute la valeur velX à la coordonnée x et la valeur velY à la coordonnée y —La balle est en effet mise en mouvement chaque fois que cette méthode est invoquée.

Cela suffira pour l'instant; passons à l'animation!

Animer la balle

Maintenant, rendons cela amusant. Nous allons maintenant commencer à ajouter des balles au canvas, et à les animer.

  1. Tout d'abord, nous avons besoin d'un endroit où stocker toutes nos balles. Le tableau suivant fera ce travail - ajoutez-le au bas de votre code maintenant:
    var balls = [];

    Tous les programmes qui animent les choses impliquent généralement une boucle d'animation, qui sert à mettre à jour les informations dans le programme et à restituer ensuite la vue résultante sur chaque image de l'animation; C'est la base de la plupart des jeux et autres programmes similaires.

  2. Ajoutez ce qui suit au bas de votre code maintenant:
    function loop() {
      ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
      ctx.fillRect(0, 0, width, height);
    
      while (balls.length < 25) {
        var ball = new Ball(
          random(0,width),
          random(0,height),
          random(-7,7),
          random(-7,7),
          'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
          random(10,20)
        );
        balls.push(ball);
      }
    
      for (var i = 0; i < balls.length; i++) {
        balls[i].draw();
        balls[i].update();
      }
    
      requestAnimationFrame(loop);
    }

    Notre fonction  loop() fait ce qui suit:

    • Définit la couleur de remplissage du canvas en noir semi-transparent, puis dessine un rectangle de couleur sur toute la largeur et la hauteur du canvas, en utilisant fillRect() (les quatre paramètres fournissent une coordonnée de départ et une largeur et une hauteur pour le rectangle dessiné ). Cela sert à masquer le dessin de la précédente image avant que la suivante ne soit dessinée. Si vous ne faites pas cela, vous verrez juste de longs serpents se faufiler autour de la toile au lieu de balles qui bougent! La couleur du remplissage est définie sur semi-transparent, rgba (0,0,0,0.25), pour permettre aux quelques images précédentes de briller légèrement, produisant les petites traînées derrière les balles lorsqu'elles se déplacent. Si vous avez changé 0.25 à 1, vous ne les verrez plus du tout. Essayez de varier ce nombre pour voir l'effet qu'il a.
    • Crée une nouvelle instance de notre Ball () en utilisant des valeurs aléatoires générées avec notre fonction random (), puis l'ajoute à la fin de notre tableau de boules, mais seulement lorsque le nombre de boules dans le tableau est inférieur à 25. Donc Quand on a 25 balles à l'écran, plus aucune balle supplémentaire n'apparait. Vous pouvez essayer de faire varier le nombre dans balls.length <25 pour obtenir plus, ou moins de balles à l'écran. En fonction de la puissance de traitement de votre ordinateur / navigateur, spécifier plusieurs milliers de boules peut ralentir l'animation de façon très significative!
    • boucles à travers toutes les boules dans le tableau de balle, et exécute la fonction draw () et update () de chaque balle pour dessiner chacune à l'écran, puis faire les mises à jour nécessaires à la position et la vitesse pour l'image suivante.
    • Exécute à nouveau la fonction à l'aide de la méthode requestAnimationFrame () - lorsque cette méthode est exécutée en permanence et a reçu le même nom de fonction, elle exécute cette fonction un nombre défini de fois par seconde pour créer une animation fluide. Cela se fait généralement de manière récursive - ce qui signifie que la fonction s'appelle elle-même à chaque fois qu'elle s'exécute, de sorte qu'elle sera répétée encore et encore.
  3. Finallement mais non moins important, ajoutez la ligne suivante au bas de votre code - nous devons appeler la fonction une fois pour démarrer l'animation.
    loop();

Voilà pour les bases — essayez d'enregistrer et de rafraîchir pour tester vos balles bondissantes!

Ajouter la détection de collision

Maintenant, pour un peu de plaisir, ajoutons une détection de collision à notre programme, afin que nos balles sachent quand elles ont frappé une autre balle.

  1. Tout d'abord, ajoutez la définition de méthode suivante ci-dessous où vous avez défini la méthode update () (c'est-à-dire le bloc Ball.prototype.update).
    Ball.prototype.collisionDetect = function() {
      for (var j = 0; j < balls.length; j++) {
        if (!(this === balls[j])) {
          var dx = this.x - balls[j].x;
          var dy = this.y - balls[j].y;
          var distance = Math.sqrt(dx * dx + dy * dy);
    
          if (distance < this.size + balls[j].size) {
            balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
          }
        }
      }
    }

    Cette méthode est un peu complexe, donc ne vous inquiétez pas si vous ne comprenez pas exactement comment cela fonctionne pour le moment. Une explication suit:

    • Pour chaque balle, nous devons vérifier chaque autre balle pour voir si elle est entrée en collision avec la balle actuelle. Pour ce faire, nous ouvrons une autre boucle for pour parcourir toutes les balles du tableau balls[].
    • Immédiatement à l'intérieur de notre boucle for, nous utilisons une instruction if pour vérifier si la balle en cours de bouclage est la même que celle que nous sommes en train de vérifier. Nous ne voulons pas vérifier si une balle est entrée en collision avec elle-même! Pour ce faire, nous vérifions si la balle actuelle (c.-à-d. La balle dont la méthode collisionDetect est invoquée) est la même que la balle boucle (c.-à-d. La balle référencée par l'itération courante de la boucle for dans la collisionDetect méthode). Nous utilisons ensuite ! pour annuler la vérification, de sorte que le code à l'intérieur de l'instruction if ne s'exécute que si elles ne sont pas identiques.
    • Nous utilisons ensuite un algorithme commun pour vérifier la collision de deux cercles. Nous vérifions essentiellement si les zones des deux cercles se chevauchent. Ceci est expliqué plus loin dans 2D collision detection.
    • Si une collision est détectée, le code à l'intérieur de l'instruction interne if est exécuté. Dans ce cas, nous définissons simplement la propriété color des deux cercles à une nouvelle couleur aléatoire. Nous aurions pu faire quelque chose de bien plus complexe, comme faire rebondir les balles de façon réaliste, mais cela aurait été beaucoup plus complexe à mettre en œuvre. Pour de telles simulations de physique, les développeurs ont tendance à utiliser des bibliothèques de jeux ou de physiques telles que  PhysicsJS, matter.js, Phaser, etc.
  2. Vous devez également appeler cette méthode dans chaque image de l'animation. Ajouter le code ci-dessous  juste après la ligne balls[i].update();:
    balls[i].collisionDetect();
  3. Enregistrez et rafraîchissez la démo à nouveau, et vous verrez vos balles changer de couleur quand elles entrent en collision!

Note: Si vous avez des difficultés à faire fonctionner cet exemple, essayez de comparer votre code JavaScript avec notre version finale (voir également la démo en ligne).

Résumé

Nous espérons que vous vous êtes amusé à écrire votre propre exemple de balles aléatoires bondissantes comme dans le monde réel, en utilisant diverses techniques orientées objet et divers  objets d'un bout à l'autre du module! Cela devrait vous donner une pratique utile dans l'utilisation des objets, et un bon contexte du monde réel.

C'est tout pour les articles sur les objets
il ne vous reste plus qu'à tester vos compétences dans l'évaluation sur les objets.

Voir aussi

 

Dans ce module

Étiquettes et contributeurs liés au document

Contributeurs à cette page : manuwhat
Dernière mise à jour par : manuwhat,