Coder le jeu video html5 pong – Vitesse et trajectoire de la balle

 

Onzième partie consacrée au développement du jeu vidéo html5 pong. L’intelligence artificielle a un côté parfait : il n’est quasi pas possible de la battre. Pour rendre les choses un peu plus jouables, et donc agréable pour le joueur, l’objectif est rendre imparfait cette intelligence artificielle. Comment ? En modifiant la vitesse de la balle mais aussi sa trajectoire avec la raquette.


 

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;
– le renvoi de la balle par les raquettes Coder le jeu video html5 pong – Renvoi de la balle;
– l’ajout du son lorsque la balle cogne un mur ou une raquette Coder le jeu vidéo Pong – Ajout du son.
– l’intelligence artificielle Coder le jeu video html5 pong – Intelligence Artificielle;
– la Coder le jeu video html5 pong – Gestion du score et engagement;
– l’ajout d’un début et d’une fin à une partie début et fin de partie.

 

Modification de la trajectoire de la balle

Jusqu’à présent, la trajectoire de la balle est simple puisqu’elle se déplace dans quatre directions obliques possibles. Pour modifier cette trajectoire, vous utilisez deux propriétés de l’objet balle : directionX et directionY qui indiquent dans quelle sens elle se déplace mais aussi à quel rythme.

En effet, les valeurs absolues (sans le signe) de directionX et directionY indiquent aussi le pas de déplacement en pixels sur le terrain.

Actuellement, elles sont de 1 : le pas sur l’axe des abscisses est identique à celui sur l’axe des ordonnées. La trajectoire de la balle est de 45° par rapport à l’horizontale.

Pour changer cette trajectoire, modifier le pas l’axe des abscisses ou des ordonnées de façon à ce qu’il soit différent d’un axe à l’autre suffirait :
– pas de 1 sur l’axe X, pas de 2 sur l’axe Y : la trajectoire de la balle ferait qu’elle monte ou descend plus vite qu’elle ne déplace vers la droite ou la gauche;
– à l’inverse, pas de 2 sur l’axe X, pas de 1 sur l’axe Y : la trajectoire de la balle ferait qu’elle monte ou descend plus lentement qu’elle ne déplace vers la droite ou la gauche.

Pour modifier la trajectoire de la balle, vous devez donc agir sur ces deux variables. N’oubliez pas que c’est la raquette qui modifie la trajectoire lorsqu’elle renvoie la balle : plus la balle sera excentrée sur la raquette lors de la frappe, plus le changement de trajectoire est important.

Pour effectuer ce changement de trajectoire, il va falloir déterminer à quel endroit la raquette a été percutée et donc définir des zones d’impacts.

Une zone d’impact est une zone de la raquette qui, percutée par la balle, modifie sa trajectoire. Chaque zone d’impact modifie de manière unique la trajectoire de la balle.

Comme illustré ci-dessous, la raquette est divisée en 5 points d’impact distincts : chacun agit sur la trajectoire de la balle, chacun fait sa propre modification de trajectoire.

Il est donc nécessaire de savoir à quel endroit la balle a frappé la raquette au moment de l’impact. Ceci passe par le biais d’une fonction qui en fonction de l’ordonnée de la balle par rapport à celui de la raquette indique quelle zone a été touchée par la balle.

Pour l’exemple, définissez les 5 zones d’impact qui seront renvoyées par la fonction ballOnPlayer rattachée au namespace game :
– TOP pour le haut de la raquette;
– MIDDLETOP à mi chemin entre le centre et le haut de la raquette;
– MIDDLEBOTTOM à mi chemin entre le centre et le bas de la raquette;
– BOTTOM pour le bas de la raquette;
– et CENTER pour le centre de la raquette.

En javascript, la fonction ballOnPlayer :

var game = {
....
  ballOnPlayer : function(player, ball) {
    var returnValue = "CENTER";
    var playerPositions = player.height/5;
    if ( ball.posY > player.posY && ball.posY < player.posY + playerPositions ) {
      returnValue = "TOP";
    } else if ( ball.posY >= player.posY + playerPositions && ball.posY < player.posY + playerPositions*2 ) {
      returnValue = "MIDDLETOP";
    } else if ( ball.posY >= player.posY + playerPositions*2 && ball.posY < player.posY + 
      player.height - playerPositions ) {
      returnValue = "MIDDLEBOTTOM";
    } else if ( ball.posY >= player.posY + player.height - playerPositions && ball.posY < player.posY + 
      player.height ) {
      returnValue = "BOTTOM";
    }
    return returnValue;
  },
....
}

Comme décidé auparavant, le changement de trajectoire se fait lorsque la balle est frappée par une raquette. Plus spécifiquement lorsqu’il y a collision entre la balle et la raquette.

Jusqu’à présent, c’est la fonction game.collideBallWithPlayersAndAction qui prenait en charge les collisions. Elle va continuer de le faire, cependant elle va aussi opérer le changement de trajectoire.

Le changement de trajectoire va être dévolu à une autre nouvelle fonction utilisatrice de la fonction game.ballOnPlayer que vous appelez changeBallPath.

