“Comment faire mourir un sprite s’il tombe dans un trou?” ou comment détecter efficacement les collisions d’un sprite avec les bornes du monde.

Dans ce tutoriel nous regardons comment détecter que le personnage rentre en collision avec un bord du monde; Cette fonctionnalité est principalement utilisée pour détecter quand le personnage va “tomber” et toucher le bas de l’écran. En pareil cas, nous pourrons déclencher un game over.

Les notions abordées sur ce tutoriel sont : 

  • la détection de collisions avec les frontières du monde,
  • la gestion des collisions en tant qu’événement 
  • l’analyse fine de la collision avec le monde : à gauche, a droite, en haut ou en bas  du monde?

Le résultat est un jeu dans lequel un personnage se cogne à gauche ou à droite de l’écran sans mourir, mais meurt (teinture en rouge et physique en pause) s’il touche le bas de la zone d’affichage.

Démo du résultat à obtenir avec ce tutoriel

Base de départ pour ce tutoriel

Nous partons d’une base constituée d’un jeu dans lequel un personnage est présent sur un monde de taille fixe avec une gravité prédéfinie. Ce personnage peut aller à gauche, à droite, et sauter avec la flèche du haut s’il touche le sol. Les animations sur ce personnage ont été définies. Cette base a été créée à partir du tutoriel  Créer son premier jeu de plate-forme en découvrant Phaser sur lequel on a enlevé toute la partie “génération des étoiles”, “génération du score”, “génération des bombes”. 

Figure 1 : un personnage pouvant bouger dans un monde simple

Cette base est directement accessible sur codesandbox sous forme de template: lorsque vous créez une nouvelle sandbox, choisissez « explore templates » et et recherchez dans la barre de recherche « phaser-base-plateforme ». 

I - Création du trou

La première étape est triviale : on bouge une des deux plate-formes servant de sol pour créer un trou. Remplacez par exemple la ligne :

  groupe_plateformes.create(600, 584, "img_plateforme"); 

par la ligne :

  groupe_plateformes.create(660, 584, "img_plateforme"); 

II - Création de l'écouteur de détection

Dans la fonction create(), une fois le personnage du joueur créé, on active la collision avec les bords du monde. Ajoutez – ou vérifiez la présence de – la ligne suivante :

player.setCollideWorldBounds(true); // le player se cognera contre les bords du monde
 

On va ensuite dire à la hitbox du personnage de surveiller les événements de collision avec le monde, en ajoutant, toujours dans create(), la ligne suivante :

  //on acvite l'écouteur sur les collisions avec le monde
  player.body.onWorldBounds = true; 

Enfin on va associer une fonction de callback (rappel) lorsque l’événement de collision contre les frontières du monde (appelé worldbounds) se produit. la syntaxe de création de l’événement est un peu déroutante à plusieurs titres ,et est expliquée en dessous de la fonction. Dans create(), à la suite des lignes précédemment ajoutées, ajoutez le bloc suivant :

  // on met en place l'écouteur sur les bornes du monde
  player.body.world.on(
    "worldbounds", // evenement surveillé
    function (body, up, down, left, right) {
      // on verifie si la hitbox qui est rentrée en collision est celle du player,
      // et si la collision a eu lieu sur le bord inférieur du player
      if (body.gameObject === player && down == true) {
        // si oui : GAME OVER on arrete la physique et on colorie le personnage en rouge
        this.physics.pause();
        player.setTint(0xff0000);
      }
    },
    this
  ); 

Les différents points syntaxiques sont expliqués ci-dessous :

  • Il nous faut ajouter un écouteur sur le monde, disant que si une collision se produit entre le monde et une hitbox, on déclenche une fonction de callback. Or nous n’avons pas de référence directe vers le monde. Mais toute hitbox possède une référence vers le monde auquel elle appartient. Ainsi player.body désigne la hitbox de player, et player.body.world désigne le monde dans lequel évolue la hitbox de player.
  • Une fois que l’on a une référence sur le monde, on ajoute un écouteur sur un événement à surveiller. Cet écouteur se fait via la méthode “on()” qui prend 3 paramètres : le nom de l’événement à surveiller (ici “worldbounds” ), la fonction de callback (rappel) à exécuter quand l’événement survient, et l’environnement d’appel (souvent this)
  • Ici la fonction de callback est entièrement écrite dans, le 2eme paramètre de on(). On aurait pu l’écrire en dehors et mettre simplement son nom à la place.
  • La fonction de callback sera exécutée en remplissant automatiquement 5 paramètres : le premier, body, désigne la hitbox qui vient de rentrer en collision. Les 4 autres up, down, left, right sont des booléens qui sont remplis automatiquement avec des valeurs true ou false, pour nous indiquer avec quel bord le player a cogné avec les bornes du monde. Ces 4 paramètres anodins vont nous etre super utiles : ils permettront de savoir si le player s’est cogné avec le bord gauche ou droit, et dans ce cas on ne fait rien, ou si c’est avec le bord inférieur down, et dans ce cas on déclenchera un game over : si la hitbox touche en bas du monde, alors down est à true.
  • A l’intérieur de la fonction de callback, il nous faut savoir si la hitbox qui est rentrée en collision avec les frontières du monde appartient bien au playerC’est le rôle de l’attribut “gameObject“, qui désigne l’objet à qui la hitbox appartient. Si cet objet est égal au player, alors il s’agit bien du player qui est rentré en collision avec le monde.
Avec tous ces éléments, le code ci-dessus devient un peu plus compréhensible et modifiable à souhait. 

testez enfin votre jeu et voyez que votre personnage ne pourra pas aller à gauche ni a droite (collision) mais en plus mourra s’il touche le bas du monde.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

− 3 = 3