Imagine que tu joues à un jeu vidéo ( parce que c’est quand même l’objectif final que l’on recherche ici 😁 ). Quand tu appuies sur une touche, par exemple pour faire sauter ton personnage, tu vois immédiatement ton personnage sauter, puis redescendre. Tu vois aussi l’ennemi qui se déplace ou ton score qui change.
Et bien tout ça, c’est grâce à la boucle de jeu ! 🎮
Et si je ne veux pas réaliser cette boucle de jeu ?
Sans la boucle de jeu, il serait impossible de répéter les actions nécessaires pour rendre un jeu interactif. En programmation impérative, chaque instruction est exécutée une seule fois, dans l’ordre où elle apparaît, puis c’est la fin du programme.
Par exemple, si tu veux que ton personnage se déplace sans arrêt, tu aurais besoin d’une manière de répéter ce mouvement encore et encore à chaque seconde.
Mais comment répéter le mouvement le bon nombre de fois ?
Bonne question ! On ne peut pas 🙂
Si on utilise la boucle « for » pour répéter l’instruction, il nous faut un compteur pour déterminer quand arrêter de répéter l’action. Or, on ne sait pas à l’avance ce que choisira le joueur de faire, ni quand. Nous avons donc besoin de résoudre cette problématique.
C’est là qu’intervient la boucle de jeu !
Elle permet de répéter tout ce qui doit être fait en continu, pour que le jeu réagisse instantanément et de manière fluide.
La boucle de jeu s’assure que les actions du joueur (comme appuyer sur une touche ou déplacer un personnage) sont répétées à chaque fois que le joueur le demande.
Elle permet donc de contourner la limitation de la programmation impérative en offrant un mécanisme de répétition continu.
La boucle de jeu est une boucle qui se répète sans fin, par exemple une boucle « while ». Elle fait tout ce qui est nécessaire pour que ton jeu fonctionne. Elle réalise ainsi plusieurs tâches à chaque tour de boucle :
Vérifier ce que fait le joueur (grâce à la souris, au clavier ou à la manette par exemple)
Mettre à jour ce qui se passe dans le jeu (position du joueur, des ennemis, etc.)
Rafraîchir l’écran (redessiner l’image)
Voici un schéma qui résume ce que fait la boucle de jeu à chaque instant :
Chaque fois que la boucle de jeu se répète, elle écoute ce que fait le joueur.
Par exemple :
Est-ce que tu appuies sur une touche pour avancer ?
Est-ce que tu fais sauter ton personnage ?
Est-ce que tu as cliqué quelque part ?
etc.
C’est comme un détecteur de mouvements.
Une fois que la boucle a vérifié ce que fait le joueur, elle passe à l’action suivante : mettre à jour le jeu.
Par exemple :
Si tu appuies sur une touche, la boucle va déplacer la position de ton personnage.
Elle va également déplacer automatiquement les autres personnages non joueurs ou leur faire réaliser des actions
Elle va aussi faire changer le score ou mettre à jour l’écran.
etc.
C’est un peu comme si la boucle de jeu donnait des ordres à tous les éléments du jeu : « Déplace-toi, saute, avance, change de direction ! »
Ensuite, après avoir mis à jour ce qui se passe dans le jeu, la boucle de jeu doit montrer ce qui vient de changer. Cela veut dire qu’elle actualise ce qui est visible à l’écran. On dit que l’on rafraîchi l’affichage.
Par exemple :
Le score peut augmenter si le joueur gagne des points.
Le personnage a sauté et doit maintenant apparaître plus haut.
Un ennemi est peut-être tombé et doit disparaître de l’écran.
Attends, attends… tu me parles de réactualiser l’écran, c’est quoi ça ?
Une fois que le jeu a été mis à jour, il faut afficher le nouveau résultat à l’écran.
Mais attention, l’image n’est pas simplement modifiée, elle est entièrement redessinée à chaque tour de boucle pour éviter que les images se superposent.
Voici comment cela se passe concrètement :
On affiche l’image
On efface
On affiche l’image légèrement modifiée (ex: le personnage a avancé d’un pixel)
On efface
et on recommence, encore et encore…
Et le tableau avec la peinture dans tout ça ?
L’affichage dans un jeu vidéo, c’est un peu comme peindre sur une toile à chaque tour de la boucle de jeu. Imagine le scénario suivant :
Tu as une grande toile blanche.
À chaque instant, tu effaces tout.
Puis tu repeins la scène du jeu : ton personnage, les ennemis, le décor, etc.
Plus précisément :
Le tableau vide : Au début, l’écran est comme une toile fraîche, sans rien dessus.
Dessin : On peint les éléments de notre jeu. (C’est alors que le joueur se déplace)
Effacer pour recommencer : Avant de redessiner, on efface l’image précédente.
Sinon, le personnage laisserait une traînée derrière lui…
Un peu comme Flash qui court à super-vitesse ⚡
Peindre les éléments du jeu : Une fois l’écran effacé, on redessine le personnage à sa nouvelle position, les ennemis mis à jour, les éléments du décor, etc. C’est ce qui sonne l’impression de mouvement fluide.
Rafraîchir régulièrement : Et on recommence… ce processus se répète des dizaines de fois par seconde.
En résumé, à chaque tour de la boucle de jeu, c’est comme si tu créais un nouveau tableau : tu effaces les anciennes couches, tu peins les nouveaux éléments et tu actualises l’affichage pour montrer le résultat au joueur. C’est ce processus constant qui permet au jeu de rester dynamique et interactif !
On appelle chacun de ces tableaux une « frame » et donc nous pouvons appeler Frames Per Seconds (FPS) le nombre de fois que l’on réaffiche le tableau par seconde. Plus cette mesure est élevée plus nous aurons un affichage fluide à l’écran
Lorsque l’on affiche 5 frames par secondes, on peux distinguer comme un effet de motion design, le mouvement est extrêmement saccadé.
À 30 FPS, les mouvements sont visibles et acceptables dans la plupart des jeux. Tu peux commencer à voir les images individuelles se succéder, mais l’animation reste généralement fluide. Dans le jeu vidéo, on considère généralement que 30 FPS constitue le seuil minimum pour une animation fluide.
À 60 FPS, l’animation devient bien plus fluide. Les mouvements des personnages, les objets et les animations sont perçus de manière très naturelle. C’est le standard pour les jeux modernes et les vidéos sur certaines plateformes. Les différences entre 30 et 60 FPS sont assez perceptibles pour un joueur attentif, surtout dans les jeux rapides où les mouvements sont très dynamiques (comme les jeux de tir ou de course).
Cependant, au-delà de 60 FPS, l’amélioration visuelle est plus subtile. À partir de 120 FPS, la différence devient de plus en plus difficile à percevoir, sauf pour les joueurs particulièrement attentifs ou ceux qui utilisent des moniteurs à haute fréquence de rafraîchissement.
Le savais-tu ?
C’est à la fin des années 1920 que le cinéma adopte le standard de 24 images par seconde, un compromis permettant d’obtenir une image perçue comme suffisamment fluide, tout en réduisant les coûts de production.
La boucle de jeu répète plusieurs étapes en continu pour afficher l’état du jeu et lui permettre d’être interactif et dynamique :
Vérifier ce que fait le joueur : La boucle vérifie en permanence les actions du joueur (appuie-t-il sur une touche ? déplace-t-il un personnage ?).
Mettre à jour les actions dans le jeu : Les personnages se déplacent, les ennemis réagissent, le score change, etc.
Rafraîchir l’écran : La boucle efface l’affichage précédent et dessine les nouveaux éléments pour refléter les changements.
Chaque cycle de la boucle est appelé une frame, et le nombre de frames affichées par seconde (FPS) détermine la fluidité visuelle du jeu :
À 30 FPS, l’animation est fluide et acceptable, souvent utilisée pour les films et certains jeux.
À 60 FPS, les mouvements deviennent très fluides, ce qui est idéal pour les jeux modernes.
À 120 FPS ou plus, la différence devient difficile à percevoir pour la plupart des joueurs, sauf sur des écrans haute fréquence.
Grâce à la boucle de jeu et à une gestion des FPS optimisée, le jeu offre une expérience fluide et agréable. 🎮
Plan du chapitre Table des matières
Introduction
Premiers pas avec Phaser
Les bases de Phaser