Coder le jeu video html5 pong – quelques réajustements

 

Le jeu vidéo html5 pong avance. Cependant et avant de continuer dans cette série proche de la fin, quelques réajustements s’imposent. Vous avez probablement remarqué que la raquette du joueur pouvait sortir de l’écran de jeu, mais aussi que le pointeur de la souris était systématiquement au dessus de la raquette. Je vous propose donc de corriger ces petites choses.

 

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 Coder le jeu video html5 pong – début et fin de partie;
– la vitesse et la trajectoire de la balle Coder le jeu video html5 pong – vitesse et trajectoire de la balle;
– le look plus moderne Coder le jeu video html5 pong – Changement de look;
– l’adaptation du jeu vidéo à la taille de l’écran sur lequel il est exécuté Coder le jeu video html5 pong – adaptation de la taille de l’écran;
– le décor du jeu vidéo Coder le jeu video html5 pong – le décor.

 

Bloquer la raquette sur les bords du terrain

Comme vous pouvez le constater, la raquette du joueur peut se déplacer bien au delà des bords du terrain. Le petit réajustement va donc consister à bloquer le déplacement de la raquette sur les bords du terrain.

C’est la fonction movePlayers du namespace javascript game que vous allez modifier.

Rappelez vous que cette méthode est dédiée aux changements des coordonnées de la raquette à partir de variables, entre autres playerOne.goUp et playerOne.goDown, dont le positionnement indique s’il faut oui ou non changer les coordonnées par incrémentation ou décrémentation.

Attention cette méthode ne gère pas l’affichage, elle ne gère que les coordonnées.

Pour empêcher la raquette de se déplacer en dehors du terrain, il suffit de lire les coordonnées du sprite de la raquette et s’ils sont en dehors des clous, les y remettre , dans le style:

if ( game.playerOne.sprite.posY > 0 )
  game.playerOne.sprite.posY-=5;
else if ( game.playerOne.sprite.posY < conf.GROUNDLAYERHEIGHT - game.playerOne.sprite.height )
  game.playerOne.sprite.posY+=5;

Idéalement, il faudrait autoriser l’incrémentation ou la décrémentation des coordonnées de la raquette uniquement lorsque ses coordonnées sont comprises entre l’ordonnée minimale (0) et l’ordonnée maximale (conf.GROUNDLAYERHEIGHTgame.playerOne.sprite.height).

Actuellement, comme vous pouvez voir ci-dessous les coordonnées varient à plusieurs endroits du code. D’une part, vous avez du code redondant, ce qui constitue une mauvaise pratique. D’autre part, il faudrait ajouter le test ci-dessus à chaque fois que les coordonnées changent, donc du code encore redondant.

var game = {
....
  movePlayers : function() {
    if ( game.control.controlSystem == "KEYBOARD" ) {
      // keyboard control
      if ( game.playerOne.goUp ) {
        game.playerOne.sprite.posY-=5;
      } else if ( game.playerOne.goDown ) {
        game.playerOne.sprite.posY+=5;
      }
    } else if ( game.control.controlSystem == "MOUSE" ) {
      // mouse control
      if (game.playerOne.goUp && game.playerOne.sprite.posY > game.control.mousePointer)
        game.playerOne.sprite.posY-=5;
      else if (game.playerOne.goDown && game.playerOne.sprite.posY < game.control.mousePointer)
        game.playerOne.sprite.posY+=5;
    }
  },
....
}

game.playerOne.sprite.posY-=5 et game.playerOne.sprite.posY+=5 se répètent. Et si vous ajoutiez les test pour empêcher la raquette hors du terrain cela donnerait:

var game = {
....
  movePlayers : function() {
    if ( game.control.controlSystem == "KEYBOARD" ) {
      // keyboard control
      if ( game.playerOne.goUp && game.playerOne.sprite.posY > 0 )
        game.playerOne.sprite.posY-=5;
      else if ( game.playerOne.goDown && game.playerOne.sprite.posY < game.groundHeight - game.playerOne.sprite.height )
        game.playerOne.sprite.posY+=5;
    } else if ( game.control.controlSystem == "MOUSE" ) {
      // mouse control
      if ( game.playerOne.goUp && game.playerOne.sprite.posY > game.control.mousePointer && game.playerOne.sprite.posY > 0 )
        game.playerOne.sprite.posY-=5;
      else if ( game.playerOne.goDown && game.playerOne.sprite.posY < game.control.mousePointer && game.playerOne.sprite.posY < conf.GROUNDLAYERHEIGHT - game.playerOne.sprite.height )
        game.playerOne.sprite.posY+=5;
    }	  
  },
....
}

Cela fonctionne mais n’est pas terrible en terme de codage. Je vous propose de centraliser les tests à un seul endroit en fin de fonction en ajoutant deux indicateurs booléens up et down dans la fonction movePlayers.

Valorisés lors de l’usage du clavier ou de la souris: up fixé à true indique une demande de déplacement vers le haut et down fixé à true indique une demande de déplacement vers le bas.

