Sauter sur une plate-forme sans s’y cogner la tête: comprendre les mécanismes de collision.

Ce tutoriel utilise le modèle physique arcade. Il s’agit du modèle physique Il n’est pas forcément adapté pour d’autres modèles physiques.

L’association de Tiled avec Le mécanisme de collision de Phaser est plus complexe qu’il n’y parait, mais permet de nombreuses possibilités. Dans cet exemple, nous montrons comment faire en sorte de n’activer la collision entre deux objets que si une condition spéciale est remplie. Cela permet par exemple, de ne pas se cogner à une plate-forme, de pouvoir monter dessus en étant en dessous, mais de ne pas tomber une fois dessus. 

Ce que contient ce tutoriel :  

  • une analyse un peu plus poussée de la méthode collide() pour le moteur physique arcade
  • un exemple dans lequel un personnage peut sauter sur une plate-forme sans se cogner la tête s’il se situe sous cette dernière.
Ce que NE contient PAS ce tutoriel :  
  •  la gestion des collisions pour d’autres moteurs physiques 

Le résultat est un jeu dans lequel un personnage peut sauter sur une plate-forme alors qu’il se situerait en dessous de cette dernière.

Test du résultat de ce tutoriel

Le code et les fichiers résultats de ce tutoriel sont disponibles à l’adresse suivante :

https://github.com/bdarties/Phaser3_insert_single_map_from_tiled

Base de départ pour ce tutoriel

Nous partons d’un jeu dans lequel un personnage est présent sur un monde de taille fixe avec un fond, un sol et 3 plates-forme. Ce personnage peut aller à gauche, à droite, et sauter avec la flèche du haut s’il touche le sol (voir Figure 1). Ce code le résultat du tutoriel “making your first phaser 3 game” :

https://phaser.io/tutorials/making-your-first-phaser-3-game  

Ce code est disponible dans codesandbox via le lien suivant :

https://codesandbox.io/s/phaser-plateforme-simple-26hbt?fontsize=14&hidenavigation=1&theme=dark

base_plateforme
Figure 1 : un personnage pouvant bouger dans un monde simple

Les mécanismes de collision présents ici sont élémentaires : le personnage player et les plate-formes (définies dans un groupe platforms) sont en collision, depuis l’ajout dans la fonction create() de la ligne ci-dessous :

// ajout d'une collision entre le personnage et les plate-formes
this.physics.add.collider(player, platforms); 

Le personnage peut donc tenir sur chaque plate-forme, mais se retrouve également coincé dessous, et se cognera la tête s’il entreprend un saut alors qu’il se situe en dessous. Ce comportement est normal ici.

La méthode collider()

Les fonctions de callBack de la méthode collider()

Dans le mode physique arcade, quand on veut mettre en place une collision entre un personnage player et une plateforme (qui serait dans un groupe platforms par exemple) on peut écrire tout simplement dans la méthode  create() la commande suivante :

this.physics.add.collider(player, platforms); 

Ceci est en fait une notation abrégée ne comprenant que deux paramètres! La notation complete est :

this.physics.add.collider(player, platforms, null , null); 

Il est possible d’ajouter à ses paramètres 2 fonctions particulières qui remplaceraient null et null :

  • une fonction dite de collideCallback, qui est exécutée si les deux objets se touchent,
  • et une fonction dite de processCallback, qui peut valider vraiment la collision lorsque deux objets se touchent … ou pas ! C’est de cette seconde fonction que nous allons discuter.

Lorsque la fonction de processCallback n’existe pas, les deux objets rentrent toujours en collision quand ils se touchent. Mais si la fonction de processCallback existe, les objets rentreront en collision si et seulement si la fonction de processCallback renvoie true. Cette fonction, lorsqu’elle est exécutée, prend en paramètre les deux objets qui sont rentrés en collision.

Ajout d'une fonction de processCallBack : des conditions supplémentaires pour la collision entre objets

Dans l’exemple ci-dessous, on modifie la collision pour que cette dernière n’ait lieu que si le personnage player arrive sur la plate-forme, mais pas depuis le dessous (il ne se cognera pas). 

Nous ajoutons tout d’abord une simple fonction nommée ici verifCollision(), qui servira de fonction de processCallback : cette fonction prend deux paramètres, et retourne vrai si le premier paramètre est un personnage qui se situe au dessus du second, ou si le second paramètre est un personnage qui se situe au dessus du premier. Elle retourne faux autrement. Ainsi la collision n’aura lieu que si le personnage se situe sur la plate-forme.

function verifCollision (objet1, objet2) { 
/* retourne vrai si objet 1 est un personnage qui se situe au dessus de objet 2,
   ou si objet 2 est un personnage qui se situe au dessus de objet 1
*/

    // cas où le premier objet est le personnage et le second la plate-forme
    // et que objet 1 se situe au dessus de objet 2
    if (objet1 == player && objet1.y < objet2.y) {
        return true;
        }
    // cas où le second objet est le personnage et le premier la plate-forme
    // et que objet 2 se situe au dessus de objet 1
    if (objet2 == player && objet1.y > objet2.y) { 
        return true;
    }
    // pour tous les autres cas : on desactive la collision 
    return false; 
} 

Enfin on modifie dans create() la fonction de collision comme suit en appelant verifCollision() :

this.physics.add.collider(player, platforms, null , verifCollision); 

Il suffit enfin de tester le jeu pour voir que le comportement de la collision a changé.

Laisser un commentaire

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