Ce second TP portera sur la création d'un jeu de plateforme à l'aide de la bibliothèque de création de jeu Phaser.
Nous en profiterons pour approfondir notre connaissance de la bibliothèque, notamment en découvrant la gestion des images et en explorant la communication entre les scènes et différents types de collision.
Les notes des TP seront obtenues à partir de vos dépôts Git, vous devrez donc prendre grand soin de la qualité de ces dépôts et de leurs « commits ».
De manière similaire, les descriptions de vos « commits » devront être claires et informatives, afin de permettre l'évaluation de la progression de votre travail.
Comme pour le TP précédent, vous partirez de la structure du projet du dépôt r301-js-template
. Vous commencerez donc par cloner le projet en local dans un répertoire « r301-js-platformer ».
Vous modifierez les fichiers nécessitants une mise à jour des informations (« package.json », « README.md », « src/index.html »...).
Vous re-initialiserez le dépôt Git local avant de réaliser votre premier commit.
Vous créerez un dépôt Git distant sur GitLab « r301-js-platformer », que vous associerez à votre dépôt local. Vous penserez à ajouter votre intervenant de TP comme membre du projet avec un rôle de « Reporter ».
Et pour finir, vous installerez toutes les dépendances du projet à l'aide de npm.
Vous devriez maintenant avoir un projet fonctionnel, dans lequel vous allez pouvoir créer votre jeu.
r301-js-template
.
Dans le TP précédent, tout le jeu se déroulait dans un même espace. Cependant, la plupart des jeux disposent de plusieurs écrans d'affichage, a minima un écran d'accueil et un écran de jeu.
Sur ce principe, vous allez remplacer la scène Play
par la première scène Title
correspondant à l'écran d'accueil. Elle affichera le titre de votre jeu et une invite à cliquer ou presser une touche.
Afin de donner un peu de vie à votre page de titre, vous ajouterez un « tween » permettant d'animer le texte de l'invite de jeu, avec une fonction d'interpolation élastique par exemple.
Vous créerez ensuite une deuxième scène Level1
représentant le premier niveau du jeu. Elle ne comportera pour l'instant qu'un texte l'identifiant.
Phaser permet de gérer plusieurs scènes actives en même temps, mais dans un souci de simplicité, nous ne gérerons qu'une scène à la fois. Vous prendrez donc soin lors de l'ajout de ces scènes à l'instance de jeu, de n'activer que la scène d'accueil.
Phaser identifie les différentes scènes à l'aide de chaînes de caractères. Les bonnes pratiques vous encouragent à définir cette clé comme une propriété de classe dans chaque scène et de n'utiliser que cette propriété pour référencer la scène et non sa valeur.
Enfin, vous ajouterez deux gestionnaires d'événements, l'un réagissant au clic de la souris et l'autre à l'appui d'une touche. Ils déclencheront tous les deux le démarrage de la scène Level1
.
Play
par la scène Title
.
Level1
.
Pour créer le premier niveau du jeu, nous allons utiliser des images. Pour commencer, vous allez ajouter une image à votre projet permettant de représenter un bloc de plateforme solide. Afin d'être utilisé dans le jeu, une image doit être accessible par celui-ci. Vous placerez donc l'image suivante : « stone.png » dans le sous-répertoire « public/img ».
Le répertoire « public » est le répertoire que vite utilise pour fournir les ressources statiques du site (les « assets »). Les ressources statiques sont les ressources que vite n'a pas besoin de transformer, les images, sons, vidéos...
Vous pourriez ajouter des blocs de pierre à votre jeu à l'aide de l'usine à object du jeu. Cependant, un niveau de jeu se composant de très nombreux blocs de plateforme, la création et la gestion de chaque bloc individuellement va être rapidement fastidieux. La gestion collective, pour la collision par exemple, peut être rapidement résolu à l'aide des groupes, mais pour résoudre le problème de création de bloc individuellement, vous allez créer deux nouvelles classes : TileGroup
et StoneGroup
.
TileGroup
et StoneGroup
diagrammesConformément au diagramme précédent, la classe TileGroup
hérite de la classe Phaser.Physics.Arcade.StaticGroup
. Elle permet de créer des groupes d'images pavant la zone de jeu.
Cet élément de jeu repose sur le moteur physique arcade, vous prendrez soin de l'activer dans la configuration de votre jeu.
La propriété tileName
contiendra l'identifiant de l'image à utiliser. Les propriétés tileWidth
et tileHeight
représente la largeur d'une colonne et la hauteur d'une ligne du pavage produit par le groupe.
La méthode addTiles
crée et ajoute au groupe un ensemble de blocs d'image en une fois. les blocs d'images seront structurés sous forme d'un rectangle, x
et y
seront les coordonnées de la première image en haut à gauche avec width
et height
le nombre de blocs d'image en largeur et en hauteur. Pour simplifier la conception du niveau, les coordonnées seront exprimées en lignes et colonnes de blocs d'image, par exemple, dans notre cas l'image « stone.png » faisant 64×64, l'invocation de la méthode addTiles(2, 3, 3)
créera une plateforme de 3 blocs dont les coordonnées du coin supérieur gauche seront (128, 192) (2×64, 3×64). Encore une fois, afin de simplifier, le positionnement des éléments, vous configurerez l'origine de chaque bloc d'image créé dans le coin supérieur gauche.
Pour faciliter la création des groupes de blocs, vous permettrez l'utilisation fluide de la méthode addTiles
en retournant l'instance courante.
Vous pourrez alors créer la classe StoneGroup
conformément au diagramme précédent, et dont la fonction sera de produire un groupe spécialisé pour l'affichage de blocs de pierre. La méthode de classe preload
devra être invoquée depuis la méthode preload
d'une instance de scène pour réaliser le chargement de l'image.
Vous devriez maintenant être capable d'afficher plus facilement des groupes de pierre dans le niveau. Mais avant de poursuivre, penchons nous sur un dernier détail. Les plus attentifs auront remarqué que le groupe dont hérite TileGroup
provient de l'espace de nom du moteur physique Arcade. Les blocs d'image créés ont donc déjà un corps physique, pour les visualisés, vous pouvez activer le débogage dans la configuration du moteur physique, lors de la configuration du jeu.
Vous devez probablement constater un décalage entre les images et la boîte englobante de leur corps physiques. Ceci est dû au fait que vous avait modifié l'origine des images après leur création et que Phaser ne met pas à jour les corps physiques. Pour résoudre ce problème, vous devez rafraîchir le corps physique des blocs d'image aprés avoir modifié l'origine.
TileGroup
et StoneGroup
.
Maintenant que le groupe de blocs de pierre est fonctionnel, de manière similaire, vous créerez un groupe de blocs de lave : LavaGroup
, utilisant l'image « lava.png ».
Vous pourrez enfin créer le premier niveau du jeu afin qu'il corresponde au schéma suivant :
LavaGroup
.
Comme précédemment, vous commencerez par ajouter l'image du joueur à votre projet « player.png ».
Vous allez créer la classe Player
et l'employer dans la classe Level1
conformément au diagramme suivant :
Player
diagrammeVous commencerez par créer la classe Player
avec uniquement sa propriété de classe, son constructeur et la méthode de classe preload
. L'image du joueur (« player.png ») est en réalité un dictionnaire d'image du joueur, chaque vignette faisant la même taille, 40×40. Pour charger ce type d'image, vous utiliserez la méthode spritesheet
. Pour la configuration des vignettes (frameConfig
), vous ne fournirez que la largeur et la hauteur. Dans le constructeur, vous prendrez soin de redéfinir l'origine de l'image en haut à gauche et d'ajouter au joueur un corps physique.
Une fois créée, vous utiliserez la classe pour ajouter un joueur dans la case (1, 7) du premier niveau. Vous constaterez que le joueur reste suspendu en l'air, vous ajouterez donc une gravité de 1000 au moteur physique. Et pour empêcher le joueur de traverser les plateformes de pierre, vous ajouterez un gestionnaire de collisions, à l'usine d'éléments physiques de la scène (this.physics.add
) entre le joueur et le groupe des blocs de pierre, qui empêchera les éléments de se superposer.
Maintenant, le joueur devrait tomber au sol, et ne plus bouger. Vous allez remédier à celà en ajoutant un peu d'interaction. Vous commencerez par ajouter les méthodes #move
, moveRight
, moveLeft
et stop
à la classe Player
.
#move
permet de déplacer le joueur latéralement. Vous utiliserez un tween permettant d'animer l'abscisse de la vélocité du corps physique pour l'amener à la valeur passée en paramètre. L'interpolation pourra être cubique et durée 300ms.moveRight
et moveLeft
utilisent #move
pour animer l'abscisse de la vélocité du joueur à 300 et -300 respectivement.stop
permet d'arrêter le joueur en ramenant l'abscisse de la vélocité du joueur à 0. Vous utiliserez un tween pour l'animation. L'interpolation pourra être cubique sur une durée de 300ms.Comme dans le TP précédent, vous ajouterez le support des touches pour vous déplacer à gauche et à droite et pour sauter. Ensuite, vous ajouterez une méthode update
à la scène, dans laquelle vous testerez l'état des touches gauche et droite. Lorsqu'une seule des touches est pressée, vous invoquerez en fonction de la touche pressée, la methode moveLeft
ou moveRight
du joueur et sinon, vous invoquerez la methode stop
.
Pour les événements ponctuels, comme le tir dans le TP précédent, vous ajouterez un gestionnaire d'événement sur la touche du saut pour invoquer la méthode jump
du joueur. La méthode jump
du joueur appliquera un « tween » pour animer l'ordonnée de la vélocité du joueur en l'amenant à -400 en 50ms à l'aide d'une interpolation cubique. Afin d'empêcher le joueur de s'envoler en appuyant plusieurs fois sur la touche de saut, vous contrôlerez que le joueur touche le sol avant d'appliquer le « tween ».
Player
.
Vous avez dû remarquer que vous ne pouviez pas voir l'ensemble de la scène, pour résoudre ce problème, vous allez configurer la caméra afin qu'elle se déplace en suivant les déplacements du joueur. Dans la scène, vous activerez le suivi du joueur par la caméra principale du jeu, à l'aide de la méthode startFollow
. Comme dans le TP précédent, Phaser propose la gestion de multiple caméra, vous n'utiliserez que la caméra principale : main
Suite à cette modification, vous constaterez que la caméra étant centrée sur le joueur, l'affichage en bord de scène affiche une grande zone vide. Pour revenir à un comportement plus usuel, où le jeu n'affiche que la scène, vous allez limiter la zone accessible à la caméra. Vous commencerez par ajouter une méthode cachée #setBounds
à la scène qui recevra en paramètres les bornes de la scène, pour ce premier niveau, il s'agit d'une zone de 1472×640 (23*64 et 10*64) pixels dont le coin supérieur gauche est en (0,0). Et dans cette méthode, vous pourrez fixer les limites de déplacement de la caméra principale à l'aide de la méthode setBounds
.
Pour finir, vous noterez que le joueur peut sortir de la zone de jeu, ce qui n'est pas pratique pour le joueur. Dans son constructeur, vous allez limiter le déplacement du joueur aux dimensions du monde à l'aide de la méthode setCollideWorldBounds
. Vous devriez constater en vous déplaçant vers la gauche de la scène que le joueur est limité aux dimensions initiales de la zone de jeu. Vous mettrez donc à jour les dimensions du monde « physique » pour qu'il corresponde à la scène à l'aide de la méthode setbounds
dans la mèthode #setBounds
.
Le joueur devrait maintenant, expérimenté une expérience de jeu plus conventionnelle.
Vous devez vous souvenir que l'image que vous avez chargé pour le joueur était un dictionnaire d'images et que pour l'instant le joueur est un peu rigide lors de ces déplacements.
Dans la classe Joueur
, vous ajouterez une nouvelle méthode privée #createAnims
. Cette méthode nour permet surtout d'organiser le code en regroupant la création des animations en un même endroit, mais son invocation sera réalisée uniquement dans le constructeur.
Dans un premier temps, la méthode #createAnims
, ajoutera deux animations à notre joueur à l'aide de la méthode create
du gestionnaire d'animations du Joueur
:
Pour des exemples de création d'animations, vous pouvez vous référer à la documentation.
Vous pourrez ensuite utiliser ces animations lors du déplacement du joueur dans les méthodes moveRight
, moveLeft
et stop
. Pour le déplacement à gauche, vous utiliserez l'animation de gauche en retournant votre Sprite
à l'aide de sa méthode setFlipX
.
Dans cette section, vous allez ajouter un arrière-plan à votre scène. Cependant, pour l'instant, vous ne pouvez ajouter qu'une image d'une dimension au moins équivalente à la surface de jeu pour la recouvrir ou positionner vous-même plusieurs images afin de réaliser un pavage de la surface de jeu. Vous allez utiliser un nouveau type d'image permettant de paver automatiquement une surface.
Vous commencerez par ajouter à votre projet l'image employée recouvrir l'arrière-plan : « bg.png ».
Afin de se simplifier la gestion de l'arrière-plan, vous allez créer une classe Background
héritant de la classe Phaser.Physics.Arcade.StaticGroup
. Dans un premier temps, vous y placerez votre code concernant l'arrière-plan en le répartissant dans le constructeur et une méthode de classe preload
.
Vous allez ajouter une image de type TileSprite
à votre groupe, afin qu'elle occupe toute la zone de jeu. Vous penserez à désactiver le défilement afin que cette image reste toujours à l'écran.
Nous avons maintenant un arrière-plan que nous avons pu remplir avec une toute petite image. Cependant, cette image ne bouge pas lorsque la caméra suit le joueur, ce qui n'est pas convenable dans de nombreux cas. Pour résoudre ce problème conformément à la documentation de la classe, vous utiliserez la méthode setTilePosition
conjointement aux propriétés scrollX
et scrollY
de la camera principale lors de l'événement « followupdate » de la caméra principale.
Vous avez maintenant, un arrière-plan fonctionnel, mais il est courant d'avoir plusieurs images pour l'arrière-plan. Vous ajouterez les images « dust1.png » et « dust2.png » à votre projet.
Vous pourrez ensuite ajouter la variable suivante à votre module JavaScript contenant la classe Background
:
Vous pourrez parcourir ce tableau pour ajouter les images à votre arrière-plan. Vous utiliserez les urls comme clés des images chargées et en bouclant sur les clés du tableau, vous ajouterez les images à votre arrière-plan.
Dans notre cas, nous utilisons plusieurs images pour gommer un peu l'aspect répétitif de la texture de fond, vous allez donc décaler les images de manière similaire lors du déplacement de la caméra, mais sur le même principe, il serait facile de mettre en place un effet de défilement parallaxe en faisant varier le décalage de chaque image.
Background
.Pour illustrer la mort du joueur, vous allez utiliser un système de particules. Ceux-ci utilisent une image pour afficher les particules, vous commencerez par ajouter l'image « particle.png » à votre projet et vous ajouterez son chargement dans la classe Player
.
Vous pourrez ensuite ajouter une méthode death
au joueur qui provoquera la mort du joueur lors de son invocation.
Cette méthode commencera par créer un système de particules centré sur le joueur avec la configuration suivante :
Afin d'empêcher d'autre collision avec l'environnement, vous allez
Vous pourrez faire ensuite produire une explosion d'une vingtaine de particles et cacher le joueur.
Vous provoquerez le redémarrage de la scène à l'aide de la méthode restart
du gestionnaire de scène. Cependant, pour que l'animation de l'explosion soit visible, vous différerez le redémarrage de la scène ainsi que la réactualisation du clavier.
Pour finir, vous utiliserez cette méthode lors de la collision du joueur avec un bloc de lave. Vous devriez maintenant voir mourir votre joueur lorsqu'il tombe dans la lave et la scène devrait redémarrer.
Vous allez ajouter un ascenseur permettant de changer de scène. Pour cela, vous allez créer une classe Elevator
héritant de Phaser.Physics.Arcade.StaticGroup
. La classe proposera le chargement de la bibliothèque d'image « elevator.png », contenant des vignettes de 64×64, et le constructeur ajoutera au groupe un sprite que vous stockerez dans une propriété d'instance back
.
Vous devriez maintenant être capable d'afficher l'ascenseur dans la scène à la case (21, 7) de la scène.
Vous ajouterez une méthode privée #createAnims
que vous invoquerez dans le constructeur et qui créera les animations. Pour le moment, cette méthode créera une animation « open », comportant les vignettes de 0 à 3 à une vitesse de défilement de 20.
Vous allez maintenant pouvoir ajouter la méthode moveIn(player)
à la classe Elevator
permettant de faire rentrer le joueur dans l'ascenseur.
Vous commencerez par désactiver le clavier et invoquer la méthode stop
du joueur, puis vous provoquerez l'ouverture de l'ascenseur à l'aide de l'animation « open ».
Vous déplacerez ensuite le joueur au centre de l'ascenseur à l'aide d'un « tween ». Puis en différent l'invocation afin que l'animation soit finie, vous réactiverez le clavier et redémarrerez la scène.
Pour activer l'ascenseur, vous ajouterez un nouveau gestionnaire de touche de clavier avec la touche bas pour gérer l'interaction du joueur. Le gestionnaire d'événement invoquera la méthode privée #handleInteract
que vous ajouterez à la scène du premier niveau. Cette méthode utilisera la méthode overlap
du moteur physique (this.physics.world
) pour tester si le joueur est sur l'ascenseur en même temps qu'il est au sol et dans ce cas, invoquera la méthode moveIn
.
Elevator
.L'animation est fonctionnelle, mais pour refermer les porte de l'ascenseur, il faudrait les afficher devant le joueur. Il serait possible de jouer avec l'indice de profondeur (z-index), mais cette solution demande un peu de rigueur pour être cohérente dans le temps. Une autre solution consiste à créer des calques afin de gérer plusieurs niveaux de profondeur.
Mais avant d'ajouter des calques à votre projet, vous allez réorganiser votre code afin de simplifier la création des niveaux. Vous commencerez par créer une classe Level
héritant de la classe Phaser.Scene
. Cette classe va comporter ce qui concerne le joueur, la caméra et l'interaction du joueur. Elle contiendra :
preload
qui chargera les images du joueur.Level1
(#handleInteract
et #setBounds(levelBound)
).initScene(xPlayer, yPlayer, levelBound)
qui créera le joueur à la position (xPlayer, yPlayer) et initialisera la caméra pour suivre le joueur. Elle invoquera aussi les méthodes #handleInput
et #setBounds(levelBound)
.De plus, la méthode #handleInteract
impose que vous ayez accès à l'ascenseur de la scène. Cependant, pour plus de généricité, vous ajouterez une propriété elevators
à la classe Level
qui contiendra un tableau vide par défaut. C'est cette propriété qui contiendra les ascenseurs de la scène, que vous testerez dans la méthode #handleInteract
.
Vous ferez ensuite hériter la classe Level1
de la classe Level
. Vous penserez à invoquer la méthode preload
du parent dans sa méthode preload
et la méthode initScene
dans sa méthode create
. Vous penserez à ajouter l'ascenseur au tableau d'ascenseur de Level
.
Vous devriez avoir de nouveau un projet fonctionnel, à l'exception près, qu'en fonction de la position de l'invocation de la méthode initScene
, le joueur peut être créé derrière l'arrière-plan.
Pour résoudre ce problème, vous allez ajouter un ensemble de calques à votre classe Level
:
Vous ajouterez le joueur au calque « player ».
Dans la classe Level1
, vous ajouterez les différents éléments du jeu dans leur calque. Background
ira dans le calque « bg » et tout le reste dans le calque « back ».
Pour les groupes, vous ne pouvez pas directement les ajouter au calque, vous devez ajouter le tableau de ces éléments à l'aide de la méthode d'instance getChildren
.
Pour l'ascenseur, vous ajouterez dans le calque « back directement l'image de fond de l'ascenseur (back
).
Level
.Level1
pour hériter de Level
.Level
.Maintenant que vous votre scène est organisée en calque, dans le constructeur de la classe Elevator
vous allez pouvoir ajouter un sprite, affiché devant le joueur, qui pourra être utilisé pour afficher les portes s'ouvrant ou se fermant sur le joueur. Ce sprite sera accessible au travers d'une propriété d'instance front.
Dans la scène, vous pourrez accéder aux propriétés front et back de l'ascenseur pour ajouter les sprites aux calques correspondants.
Enfin, vous créerez une nouvelle animation « open » pour ce nouveau sprite, réalisant l'animation des vignettes 4 à 7 de la bibliothèque d'images.
Puis, dans la méthode moveIn
, aprés le déplacement du joueur au centre de l'ascenseur onComplete, vous pourrez jouer l'animation de fermeture des portes à l'aide de la méthode playReverse
.
Maintenant que l'animation fonctionne correctement, vous allez pouvoir provoquer le changement de scène. Dans ce but, le constructeur de la classe Elevator
recevra un nouveau paramètre contenant la clé de la scène vers laquelle emmène l'ascenseur. Ce paramètre sera sauvegarder dans une propriété d'instance to
, pour pouvoir être utilisée dans la méthode moveIn
à la fin des animations pour démarrer la nouvelle scène plutôt que de redémarrer la scène actuelle.
Pour que votre ascenseur soit fonctionnel, vous créerez une classe Level2
représentant votre deuxième niveau. Pour l'instant celui-ci se conformera au schèma suivant :
Aprés avoir ajouté la scène au jeu, vous ajouterez la destination de l'ascenseur du niveau 1 afin qu'il emmène au niveau 2.
Maintenant, votre joueur doit parvenir à passer du niveau 1 au niveau 2. Cependant, l'animation est un peu décevante. Afin d'y remédier, vous allez transmettre l'information de la provenance du joueur lors du démarrage de la scène. Dans la méthode moveIn
de la classe Elevator
, vous passerez en deuxième paramètre de la méthode start
un object JavaScript comportant une propriété from
avec comme valeur la clé de scène comportant l'ascenseur. Cet objet JavaScript sera transmis, lors du démarrage de scène, en paramètre de la méthode créate
de la scène démarrée. Vous pourrez remplir (set
) les données de la scène avec celui-ci.
Vous ajouterez ensuite une méthode moveOut(player)
à la classe Elevator
permettant de faire sortir le joueur de l'ascenseur.
Vous commencerez par désactiver le clavier et invoquer la méthode stop
du joueur, placer le joueur au centre de l'ascenseur. Vous afficherez, à l'aide de la méthode setTexture
, le sprite arrière comme ouvert (vignette 3) et le sprite avant comme fermé (vignette 4).
Vous allez provoquer l'ouverture de l'ascenseur à l'aide de l'animation « open » sur le sprite avant, mais avant, vous allez enregistrer un gestionnaire d'événement unique réagissant à la fin de l'animation du sprite avant ("animationcomplete"
). Dans la fonction de rappel, vous réactiverez la gestion du clavier et vous provoquerez la fermeture du sprite arrière.
Pour finir, lors de la création des scènes, vous pourrez déclencher la sortie de l'ascenseur en fonction de la provenance de l'utilisateur que vous obtiendrez à l'aide de la méthode get
du gestionnaire de données de la scène.
moveOut(player)
à la classe Elevator
.Une fois les transitions entre les scènes opérationnelles, vous allez pouvoir créer la version définitive du deuxième niveau. Dans ce niveau, vous allez mettre en place un nouveau type de blocs, les échelles.
Mais avant de définir le deuxième niveau, en vous inspirant de la scène Title
, vous ajouterez une nouvelle scène à votre jeu indiquant que le jeu est fini, vous penserez à l'ajouter à votre instance de jeu.
Ensuite, vous ajouterez une nouvelle image à votre projet : « ladder.png ». Il s'agit de l'image d'un bloc d'échelle.
Comme précédemment, vous créerez une classe LadderGroup
pour ajouter des ensembles de blocs à votre scène. Cependant, les plus attentifs constateront que l'image étant de dimensions 40×64, le positionnement des images ne va pas être correct. Pour palier à ce problème, vous ajouterez deux paramètres (offsetX
et offsetY
) avec une valeur par défaut de 0 au constructeur de TileGroup
. Vous initialiserez des propriétés d'instance pour conserver ces valeurs et vous les utiliserez dans la méthode d'instance addTiles
pour pouvoir décaler la position de chaque image lors de la création par lot. Cette modification ne devrait pas avoir d'impact sur votre projet. Vous pourrez ensuite créer la classe LadderGroup
pour afficher des groupes d'échelles alignés sur les cases de dimensions 64×64.
Vous pouvez maintenant mettre à jour votre classe Level2
pour que le deuxième niveau corresponde au schèma suivant :
LadderGroup
pour gérer les groupes d'échelles.Pour pouvoir monter ou déscendre des échelles, vous ajouterez la gestion des touches haut et bas, si elles ne sont pas déjà disponible.
Dans la méthode d'instance #createAnims
de la classe Player
, vous ajouterez deux animations « back » et « climb » :
Vous ajouterez ensuite deux méthodes d'instance : startClimbing()
et stopClimbing()
qui permettront de placer ou sortir le joueur dans un mode « en grimpe » :
startClimbing()
affectera la valeur true
à la propriété d'instance isClimbing du joueur, désactivera la gravité pour le joueur et déclenchera l'animation « back ».stopClimbing()
affectera la valeur false
à la propriété d'instance isClimbing du joueur, activera la gravité pour le joueur et déclenchera l'animation « stand ».Vous continuerez en ajoutant les trois méthodes d'instance : climbingUp()
, climbingDown()
et climbingPause()
à la classe Player
, qui permettront de modifier la vitesse du joueur. climbingUp()
et climbingDown()
utiliseront un « tween » pour modifier l'ordonnée de la vitesse du joueur à -200 ou 200 en 50ms selon une interpolation cubique. climbingPause()
utilisera un « tween » similaire pour amener l'ordonnée de la vitesse à 0. Elles lanceront toutes les trois une animation appropriée.
Avant de gérer le clavier permettant de gérer l'interaction avec les échelles, vous allerz ajouter une methode d'instance privée playerCanClimb()
permettant d'identifier si le joueur est en position de monter ou descendre d'une échelle. Cette fonction retournera vraie si le joueur n'est pas au sol et s'il est superposé à une échelle.
Pour finir, vous ajouterez une méthode d'instance update
à la classe Level2
. Vous penserez à invoquer la méthode update
de la classe parente.
Dans cette méthode, vous allez pouvoir tester si le joueur est en train de grimper grâce à la propriété d'instance isClimbing
du joueur.
stopClimbing()
.startClimbing()
.Vous devriez maintenant pouvoir monter et descendre aux échelles, et parvenir à la fin du niveau.