Cette demande de déplacement est analysée et prise en compte si les coordonnées de la raquette sont dans les clous que constituent les limites du terrain.

var game = {
....
  movePlayers : function() {
  
    var up;
    var down;
	
    if ( game.control.controlSystem == "KEYBOARD" ) {
      if ( game.playerOne.goUp ) {
        up = true;
        down= false;
      } else if ( game.playerOne.goDown ) {
        up = false;
        down= true;
      }
    } else if ( game.control.controlSystem == "MOUSE" ) {
      if (game.playerOne.goUp && game.playerOne.sprite.posY > game.control.mousePointer ) {
        up = true;
        down= false;
      } else if (game.playerOne.goDown && game.playerOne.sprite.posY < game.control.mousePointer ) {
        up = false;
        down= true;
      }
    }	
	
    if ( up && game.playerOne.sprite.posY > 0 )
      game.playerOne.sprite.posY-=5;
    else if ( down && game.playerOne.sprite.posY < conf.GROUNDLAYERHEIGHT - game.playerOne.sprite.height )
      game.playerOne.sprite.posY+=5;
	  
  },
....
}

Et le code est plus lisible.

Le pointeur de la souris au dessus de la raquette

Ce n’est pas un gros problème et n’empêche pas le jeu d’être jouable. Mais c’est plus clean si la raquette s’arrête là où le pointeur de la souris se situe sur la verticale.

Ici, il suffit simplement de corriger l’abscisse renvoyée par la souris (game.control.mousePointer) dans la fonction onMouseMove du namespace javascript game.control.

game.control = {
  ....
  onMouseMove : function(event) {
   
    game.control.controlSystem = "MOUSE";
	
    if ( event ) {
      game.control.mousePointer = event.clientY - 50;
    }
    ....
  },
  ....
}

Ajustez le nombre à votre environnement de développement.

Il reste à adapter ce nombre au redimensionnement en créant une variable dédiée dans le namespace javascript conf et en respectant les règles de nommage.

var conf = {

  MOUSECORRECTIONPOSY : 50,
  ....
}

Puis de remplacer la valeur en dur dans la fonction onMouseMove par cette variable.

game.control = {
  ....
  onMouseMove : function(event) {
   
    game.control.controlSystem = "MOUSE";
	
    if ( event ) {
      game.control.mousePointer = event.clientY - conf.MOUSECORRECTIONPOSY;
    }
    ....
  },
  ....
}

Et voilà, le tour est joué.

La balle sort de l’écran avant de rebondir sur le mur du bas

La fonction bounce de l’objet ball du namesapce game gère le rebond sur les murs.

var game = {
  ....
  ball : {
    ....
    bounce : function(soundToPlay) {
      if ( this.sprite.posX > conf.GROUNDLAYERWIDTH || this.sprite.posX < 0 ) {
        this.directionX = -this.directionX;
		soundToPlay.play();
	  }
      if ( this.sprite.posY > conf.GROUNDLAYERHEIGHT || this.sprite.posY < 0  ) {
        this.directionY = -this.directionY;
        soundToPlay.play();
      }		
    },
    ....
  }
  ....
}

La partie du code gérant le rebond sur le mur du bas est:

      if ( this.sprite.posY > conf.GROUNDLAYERHEIGHT || this.sprite.posY < 0  ) {
        this.directionY = -this.directionY;
        soundToPlay.play();
      }		

La gestion d’un rebond visuellement correcte doit prendre en compte la taille du sprite de la balle.
Actuellement, seul un test sur la position du sprite sur l’écran (posY) est fait.
Or la position du sprite est déterminée à partir du point supérieur gauche.

Dans le cas présent, le rebond n’a donc lieu que lorsque le point supérieur gauche du sprite (posY) entre en contact avec le mur. Avant cela et si la balle est suffisamment proche du mur, elle disparait.

Vous devez doc modifier le test en prenant en considération la taille de la balle: le point de contact avec le mur doit être la position du sprite de la balle (posY) auquel on ajoute sa taille.

var game = {
  ....
  ball : {
    ....
    bounce : function(soundToPlay) {
      if ( this.sprite.posX > conf.GROUNDLAYERWIDTH || this.sprite.posX < 0 ) {
        this.directionX = -this.directionX;
		soundToPlay.play();
	  }
      if ( this.sprite.posY + this.sprite.height > conf.GROUNDLAYERHEIGHT || this.sprite.posY < 0  ) {
        this.directionY = -this.directionY;
        soundToPlay.play();
      }		
    },
    ....
  }
  ....
}

Les réajustements sont maintenant terminés.

 
Pour voir en live le code, cliquez sur Pong

 

Si vous avez aimé cet article, partagez le.

 

Si vous constatez des coquilles, ou avez des remarques, une autre solution ou encore souhaitez manifester votre satisfaction de ce tuto, commentez.

 

Posté dans html5, pongTaggé canvas html5, canvas image, jeu video html5, tuto html5  |  Laisser un commentaire

Répondre