Coder le jeu video html5 pong – le décor




 

Quartorzième partie consacrée au développement d’un jeu vidéo html5 javascript: je vous propose de mettre un décor plus fouillé et plus abouti.

 

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 principe

Hormis le nécessaire au redimensionnement des composants, pas de développement supplémentaire, du html principalement.

Dans un premier temps, je vous propose de:
– centrer le terrain de jeu;
– ajouter un bandeau de part et d’autre du terrain: l’un pour intégrer un menu pour le jeu, l’autre pourrait être dédié à l’accueil de publicité.

Rendre visible un bloc div vide

Dans cet article, vous allez manipuler à certains moments des blocs html div vides. Pas simple de visualiser le résultat.

Je vous propose de les rendre visibles en ajoutant un contour fin coloré par le biais d’un style:

border: 1px solid #0000FF;

Pour l’intégrer au div html:

<div id="divGame" style="border: 1px solid #0000FF;"></div>

Ni plus, ni moins.

Ajout des bandeaux

Le canvas html5 est associé/intégrée à un bloc html nommé divGame.

Pour créer les 2 bandeaux à sa gauche et à sa droite, ajoutez 2 nouveaux blocs div en n’omettant pas les styles pour leur visibilité.

<div id="left" style="border: 1px solid #0000FF;"></div>
<div id="divGame" style="border: 1px solid #0000FF;"></div>
<div id="right" style="border: 1px solid #0000FF;"></div>

Le résultat n’est pas probant et ceci est normal. Pour que les blocs html div existent pleinement, il faut non seulement leur donner des dimensions mais aussi faire en sort qu’ils s’affichent pleinement sans se limiter à son contenu.

Vous devez donc spécifier certaines caractéristiques de style indispensables:
display:block; -> pour indiquer d’afficher un bloc;
width:200px;height:100px; -> pour le dimensionner.

<div id="left" style="display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>
<div id="divGame" style="display:block;width:600px;height:100px;border: 1px solid #0000FF;"></div>
<div id="right" style="display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>

Ce n’est toujours pas probant. Cependant, vous voyez derrière le terrain 2 blocs l’un en dessous de l’autre.

Là nous sommes face à une problématique de positionnement des blocs les uns par rapport aux autres: il suffit de changer cette politique de positionnement par une qui placera les éléments les uns derrières les autres sur une même ligne

Le style float:left placé sur une balise html div indique que cette même balise sera placée à la gauche de la suivante ou plus simplement que la balise suivante sera placée à sa droite.

Tout ceci, bien entendu si les dimensions le permettent: si vous mettez trois blocs dont la somme des dimensions est supérieure à la dimension de l’écran alors le bloc le plus à droite de l’écran sera placé en dessous du premier bloc (float:left=le plus à gauche possible).

<div id="left" style="float:left;display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>
<div id="divGame" style="float:left;display:block;width:600px;height:100px;border: 1px solid #0000FF;"></div>
<div id="right" style="float:left;display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>

Ce qui cloche maintenant, c’est la taille du canvas qui plus grande que celle du div html. Pour corriger, il suffit que le div html ait la même taille que le canvas html5.

Vous retrouverez la bonne taille dans le fichier conf.js avec les valeurs de GROUNDLAYERWIDTH et GROUNDLAYERHEIGHT.

<div id="left" style="float:left;display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>
<div id="divGame" style="float:left;display:block;width:700px;height:400px;border: 1px solid #0000FF;"></div>
<div id="right" style="float:left;display:block;width:200px;height:100px;border: 1px solid #0000FF;"></div>

Voilà qui est un peu mieux. Pour parfaire la solution, je vous propose d’aligner la hauteur des deux blocs à celle de celui du milieu.

<div id="left" style="float:left;display:block;width:200px;height:400px;border: 1px solid #0000FF;"></div>
<div id="divGame" style="float:left;display:block;width:700px;height:400px;border: 1px solid #0000FF;"></div>
<div id="right" style="float:left;display:block;width:200px;height:400px;border: 1px solid #0000FF;"></div>

Comme je le disais précédemment:
– le bloc de gauche pourrait être un panneau de commande avec le bouton start auquel vous pourriez ajouter un bouton pause;
– le bloc de droite pourrait accueillir de la publicité (monétisation du jeu ?)

