Accélérer un jeu vidéo

Lorsque vous utilisez une seul et unique canvas html5 pour l’affichage d’un jeu vidéo, vous rafraichissez la totalité du canvas html5 en effaçant et réaffichant chacun des éléments à chaque itération d’affichage.

En html5, plus les images sont grandes, plus elles sont couteuses à afficher. Vous devez donc éviter au maximum l’affichage itératif de grandes images, sans quoi la vitesse du jeu s’en ressentira.


Si vous développez un jeu vidéo comportant un arrière plan statique affichant une image de sa taille, il semble de bon augure de ne pas réafficher cet arrière plan à chaque itération d’affichage.

L’optimisation consiste donc à empiler deux canvas html5 empilés l’un sur l’autre : l’un dédié au premier plan à fond transparent, l’autre dédié à l’arrière plan comportant l’image statique. Puis à ne rafraichir que le premier plan.

Ne pas retracer l’arrière plan fait gagner un temps machine précieux.

 

Prérequis

– Savoir ce qu’est html et connaître la balise canvas;
– savoir ce qu’est un style et savoir l’utiliser;
– avoir des connaissances de base en javascript.

 

L’exemple

Dans cet exemple, vous allez afficher une image de fond statique qui n’a pas besoin d’être rafraichie, et une image animée au premier plan correspondant à un sprite.

Pour le projet, reprenez l’arborescence suivante.

Reprenez le code de base suivant (les explications dans l’article Initialiser le développement d’un jeu vidéo).

<script>
// début du code isolé
(function () {
 let requestAnimId;
 
 const initialisation = function() {
   // le code de l'initialisation 
   requestAnimId = window.requestAnimationFrame(principale);
 }
 
 const principale = function() {
   // le code du jeu
   requestAnimId = window.requestAnimationFrame(principale);
 }
 
 window.onload = initialisation; // appel de la fonction initialisation au chargement de la page
})();
// fin du code isolé
</script>

Initialisation

Vous allez dans un premier temps créer deux canvas empilés.

C’est la propriété z-index du style qui permet de maitriser l’empilement : le canvas ayant le z-index le plus faible étant le canvas le plus en arrière plan.

Par le biais de la propriété id, nommez :
– background le canvas ayant le z-index à 0;
– foreground le canvas ayant le z-index à 1.

Le code source des deux canvas.

<canvas id="background" width="1000" height="600" style="position: absolute; z-index: 0">
</canvas>
<canvas id="foreground" width="1000" height="600" style="position: absolute; z-index: 1">
</canvas>

La fonction d’initialisation

Vous allez créer deux variables relatives aux contextes des deux canvas. Puis dans le canvas du fond d’écran (background), vous affichez l’image de fond. Enfin, dans le canvas de premier plan (foreground), vous affichez l’image d’un sprite html5.

La fonction initialisation prend la forme suivante.

let canvasContextBg;
let imgBg;
let canvasContextFg;
let imgFg;
 
const initialisation = function() {
  canvasContextBg = document.querySelector('#background').getContext('2d');
  canvasContextFg = document.querySelector('#foreground').getContext('2d');
   
  imgBg = new Image();
  imgBg.src = 'https://www.video-game-coder.fr/download/jsperf/background.jpg';
  canvasContextBg.drawImage(imgBg,0,0);
     
  imgFg = new Image();
  imgFg.src = 'https://www.video-game-coder.fr/download/jsperf/module.png';
  canvasContextFg.drawImage(imgFg,100,100);
     
  requestAnimId = window.requestAnimationFrame(principal);
};

4 variables ont été initialisées : canvasContextBg, imgBg, canvasContextFg, imgFg.

 

Implémentation de la boucle d’affichage (principale)

La fonction principale appelée en boucle efface le premier plan puis réaffiche l’image du sprite html5. On ne se préoccupe pas de l’arrière plan qui est statique : il est affiché à l’initialisation, ce qui est suffisant. Seuls sont rafraichis les canvas comportant des objets animés.

let posX = 10;
let posY = 10;
const principal = function() 
  canvasContextFg.clearRect(0,0,1000,600);
  canvasContextFg.drawImage(imgFg,++posX,posY);
  requestAnimId = window.requestAnimationFrame(principal);
};

Pour voir la démo, cliquez ici.

 

La preuve par les benchmarks

J’ai réalisé par le biais de jsperf et les résultats sont éloquents, constatez par vous-même.

Quelque soit le navigateur, la version optimisée est toujours la plus rapide. Le différentiel relatif le plus important est sous Firefox. Cependant, chrome est le navigateur aussi plus rapide dans le mode simple layer par rapport au mode double layer des autres navigateurs.

 

Conclusion

Ce qui a été vu ici n’est pas l’unique optimisation, il en existe d’autres que j’aborderai prochainement. Un petit bémol à cette optimisation : n’imaginez pas avoir le même différentiel sur un jeu fini, l’affichage n’étant pas l’unique composante d’un jeu.

Apprenez à créer un jeu vidéo en une soirée.

Accessible à tous. Pour moins de 10€.
Dernières places disponibles pour l'année 2024.

Ce format court sera abandonné en 2025.

Voir l'événement

Bravo, jette un œil à ta boite mail pour télécharger ton guide.