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.
- 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
Base de départ pour ce tutoriel
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
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é.