Bref, là c’est à votre inspiration de faire le boulot.

Centrer horizontalement l’écran de jeu

Pour centrer les trois blocs sans travailler sur chacun individuellement nécessite qu’ils forment un tout. Et c’est ce tout que vous allez centrer.

Pour former ce tout, il vous suffit d’encapsuler les trois blocs dans un div container:

<div id="blocToCenter">
  <div id="left" style="float:left;display:block;width:200px;height:400px;border: 1px solid #0000FF;"></div>
  <div id="divGame" style="float:left;display:block;width:700px;height:400px;border: 1px solid #0000FF;"></div>
  <div id="right" style="float:left;display:block;width:200px;height:400px;border: 1px solid #0000FF;"></div>
</div>

Cependant, tel qu’indiqué rien ne change: il reste à centrer de bloc container.

La méthode la plus simple pour center en bloc div html sur l’horizontale est:
– de lui donner une taille qui soit supérieure à la somme des tailles des trois blocs encapsulés (via les propriétés de style width et height);
– de lui laisser calculer les marges automatiquement à sa gauche et à sa droite (via les propriétés de style margin).

<div id="blocToCenter" style="width:1010px;height:400px;margin-left:auto;margin-right:auto">
  <div id="left" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;"></div>
  <div id="divGame" style="float:left;display:block;width:700px;height:400px;border: 1px solid #0000FF;"></div>
  <div id="right" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;"></div>
</div>

Habillage du bloc gauche

Remarquez que le bouton start en haut à gauche de l’écran fait un peu (voire très) moche. Pourquoi ne pas utiliser le bloc gauche pour y intégrer ce bouton et y ajouter un bouton pause ?

Il y a juste à déplacer la balise img dans le bloc div html nommé left en prenant soin de réduire un peu la taille de l’image à 100 pixels pour qu’elle soit trop grossière:

<div id="left" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;text-align:center;">
  <input id="startGame" type="image" style="width:100px" src="./img/startBtn.png">
</div>

Ajoutez un bouton de pause comme celui-ci en le plaçant préalablement dans le dossier img du projet:

<div id="left" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;text-align:center;">
  <input id="startGame" type="image" style="width:100px" src="./img/startBtn.png">
  <input id="pauseGame" type="image" style="width:100px" src="./img/pauseBtn.png">
</div>

Du coup, le bloc complet est remonté et colle quasiment à la partie supérieure de l’écran.

Vous pouvez par ailleurs supprimer le bloc menu qui ne sert plus à rien.

Centrer horizontalement et verticalement l’écran de jeu

Esthétiquement parlant, c’est pas top. Un centrage vertical me parait aussi utile et là vous devez changer de méthode. Autant la méthode pour un centrage horizontal tel qu’indiqué est préconisée, si vous voulez les deux c’en est une autre.

Pour centrer le bloc horizontalement et verticalement avec CSS, la méthode va être de placer le bloc div html (son coin supérieur gauche au centre de la page), puis de déplacer ce bloc vers la gauche de la moitié de sa taille horizontale (1010px/2=505px) et vers le haut de la moitié de sa taille verticale (400px/2=200px) en fixant des marges négatives.

Vous devez d’abord choisir un mode de positionnement absolu (position:absolute;) c’est à dire indépendamment de tout autre élément de la page. Ce mode de positionnement permet de placer le bloc div html où bon vous semble, vous n’avez qu’à spécifier ses coordonnées via les propriétés left et top.

position:absolute;

Puis placer le bloc (son bord supérieur gauche) au milieu de l’écran.

left:50%;top:50%;

Ensuite fixer ses dimensions (width et height), ce qui est normalement déjà fait.

width:1010px;height:400px;

Enfin fixer des marges haute et gauche négatives valant la moitié des dimensions verticale et horizontale du bloc.

margin:-200px 0 0 -505px;

Au final, vous obtenez:

<div id="blocToCenter" style="width:1010px;height:400px;position:absolute;left:50%;top:50%;margin:-200px 0 0 -505px;">

La totale:

