Coder le jeu video html5 pong – Renvoi de la balle

 

Sixième partie consacrée au développement d’un jeu vidéo html5 javascript. L’objectif du jour est de renvoyer la balle avec la raquette du joueur.


 

Prérequis

Avoir lu les tutoriaux suivants :
– l’initialisation du projet Coder le jeu vidéo Pong;
– la mise en place de l’environnement du jeu constitué du terrain, du filet, des raquettes, de la balle et du score Coder le jeu vidéo Pong – Raquettes et Balle;
– l’animation de la balle Coder le jeu vidéo Pong – Animer la balle;
– le contrôle de la raquette par le joueur à l’aide du clavier Coder le jeu vidéo Pong – Animer les raquettes;
– le contrôle de la raquette par le joueur à l’aide de la souris Coder le jeu vidéo Pong – Controle à la souris.

Je vous conseille aussi la lecture de l’article consacré aux collisions des sprites : Javascript HTML5 collision de sprites

 

Le principe

Il va consister à changer la trajectoire de la balle lorsqu’elle entrera en collision avec la raquette. Si la raquette ne la rattrape pas, elle est considérée comme perdue et réapparait de l’autre côté du terrain.

A chaque cycle d’affichage, il va donc falloir tester s’il y a collision entre la balle et la raquette. S’il y a collision, la balle rebondit sur la raquette : elle change de trajectoire.

 

Comment va changer la trajectoire de la balle ?

La balle évolue dans 4 directions différentes :

– vers le haut et la droite, en incrémentant son abscisse et en décrémentant son ordonnée;

– vers le bas et la droite, en incrémentant son abscisse et en incrémentant son ordonnée;

– vers le bas et la gauche, en décrémentant son abscisse et en incrémentant son ordonnée;

– vers le haut et la gauche, en décrémentant son abscisse et en décrémentant son ordonnée.

La raquette du joueur étant toujours celle de gauche, la balle arrivera toujours par la droite du terrain de jeu. Il y a donc deux cas possibles de collision avec la raquette :

– la balle se dirige vers le bas et la gauche de l’écran

– la balle se dirige vers le haut gauche de l’écran

L’ordonnée de la balle continue d’évoluer dans le même sens avant et après la collision :
– lorsque la balle descend, elle continue de descendre lorsque la raquette la percute;
– lorsque la balle monte, elle continue de monter lorsque la raquette la percute.

Avant percussion avec la raquette, la balle se dirige de la droite vers la gauche : son abscisse diminue.
Lorsqu’elle percute la raquette, elle doit se diriger de la gauche vers la droite : son abscisse doit augmenter.

Dans les deux cas de collision, l’incrément de l’abscisse (game.ball.directionX) de la balle s’inverse.

Vous pouvez envisager des changements de trajectoire plus complexes et en fonction de l’endroit où la balle tape la raquette, mais ceci fera l’objet d’un prochain article.

 

Le code javascript

Créez une nouvelle méthode pour détecter les collisions entre la balle et la raquette. Dès lors, se pose une question : à qui rattacher cette fonction ? La balle, la raquette, non rattachée….

Une fonction non rattachée pose le problème de la réutilisation du code pour des développements futurs pour d’autres jeux : dans ce cas, elle sera spécifique au jeu.

Les raquettes, la balle sont des objets qui seront réutilisables en partie. Ils préfigurent ce que sont des sprites. Du moins, ces objets ont des propriétés communes qui pourraient être rassemblées dans un objet classe pour réutilisation.

Commencez par créer une nouvelle méthode collide au sein de l’objet ball, fonction dédiée à la détection de collisions avec d’autres objets graphiques.

Pour en savoir plus sur la méthode de gestion des collisions, celle-ci est abordée en détail dans l’article Javascript HTML5 collision de sprites.

En adaptant le code de l’article Javascript HTML5 collision de sprites, on obtient :

var game = {
  ....   
  ball : {
  ....
    collide : function(anotherItem) {
      if ( !( this.posX >= anotherItem.posX + anotherItem.width || this.posX <= anotherItem.posX
      || this.posY >= anotherItem.posY + anotherItem.height || this.posY <= anotherItem.posY ) ) {
        // Collision
        return true;
      } 
      return false;
    },
  ....
}

Lors de l’appel de cette nouvelle fonction et si elle renvoie la valeur true, il y a collision et la trajectoire de la balle devra être modifiée.

Cette fonction renvoie un booléen :
true s’il y a collision;
false s’il n’y a pas collision.

Il ne reste plus qu’à intégrer la fonction collide dans le code existant, notamment la fonction principale.

Notez qu’il y a deux tests de collision à faire : un pour chaque raquette (playerOne et playerTwo).

Pour une meilleure lisibilité, encapsulez ces tests dans une fonction comme ceci au sein du namespace game en y intégrant l’action voulue : le renvoi de la balle (l’inversion de sa trajectoire sur l’axe des abscisses).

var game = {
  ....
  collideBallWithPlayersAndAction : function() { 
    if ( this.ball.collide(game.playerOne) )
      game.ball.directionX = -game.ball.directionX;
    if ( this.ball.collide(game.playerTwo) )
      game.ball.directionX = -game.ball.directionX;
  },  
  ....
}

Puis appelez cette fonction dans la boucle principale d’exécution qu’est main :

  var main = function() {
    // le code du jeu
    game.clearLayer(game.playersBallLayer);
    game.movePlayers();
    game.displayPlayers();
    game.moveBall();
    game.collideBallWithPlayersAndAction();
    requestAnimId = window.requestAnimationFrame(main); // rappel de main au prochain rafraichissement de la page
  }

La balle est renvoyée lorsqu’elle percute la raquette sur sa face avant. Cependant, une petite imperfection subsiste : on voit la balle en surimpression de la raquette avant que l’adversaire (raquette à droite de l’écran playerTwo) ne la renvoie.

Cette petite imperfection revient au code de détection des collisions qui ne prend pas en compte la largeur et la hauteur du sprite cible de la collision. Le correctif est très rapide :

var game = {
  ....   
  ball : {
  ....
    collide : function(anotherItem) {
      if ( !( this.posX >= anotherItem.posX + anotherItem.width || this.posX <= anotherItem.posX - this.width
      || this.posY >= anotherItem.posY + anotherItem.height || this.posY <= anotherItem.posY - this.height ) ) {
        // Collision
        return true;
      } 
      return false;
    },
  ....
}

Et le tour est joué.

Pour voir en live le code, cliquez sur Pong

Le prochain article va consister à ajouter du son lors des chocs de la balle avec les murs et les raquettes. A suivre ici.

 

Si vous avez aimé cet article, partagez le.

 

Si vous constatez des coquilles, ou avez des remarques à faire ou encore souhaitez manifester votre satisfaction de ce tuto, n’hésitez pas les commentaires sont faits pour ça.

 

 

Posté dans html5, pongTaggé développer pong, pong html5, pong javascript, tutoriel html5, tutoriel jeu vidéo, tutoriel pong  |  13 commentaires

13 réponses à "Coder le jeu video html5 pong – Renvoi de la balle"

Répondre