Elle reprend les changements tels qu’ils sont indiqués sur le schéma ci-dessus en distinguant le positionnement de la raquette (gauche ou droite).

var game = {
....
  changeBallPath : function(player, ball) {
    if ( player.originalPosition == "left" ) {
      switch( game.ballOnPlayer(player, ball) ) {
        case "TOP":
          ball.directionX = 1;
          ball.directionY = -3;
          break;
        case "MIDDLETOP":
          ball.directionX = 1;
          ball.directionY = -1;
          break;
        case "CENTER":
          ball.directionX = 2;
          ball.directionY = 0;
          break;
        case "MIDDLEBOTTOM":
          ball.directionX = 1;
          ball.directionY = 1;
          break;
        case "BOTTOM":
          ball.directionX = 1;
          ball.directionY = 3;
          break;
      }
	} else {
      switch( game.ballOnPlayer(player, ball) ) {
        case "TOP":
          ball.directionX = -1;
          ball.directionY = -3;
          break;
        case "MIDDLETOP":
          ball.directionX = -1;
          ball.directionY = -1;
          break;
        case "CENTER":
          ball.directionX = -2;
          ball.directionY = 0;
          break;
        case "MIDDLEBOTTOM":
          ball.directionX = -1;
          ball.directionY = 1;
          break;
        case "BOTTOM":
          ball.directionX = -1;
          ball.directionY = 3;
          break;
      }
    }
....
}

Pour terminer, integrez à la fonction game.collideBallWithPlayersAndAction ces possibles changements de trajectoire.

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

devient

var game = {
....
  collideBallWithPlayersAndAction : function() { 
    if ( this.ball.collide(game.playerOne) ) {
      this.changeBallPath(game.playerOne, game.ball);
      this.playerSound.play();
    }
    if ( this.ball.collide(game.playerTwo) ) {
      this.changeBallPath(game.playerTwo, game.ball);
      this.playerSound.play();
    }
  },
....
}

 

La vitesse de la balle

La vitesse a déjà été évoquée dans l’article Animer la balle.

A ce propos, l’objet ball intègre une propriété speed qui indique la vitesse de déplacement de la balle fixé jusqu’à présent à 1.

Cette vitesse speed est en réalité un coefficient qui s’applique aux variables directionX et directionY.

Si ce coefficient est inférieur à 1, la balle ralentit.
Si ce coefficient est supérieur à 1, la balle accélère. Et plus ce coefficient est élevé, plus la balle va vite. Ce coefficient peut être associé à la vitesse de la balle.

Dans le code existant, il s’applique déjà mais n’a aucun effet puisqu’il est fixé à la valeur 1. Depuis la méthode move de l’objet ball:

ball : {
....
  move : function() {
    if ( this.inGame ) {
      this.posX += this.directionX * this.speed;
      this.posY += this.directionY * this.speed;
    }
  },
....
}

Avec une vitesse suffisamment élevée, l’intelligence artificielle devient battable.

Le plus simple est que la balle accélère au fur et à mesure qu’un échange dure: augmenter la valeur de game.speed à intervalle régulier par le biais d’une nouvelle méthode speedUp de l’objet ball:

ball : {
....
  speedUp: function() {
    this.speed = this.speed + .1;
  },
....
}

Pour appliquer l’accélération, il suffit de l’appeler à intervalles réguliers grâce à la fonction javascript setInterval.

Ce choix est purement arbitraire, il est aussi possible de donner un coup d’accélération lorsque la balle percute une raquette.

La fonction setInterval prend en paramètres :
– une fonction à appeler;
– un intervalle exprimé en millisecondes qui correspond au temps qui sépare deux appels de la fonction donnée en premier paramètre.

Pour plus de lisibilité, encapsulez le code dans une fonction au nom parlant speedUpBall rattachée au namespace game:

var game = {
....
  speedUpBall: function() { 
    setInterval(function() {
	  game.ball.speedUp();
	}, 5000);
  }
....
}

Il n’y a plus qu’à l’appeler à l’initialisation du jeu:

var game = {
....
  init : function() {
  ....
    game.speedUpBall();
  },
....
}

Et à réinitialiser la valeur de la vitesse de la balle lorsqu’elle est lancée depuis la fonction reinitGame :

var game = {
....
  reinitGame : function() {
    this.ball.inGame = false;
    this.ball.speed = 1;
    this.playerOne.score = 0;
    this.playerTwo.score = 0;
    this.scoreLayer.clear();
    this.displayScore(this.playerOne.score, this.playerTwo.score);
  },
....
}

Vous avez maintenant une IA que vous pouvez battre. Le jeu commence à devenir plus intéressant puisqu’il est désormais jouable.

 
Pour voir en live le code, cliquez sur Pong

Dans l’article suivant, un petit ravalement de façade 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, tutoriel html5, tutoriel jeu vidéo  |  3 commentaires

3 réponses à "Coder le jeu video html5 pong – Vitesse et trajectoire de la balle"

Répondre