<div id="blocToCenter" style="width:1010px;height:400px;position:absolute;left:50%;top:50%;margin:-200px 0 0 -505px;">
  <div id="left" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;text-align:center;">
    <input id="startGame" type="image" style="width:100px" src="./img/startBtn.png">
    <input id="pauseGame" type="image" style="width:100px" src="./img/pauseBtn.png">
  </div>
  <div id="divGame" style="float:left;display:block;width:700px;height:400px;border: 1px solid #0000FF;"></div>
  <div id="right" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;"></div>
</div>

 

Activation des boutons

Rien à changer pour le bouton start puisque déjà actif. Il reste à activer le bouton pause.
Le mieux serait que lorsque bouton pause est cliqué, il se transforme en bouton continue et vice-versa.

Commencez par ajouter le bouton continue en le rendant invisible via la propriété de style display:

<div id="left" style="float:left;display:block;width:150px;height:400px;border: 1px solid #0000FF;text-align:center;">
  <input id="startGame" type="image" style="width:100px" src="./img/startBtn.png">
  <i<em>nput id="pauseGame" type="image" style="width:100px" src="./img/pauseBtn.png">
  <input id="continueGame" type="image" style="width:100px;display:none;" src="./img/continueBtn.png">
</div>

Ensuite, créez les fonctions appelées au clic des boutons pause et continue: l’un rendra invisible en plus de mettre en pause ou pas le jeu. Ces deux fonctions prennent la même forme que la fonction onStartGameClickButton du namespace game.control.

game.control = {
  ...
  onPauseGameClickButton : function() {
    if ( game.gameOn ) {
      game.gameOn = false;
      game.pauseGameButton.style.display = 'none';
      game.continueGameButton.style.display = 'inline';
    }
  },
  
  onContinueGameClickButton : function() {
    if ( !game.gameOn ) {
      game.gameOn = true;
      game.pauseGameButton.style.display = 'inline';
      game.continueGameButton.style.display = 'none';
    }
  }
}

Il ne reste plus qu’à appeler ces fonctions sur le clic des boutons dans le namespace game.js. Même forme que pour la fonction initStartGameButton: initPauseGameButton et initContinueGameButton.

var game = {
  ...
  initPauseGameButton : function() {
    this.pauseGameButton.onclick = game.control.onPauseGameClickButton;
  },

  initContinueGameButton : function() {
    this.continueGameButton.onclick = game.control.onContinueGameClickButton;
  },
  ....
}

Appelez ces fonctions initPauseGameButton et initContinueGameButton depuis la fonction init.

En ayant au préalable créer et initialiser (toujours depuis la fonction init) les propriétés du namespace game pauseGameButton et continueGameButton: l’initialisation consistant simplement à rattacher les propriétés pauseGameButton et continueGameButton aux objets html correspondant.

var game = {
  ...
  init : function() {
    ...
    this.divGame = document.getElementById("divGame");
    this.startGameButton = document.getElementById("startGame");
    this.pauseGameButton = document.getElementById("pauseGame");
    this.continueGameButton = document.getElementById("continueGame");
    ...
    this.initStartGameButton();
    this.initPauseGameButton();	
    this.initContinueGameButton();
    ....
  }
}

Ajouter un fond

Une simple image de fond ajoutée via la propriété de style background-image à la balise body.

L’image à télécharger et intégrer dans le dossier img du projet. Libre à vous d’y mettre une de vos créations.

Le code html:

<html>
  <body style="background-image:url(./img/background.jpg)">
  ...
</html>

Je vous invite à prendre une image suffisamment grande pour éviter l’effet damier: lorsqu’une image est trop petite celle-ci est répétée autant que besoin pour couvrir la totalité de l’écran.

Le redimensionnement

Tout un tas de truc a été ajouté, mais pas prévu pour être redimensionné comme dans l’article précédent. Y a plus qu’à s’y mettre.

Souvenez-vous du principe et de la méthode:
– des valeurs utilisées (et adaptées) de la plateforme le développement énumérées et stockées dans le namespace conf;
– une fonction resizeDisplayData du namespace game prenant des ratios d’adaptation (calculés à partir de la plateforme d’exécution) en paramètres, utilisés pour redimensionner et adapter les valeurs du namespace conf à la plateforme d’exécution.

Le bloc central intégrant de terrain de jeu:

<div id="blocToCenter" style="width:1010px;height:400px;position:absolute;left:50%;top:50%;margin:-200px 0 0 -505px;">
....
</div>

Voyez que le style comporte deux propriétés width et height fixée en dur, propriétés dont il va falloir ajuster a valeur selon les caractéristiques de l’écran d’exécution.

Il y a aussi deux valeurs utilisées dans la propriété margin: ces deux valeurs sont respectivement la moitié des deux valeurs précédentes.

En conséquence, n’ajouter au namespace conf que les valeurs width et height suffit pour faire le redimensionnement (les valeurs fixées sont celles utilisées pour la plateforme de développement).

var conf = {

  BLOCCENTERWIDTH : 1010,
  BLOCCENTERHEIGHT : 400,
  ...
}

Ces deux valeurs vont être réajustées via la méthode resizeDisplayData, donc rien à faire de ce côté là. Par contre, vous devez réaffecter les valeurs réajustées dans la méthode init.

this.blocToCenter = document.getElementById("blocToCenter");
this.blocToCenter.style.width = conf.BLOCCENTERWIDTH + "px";
this.blocToCenter.style.height = conf.BLOCCENTERHEIGHT + "px";
this.blocToCenter.style.margin = "-" + conf.BLOCCENTERHEIGHT/2 + "px 0 0 -" + conf.BLOCCENTERWIDTH/2 + "px";

Ceci vous oblige aussi à déclarer la propriété blocToCenter au sein du namespace game.

var game = {
   
  blocToCenter : null,
  ....
}

Les blocs et images encapsulés dans la balise div blocToCenter sont aussi à redimensionner en utilisant la même méthode.

Il reste à traiter donc :
– le bloc de gauche (id=left);
– le bloc de droite (id=right);
– le bloc encapsulant le canvas html5 (id=divGame);
– les trois boutons start (id=startGame), pause (id=pauseGame) et continue (id=continueGame).

Les trois boutons et le bloc div divGame sont déjà définis en tant que propriétés du namespace game:
startGameButton pour le bouton startGame;
pauseGameButton pour le bouton pauseGame;
continueGameButton pour le bouton continueGame;
divGame pour le bloc encapsulant le canvas html5.

S’ajoutent au namespace conf les déclarations suivantes:

var conf = {
  ....
  BLOCLEFTWIDTH : 150,
  BLOCLEFTHEIGHT : 400,
  BLOCRIGHTWIDTH : 150,
  BLOCRIGHTHEIGHT : 400,
  BLOCDIVGAMEWIDTH : 700,
  BLOCDIVGAMEHEIGHT : 400,

  BUTTONSTARTGAMEWIDTH : 100,
  BUTTONPAUSEGAMEWIDTH : 100,
  BUTTONCONTINUEGAMEWIDTH : 100,
  ....
}

S’ajoutent au namespace game les réaffectations de valeur après redimensionnement dans le méthode init:

var game = {
  ....
  init : function() {
    ....
    this.blocRight = document.getElementById("right");
    this.blocRight.style.width = conf.BLOCRIGHTWIDTH + "px";
    this.blocRight.style.height = conf.BLOCRIGHTHEIGHT + "px";
	
    this.divGame = document.getElementById("divGame");
    this.divGame.style.width = conf.BLOCDIVGAMEWIDTH + "px";
    this.divGame.style.height = conf.BLOCDIVGAMEHEIGHT + "px";
	
    this.startGameButton = document.getElementById("startGame");
    this.startGameButton.style.width = conf.BUTTONSTARTGAMEWIDTH + "px";
	
    this.pauseGameButton = document.getElementById("pauseGame");
    this.pauseGameButton.style.width = conf.BUTTONPAUSEGAMEWIDTH + "px";
	
    this.continueGameButton = document.getElementById("continueGame");	
    this.continueGameButton.style.width = conf.BUTTONCONTINUEGAMEWIDTH + "px";
    ....
  }
  ....
}

Les bases sont désormais installées. A vous de les agrémenter comme bon vous semble. De la pub, un décor plus fouillé, c’est à votre imagination de bosser.

 
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  |  1 commentaire

Une réponse à "Coder le jeu video html5 pong – le décor"

Répondre

*