Construisez un Metroidvania dans Godot ! | Thomas Yanuziello | Skillshare

Vitesse de lecture


1.0x


  • 0.5x
  • 0.75x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Construisez un Metroidvania dans Godot !

teacher avatar Thomas Yanuziello, Indie Game Developer

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Bande-annonce 0-0

      2:01

    • 2.

      Téléchargements en 0-1

      2:34

    • 3.

      Éditeur 0-2

      4:42

    • 4.

      0-3 scènes

      6:48

    • 5.

      Physique 0-4

      4:51

    • 6.

      0-5 scripts

      5:43

    • 7.

      Jeu 0-6

      5:44

    • 8.

      Corps de personnage 1-1

      5:15

    • 9.

      1-2 cartes en entrée

      8:47

    • 10.

      1-3 Mouvement

      7:15

    • 11.

      1-4 Sauter

      7:23

    • 12.

      1-5 Chute

      7:25

    • 13.

      1-6 Running

      4:40

    • 14.

      1-7 Coyote

      8:41

    • 15.

      Sprite 2-1

      7:36

    • 16.

      2-2 joueurs d'animation

      9:56

    • 17.

      2-3 Arbre d'animation

      10:02

    • 18.

      2-4 effets sonores

      8:58

    • 19.

      2-5 Sprite animé

      7:54

    • 20.

      2-6 Instantier

      11:27

    • 21.

      2-7

      6:13

    • 22.

      Carte en 3-1 en tuiles

      8:05

    • 23.

      3-2 Terrain

      8:15

    • 24.

      3-3 caméra

      6:46

    • 25.

      3-4 Regarder l'avenir

      9:24

    • 26.

      3-5 Regarder vers le haut

      10:41

    • 27.

      3-6 limites

      11:05

    • 28.

      Parallaxe 3-7

      10:06

    • 29.

      4-1 Synthèse

      6:58

    • 30.

      4-2 pièces

      8:29

    • 31.

      Parallaxe 4-3

      10:06

    • 32.

      4-4 Transition

      7:38

    • 33.

      4-5 Fenêtres de vue

      7:05

    • 34.

      4-6 Visibilité

      7:49

    • 35.

      Carte 4-7

      7:46

    • 36.

      5-1 HUD

      9:38

    • 37.

      Calibre 5-2

      10:27

    • 38.

      Icône 5-3

      8:00

    • 39.

      Compteur 5-4

      8:40

    • 40.

      Boîte à 5-5 dommages

      10:57

    • 41.

      5-6 Données

      6:10

    • 42.

      Fichier 5-7

      8:27

    • 43.

      Double saut 6-1

      10:37

    • 44.

      6-2 Diapositive murale

      10:16

    • 45.

      6-3 Sauts de mur

      10:28

    • 46.

      6-4 Poinçon

      10:45

    • 47.

      Temps de récupération 6-5

      11:34

    • 48.

      6-6 Hat

      13:32

    • 49.

      Projectile 6-7

      18:21

    • 50.

      Rythme 7-1

      12:03

    • 51.

      7-2 Murs invisibles

      6:41

    • 52.

      7-3 Détection de ranges

      9:24

    • 53.

      7-4 Voler

      11:48

    • 54.

      Crawl 7-5

      14:44

    • 55.

      7-6 La vue

      12:48

    • 56.

      7-7 Agression

      14:25

    • 57.

      Combo 8-1

      12:21

    • 58.

      Coup 8-2

      11:35

    • 59.

      8-3 jus

      12:51

    • 60.

      Médulle 8-4

      7:39

    • 61.

      8-5 Mort

      13:28

    • 62.

      8-6 Boss 1

      15:37

    • 63.

      8-7 Boss 2

      10:13

    • 64.

      8-8 Boss 3

      13:48

    • 65.

      Point de sauvegarde 9-1

      11:55

    • 66.

      9-2 Metroidvania

      10:45

    • 67.

      Raccourci 9-3

      13:19

    • 68.

      Carte 9-4

      11:19

    • 69.

      Musique 9-5

      8:14

    • 70.

      9-6 Boss final

      9:54

    • 71.

      9-7 Final

      5:42

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

6

apprenants

--

À propos de ce cours

Vous apprendrez à construire un jeu Metroidvania dans Godot en partant de zéro.  Donnez à vos joueurs des capacités à débloquer qu'ils pourront utiliser pour accéder et explorer progressivement une plus grande partie de l'univers de votre jeu, une carte qui montre leur emplacement et des points de sauvegarde pour suivre leur progression.

Dans ce cours, vous apprendrez à : 
Utiliser le moteur de jeu Godot pour créer des jeux
Écrire des scripts dans GDScript
Principes de conception de la programmation orientée objet
Décomposer un projet complexe en composants individuels

(Vous pouvez penser à réaliser un jeu metroidvania entier par vous-même) peut sembler une tâche intimidante, mais ce cours vous apprendra à le décomposer en petits éléments beaucoup plus faciles à gérer, tout en vous enseignant la structure de design qui assemble tous ces éléments.

Ce cours s'adresse aux apprenants de tous niveaux de compétence.
Si vous débutez, nous vous recommandons de suivre le cours exactement comme il est présenté.  Chaque ligne de code sera tapée à l'écran et chaque étape du processus sera démontrée.
Pour les apprenants intermédiaires, vous pourrez essayer d'utiliser d'autres ressources ou adapter certaines des mécaniques du jeu pour apporter votre propre touche à ce qui est fourni.
Les apprenants avancés devraient pouvoir utiliser leurs propres ressources pour concevoir et créer leur propre jeu Metroidvania en utilisant ce projet qui leur offre un modèle qui leur servira de structure générale et leur inspiration.

Toutes les ressources utilisées dans les vidéos sont fournies afin que vous puissiez suivre le cours, mais vous êtes libre d’utiliser d’autres ressources ou de faire les vôtres si vous préférez.

Rencontrez votre enseignant·e

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Enseignant·e

Compétences associées

Développement Plus en développement
Level: All Levels

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Bande-annonce 0-0: Bienvenue dans mon cours sur la création d' amétroivnia dans le moteur de jeu Gadot Je m'appelle Thomas Ionizlo et je serai votre instructeur. Je suis titulaire d'un baccalauréat en informatique et j'enseigne le développement de jeux vidéo sur plusieurs plateformes depuis plus de cinq ans. J'ai inclus un ensemble complet de ressources, notamment des sprites, des effets sonores et de la musique que vous pouvez utiliser pour suivre le cours ou que vous pouvez utiliser vos propres ressources si vous préférez Ce cours vous aidera à vous familiariser avec le moteur GDOgame C'est un flux de travail très efficace pour créer des jeux et son langage de script natif GD Vous apprendrez à créer et à modifier des scènes à l'aide des différents nœuds de Gado et modifier leur comportement à l' aide de scripts écrivant ces scripts, vous apprendrez à appliquer principes de programmation orientée objet pour que votre code reste concis, évolutif et réutilisable pour d'autres projets. Plus important encore, vous apprendrez à structurer un projet complexe de cette envergure en le décomposant en composants individuels. Nous allons commencer par créer et animer un personnage de plateforme en deux D. Créez ensuite un environnement que le personnage pourra explorer et déplacez la caméra du jeu. Ensuite, nous allons permettre au personnage de passer d' l' autre et de dessiner le monde sur une carte pour aider le joueur à explorer votre monde. Après avoir enregistré et chargé la progression du joueur, nous allons dessiner un affichage tête haute. Ajoutez ensuite nos capacités à débloquer, notamment un double saut, un saut mural, un tiret et le tir d'un et le tir Enfin, nous ajouterons des ennemis pour le combat, un combat contre un boss, et nous suivrons la progression du joueur dans le jeu. Que vous débutiez dans le développement de jeux, découvriez le moteur de jeu Gadot ou que vous découvriez simplement Metroid Venias, ce cours vous apprendra tout ce que vous devez savoir pour créer un jeu complet à partir de zéro Si vous avez besoin d'aide, notre serveur Discord regorge d' autres étudiants et développeurs de jeux en herbe qui peuvent répondre à toutes vos Cliquez sur le lien dans mon profil pour m'inscrire. Vous pouvez prévisualiser les deux premières sections du cours gratuitement, et j'ai également un autre cours qui couvre les bases de la programmation GD Script entièrement gratuitement Une fois que vous serez prêt, nous pourrons commencer à apprendre à construire une metrovnia en 2. Téléchargements en 0-1: Bonjour les amis. Pour suivre ce cours, vous aurez besoin du moteur Godot Ouvrez n'importe quel navigateur Web, rendez-vous sur godot.org et téléchargez la dernière version, qui, au moment de l'enregistrement de cette vidéo, est 4.5 0.1 L'utilisation du moteur est gratuite, mais vous pouvez éventuellement choisir de faire un don pour soutenir le développement si vous le souhaitez. Une fois le téléchargement terminé, vous devez extraire les fichiers du dossier compressé, puis les stocker en lieu sûr sur votre ordinateur Pour exécuter l'éditeur, il vous suffit d' exécuter le fichier le plus volumineux qui ne se termine pas dans la console. Il n'y a pas d'installateurs ou de lanceurs à craindre. La première fois que vous ouvrez Godot, votre liste de projets sera vide et il vous sera demandé si vous souhaitez explorer certains des exemples de projets disponibles Nous allons ignorer cela et créer notre premier projet, qui ouvrira une nouvelle fenêtre. Ici, nous pouvons décider où enregistrer le projet. L'emplacement par défaut est dans le dossier des documents, mais il est conseillé de créer un sous-dossier distinct pour contenir vos projets Godot Ensuite, nous pouvons donner un nom à notre projet. Ne t'en fais pas trop pour le moment. Vous pourrez toujours le modifier ultérieurement. Un nouveau sous-dossier portant le même nom sera également créé pour contenir tous les fichiers liés à ce projet Trois moteurs de rendu différents peuvent être sélectionnés, chacun étant optimisé à des fins différentes Je vous recommande de démarrer tous vos projets en utilisant le moteur de rendu de compatibilité pour commencer, car il est préférable pour les versions Web. Ne changez de moteur de rendu que plus tard si vous avez besoin d'un meilleur support pour des effets visuels de meilleure qualité contrôle de version avec Gi Hub est automatiquement pris en charge et je vous recommande vivement d'apprendre à l'utiliser. En créant ce projet, il sera ouvert automatiquement afin que nous puissions le modifier. Je vais cependant fermer l' éditeur et le rouvrir. Notre projet est désormais inclus dans la liste des projets, et nous pouvons l'ouvrir soit en double-cliquant dessus soit en le sélectionnant dans la liste et en cliquant sur le bouton Modifier. Nous avons maintenant accès au Godot et nous pouvons commencer à éditer notre premier projet Dans la vidéo suivante, nous allons explorer la disposition de la fenêtre de l'éditeur. Je vous verrai dans la prochaine vidéo. 3. Éditeur 0-2: Bonjour, mes amis. Avant de commencer à modifier notre projet, nous devons nous familiariser avec la mise en page de la fenêtre de l'éditeur Godot La majeure partie de la fenêtre est remplie d'une vue en trois D de la scène en cours. Ce projet sera en deux D, non en trois D. Nous pouvons passer de la vue et non en trois D. Nous pouvons passer de la vue en trois D à deux D à l'aide des boutons situés en haut de la fenêtre. En deux D, nous avons l'axe X dessiné en rouge, l'axe Y dessiné en vert et un rectangle bleu qui montre la fenêtre d'affichage, ou ce qui sera réellement dessiné à l'écran lors du lancement du jeu Notez que la fenêtre d'affichage se trouve en dessous de l'axe X avec Y égal à zéro représentant le haut de l'écran L'axe Y étant inversé, valeurs positives pour Y se déplaceront vers le bas de l'axe Y, et non vers le haut haut à gauche, nous avons un onglet pour la structure de la scène actuelle, qui est actuellement vide et nous demande de créer un nœud racine pour cette scène. Puisque notre jeu sera en deux D, créons une scène en deux D. L'onglet scène affiche désormais notre nœud racine de scènes, un nœud deux D. Nous allons savoir plus sur les scènes et les nœuds dans la vidéo suivante. Ce dock contient également l'onglet Importer, qui nous permettra de modifier les paramètres d'importation pour les fichiers importés que nous utiliserons dans notre projet, tels que les graphiques et le son. Ces fichiers seront stockés et organisés dans le système de fichiers du projet, que nous pouvons voir en bas à gauche. Actuellement, notre projet ne contient qu'un seul fichier, l'icône Gadot Dans l'onglet Système de fichiers, nous pouvons organiser nos fichiers de projet en créant des dossiers et en les parcourant à l'aide du filtre. En revenant à l'onglet scène, si une note est sélectionnée , ses propriétés seront présentées dans l' onglet Inspecteur sur la droite. Nous pouvons développer les catégories de ces propriétés et modifier leurs valeurs ici. Ce dock contient également l'onglet nœud, qui fournit une liste des signaux que ce nœud peut émettre, ainsi que les groupes dont il fait partie. L'onglet historique contient une liste de toutes les modifications que nous avons apportées dans la scène actuelle ou pour l'ensemble du projet. Vous pouvez voir toutes les modifications que nous avons apportées, et j'ai également édité l'éditeur Fontie Le dock inférieur est actuellement réduit, mais nous pouvons cliquer sur le bouton de sortie pour le développer. La sortie nous montrera également les modifications que nous apportons au projet et affichera également le texte de sortie de notre jeu, ce qui est très utile pour le débogage Nous pouvons afficher des messages manuellement ici, mais l'éditeur affichera également des avertissements et des erreurs ici. Le débogueur dispose d'une variété d'outils utiles pour nous aider à déterminer ce qui ralentit ou bloque Il existe également des onglets spécifiques pour l'audio, l'animation, les shaders et d'autres onglets seront ajoutés ici selon les besoins Nous pouvons réduire ce dock en cliquant sur l'onglet actuellement sélectionné. En cliquant sur les trois points, ces quais peuvent être réorganisés en fonction de vos besoins, mais vous pensez qu'ils fonctionneront le mieux en fonction de votre flux de travail votre flux de travail Les onglets individuels peuvent également être déplacés entre les documents. Lorsque vous trouvez une mise en page qui vous convient, vous pouvez l'enregistrer dans le menu de l'éditeur. Vous pouvez également modifier divers paramètres de l' éditeur afin de le personnaliser en fonction de vos besoins. Lorsque nous avons finalement un jeu à exécuter, nous pouvons le faire à partir des boutons situés dans le coin supérieur droit. Vous pouvez soit jouer au jeu depuis le début, soit exécuter uniquement la scène en cours, interrompant ou en arrêtant le jeu Dans la vidéo suivante, nous allons apprendre à créer une scène. Je vous verrai dans la prochaine vidéo. 4. 0-3 scènes: Bonjour, mes amis. Maintenant que nous connaissons la mise en page de l'éditeur, commençons à éditer notre première scène. Nous allons commencer par cliquer sur une scène à deux D, faisant du nœud racine de notre scène un nœud deux D. Un nœud deux D ne représente rien dans notre jeu. Il ne s'agit que d'une transformation bidimensionnelle. Une transformation est une combinaison d' une position, d'une rotation et d'une échelle. Godot inclut également une composante oblique dans deux transformations en D. Si nous voulons réellement dessiner quelque chose, nous devons ajouter un autre nœud à notre scène. En cliquant avec le bouton droit sur le nœud racine et en sélectionnant Ajouter un enfant ou en cliquant sur le bouton Plus, nous pouvons ajouter un nœud enfant à notre scène. Il existe de nombreux types de nœuds qui ont tous des objectifs différents. La façon la plus courante de dessiner quelque chose dans deux jeux en D est d' utiliser un sprite Nous allons donc ajouter un nœud Sprite two D à notre scène. Les types de nœuds héritent des autres types de nœuds. Ainsi, un nœud sprite à deux D est également un nœud deux D et un élément de canevas, ainsi qu'un nœud de base, et possède les mêmes propriétés héritées de ces types, ainsi que d'autres qui lui sont propres Le nœud Sprite two D est ajouté en tant qu'enfant du nœud racine, indiqué par l'indentation Les scènes sont organisées selon une hiérarchie, en commençant par un nœud racine singulier puis en un certain nombre de nœuds enfants Ces nœuds enfants peuvent également avoir leurs propres nœuds enfants formant l'arbre de scène. Nous pouvons réduire les branches de l'arbre ou l'arbre entier en cliquant sur la flèche située à côté d'elles, et encore une fois pour les agrandir. Le nœud sprite ne dessine toujours rien car on ne lui a pas dit quoi dessiner sélectionnant, nous pouvons voir ses propriétés dans l'inspecteur, où il possède effectivement des propriétés héritées du nœud, l'élément Canvas et du nœud D. Dans la section Sprite two D, il possède également une propriété de texture, qui est actuellement vide Nous pouvons charger un fichier de texture ou faire glisser l'icône GAD de l' onglet du système de fichiers vers le champ de texture pour le renseigner. Et maintenant, le nœud Sprite two D dessine la texture de l'icône GADO sous la forme d'un sprite dans notre Dupliquons ce nœud Sprite two D dans l'arborescence de la scène en cliquant avec le bouton droit de la souris et en sélectionnant Dupliquer ou en sélectionnant le nœud et en appuyant sur Ctrl ou Commande D. Le doublon possède les mêmes propriétés que le nœud d'origine et est renommé en ajoutant un nombre croissant à son frères et sœurs figurant dans l'arbre des scènes ne sont pas autorisés à porter le même nom. Nous pouvons déplacer l'un ou l'autre de nos sprites dans la vue de scène en le faisant simplement glisser Cela mettra automatiquement à jour leur propriété à deux positions D transformées dans l'inspecteur. Nous pouvons également faire pivoter le sprite, redimensionner et l'incliner si nous le voulons Ensuite, faisons glisser ce nœud Sprite Tu Di sur l'autre, en le désignant comme nœud enfant de l'autre nœud Sprite Tu Di, indiqué par un autre niveau Maintenant, si nous sélectionnons le nœud Sprite tu Di parent et modifions ses propriétés de transformation, ces modifications sont héritées par l'enfant Les propres propriétés de transformation de l'enfant sont définies par rapport à celles du parent. Cette structure hiérarchique des scènes et l'héritage des propriétés nous permettent de créer des scènes complexes avec plusieurs composants différents. Nous pouvons ajouter n'importe quel nombre de nœuds différents à la scène, tels qu'un lecteur de flux audio à deux nœuds D et un nœud à deux nœuds en D pour les particules GPU. Désormais, cette scène en deux D peut dessiner quelque chose, émettre des sons et des particules, et tous ces composants hériteront de leur position de transformation du nœud racine Pour faciliter les choses, la transformation d'un nœud racine doit toujours avoir toutes les valeurs par défaut et uniquement les nœuds enfants dont les transformations sont modifiées. Nous pouvons renommer les nœuds, ce qui est particulièrement utile lorsque le nœud racine d'une scène décrit de quoi il s'agit Disons que c' est un robot. Ensuite, nous pouvons enregistrer cette scène en tant que fichier de scène dans notre projet, et elle portera automatiquement le même nom que le nœud racine. Créez ensuite une nouvelle scène en deux D et imaginez-la pour représenter une pièce contenant le robot. Notre scène de robot peut être ajoutée à la scène en tant que nœud unique. Nous pouvons même avoir plusieurs robots si nous le voulons. À partir du contexte de cette scène plus vaste, nous pouvons désormais modifier les propriétés de transformation d'un robot pour le déplacer, le faire pivoter, le redimensionner, l'incliner, etc. Renommons cette scène Room et sauvegardons-la. Si nous revenons à la scène du robot et modifions les nœuds enfants du robot, ces modifications seront appliquées à toutes les instances du robot dans les autres scènes. La scène de la pièce n'a pas besoin de se préoccuper de la façon dont le robot est construit, mais uniquement de son emplacement dans la pièce. La construction de scènes à partir de composants individuels nous permet de conserver les détails des objets individuels contenus et de les dissimuler hors de portée de plus grande envergure. Cela nous permet également de produire facilement plusieurs copies de la même chose, mais avec une seule source pour cet objet à modifier. création d'un jeu complet consiste à créer de nombreuses scènes plus petites représentant des objets, des personnages et des lieux de jeu individuels , puis à combiner plusieurs de ces scènes pour créer une scène plus grande pendant que le jeu est en cours d'exécution. Dans la vidéo suivante, nous verrons comment le moteur fournit des types de nœuds intégrés utiles pour simuler la physique Je vous verrai dans la prochaine vidéo. 5. Physique 0-4: Bonjour, mes amis. Maintenant que nous savons comment les scènes sont construites, nous allons voir comment les moteurs de jeu fournissent des fonctionnalités intégrées pour faciliter le développement de jeux. Nous pouvons nous débarrasser des robots et supprimer cette scène du projet. Commençons par ajouter un corps rigide à notre scène. Dans le contexte de la physique, un corps est un objet qui peut entrer en collision avec d'autres objets et qui possède une masse Un corps rigide représente un objet solide. Il sera affecté par des forces externes telles que la gravité, entrera en collision avec d'autres objets solides, mais ne se déformera ni ne Il conservera sa forme. Ce corps rigide a besoin d'une forme, qui est un autre nœud qui doit être ajouté en tant qu'enfant direct du corps rigide. Ce nœud de forme ne sait pas de quelle forme il s'agit tant que nous ne lui avons pas fourni une ressource de forme dans l'inspecteur. le menu déroulant, nous pouvons sélectionner différentes options. Je vais faire un rectangle. Maintenant, ce corps rigide a une forme, mais rien n'est réellement dessiné. Nous allons donc y ajouter un nœud Sprite two D et lui faire dessiner la texture de l'icône Godot La forme du sprite et celle de la collision ne correspondent pas. En sélectionnant le nœud de forme de collision, nous pouvons donc l'ajuster pour qu'il corresponde mieux au sprite en cliquant et en faisant glisser les points rouges ou modifiant ses propriétés dans l'inspecteur En maintenant la touche Alt enfoncée avec le nœud rigide sélectionné, positionnons-le quelque part en haut au milieu de l'écran. Appuyez ensuite sur le bouton Exécuter la scène en cours ou appuyez sur F six comme raccourci. Le moteur de jeu applique automatiquement des forces au corps rigide pour simuler physique du monde réel, comme la gravité. L'échelle de masse et de gravité peut être rapidement ajustée dans l'inspecteur pour modifier le comportement du corps rigide Nous pouvons même lui donner un matériau physique pour ajouter de la friction ou du rebond, ajuster son centre de masse et bien d'autres options Pour l'instant, faisons en sorte que cette simple boîte entre en collision avec un sol. Les objets très robustes que nous ne voulons pas déplacer sont généralement fabriqués à partir d'un corps statique plutôt que d'un corps rigide. Un corps statique peut toujours entrer en collision avec d'autres corps, mais il ne bougera pas à la suite de cette collision et ne sera pas affecté par des forces telles que la gravité Un corps statique a également besoin d'une forme de collision. Dans le menu déroulant, je vais sélectionner la limite du monde. Contrairement aux autres formes, les limites du monde s'étendent à l'infini. En deux D, cela est représenté par une ligne. La flèche dans les deux vues en D s'éloigne de la limite. Par défaut, il créera un étage. Déplacez la position du nœud statique vers le bas de la fenêtre d' affichage pour empêcher le corps rigide de dépasser cette limite du monde Dupliquons le corps rigide et voyons comment il se comporte lorsqu'il entre en collision avec un autre corps rigide Nous pouvons cliquer sur un nœud et changer son type. Transformons donc ce corps rigide en un corps statique. Positionnez-le et faites-le pivoter de manière à ce que le corps rigide entre en collision avec lui en plein vol. N'oubliez pas de renommer les nœuds après avoir modifié leur type afin de savoir de quel type ils sont Mais vous pouvez également le savoir grâce à l' icône à côté de leur nom. Si nous devions programmer manuellement tout cela nous-mêmes, il faudrait beaucoup de travail pour dessiner ces sprites, calculer comment ils sont affectés par les forces, déterminer quand ils entrent en collision les uns avec les autres et déterminer comment cela affecte leur comportement Outre la physique, les moteurs de jeu nous aident en automatisant de nombreuses fonctionnalités communes à la plupart des jeux afin d'accélérer et de simplifier considérablement le développement Dans la vidéo suivante, nous allons apprendre à associer des scripts à des nœuds pour modifier leur comportement. Je vous verrai dans la prochaine vidéo. 6. 0-5 scripts: Bonjour, mes amis. Bien que le moteur de jeu nous offre de nombreuses fonctionnalités intégrées , nous pouvons également ajouter les nôtres en attachant des scripts aux nœuds. En sélectionnant n'importe quel nœud dans l'arbre de la scène, j'utiliserai le corps statique qui est une boîte flottante. Nous pouvons soit cliquer avec le bouton droit de la souris et sélectionner le script joint, soit appuyer sur le bouton du script joint. Cela ouvre une nouvelle fenêtre. Le script héritera automatiquement du type de nœud auquel il est attaché, et nous pouvons démarrer notre script à partir d'un modèle si nous le voulons Nous allons également spécifier un nom pour le script, qui doit refléter son objectif. Je vais nommer mon script spin, ainsi que le dossier dans lequel il est enregistré. Cliquez sur le bouton Créer pour passer automatiquement de l' affichage au mode script, afin que nous puissions commencer à modifier le script. Le modèle commence par deux fonctions : prêt et traitement. Tout texte suivi du symbole Octothorp est un commentaire. Il n'est pas utilisé par le moteur et n'existe qu' notre avantage pour nous aider à mieux comprendre le script. Comme le décrivent ces commentaires, la fonction Ready est automatiquement appelée lorsque ce nœud entre dans l'arborescence des scènes pour la première fois, ce qui est un peu trompeur. Mais pour l'instant, cela signifiera quand le jeu débutera pour la première fois. Le processus, quant à lui, sera appelé à chaque image pendant le jeu, ce qui, avec les paramètres par défaut du projet sera appelé 60 fois par seconde. Une déclaration de fonction commence par le mot clé funk, suivi du nom de la fonction Ces noms de fonctions commencent par un trait de soulignement, c'est ainsi que Gudo marque les fonctions comme privées, ce qui marque les fonctions comme privées, signifie qu'elles ne sont destinées à être utilisées que dans le contexte de ce script Le nom de la fonction est suivi de parenthèses, qui contiendront les paramètres de la fonction, le cas échéant La fonction de traitement possède un paramètre, Delta, qui correspond au nombre de secondes écoulées depuis la trame précédente. Ce sera donc le plus souvent un soixantième, mais cela augmentera parfois si traitement d'une image prend plus de temps que prévu Les paramètres sont suivis d'un tiret supérieur à une flèche, puis du type de retour de la fonction, qui dans les deux cas est nul, ce qui signifie qu'ils ne renvoient aucune valeur déclaration des types de retour est facultative et vous pouvez les supprimer si vous le souhaitez. Le contenu d'une fonction est indenté sur un onglet, pas besoin d'accolades Ces deux fonctions ne contiennent que le mot clé pass, ce qui signifie essentiellement ne rien faire. Mais nous pouvons remplacer cette instruction par quelque chose de différent. Pour voir comment cela fonctionne, changeons le corps de la fonction Ready pour qu'elle fasse quelque chose. La fonction d'impression affichera tout ce que nous voulons sur le panneau de sortie une fois le jeu lancé. Nous pouvons appeler des fonctions en spécifiant leur nom suivi de parenthèses Ensuite, entre parenthèses, nous pouvons fournir des arguments correspondant aux paramètres déclarés des fonctions Entre guillemets, nous pouvons écrire ce que nous voulons, par exemple « prêt à tourner ». Tout ce que nous mettons entre guillemets est appelé chaîne, abréviation de chaîne de caractères. Dans la fonction de traitement, faisons la même chose, mais cette fois, imprimons la valeur de Delta. Faisons également ce que ce script était censé faire modifier la valeur de la rotation de ce nœud, en l'augmentant par Delta à l'aide de l'opérateur plus égal. L'opérateur plus égal prendra la valeur de Delta et l'ajoutera à la valeur de rotation. Ensuite, assignez également le résultat à la rotation. En parcourant la scène, nous pouvons voir que la boîte tourne. l'arrêt du jeu, nous pouvons voir dans le résultat que le message « prêt » a été imprimé en premier, une seule fois, suivi de nombreux chiffres, dont la plupart sont un soixantième Comment cela fonctionne-t-il ? Ready et process sont tous deux des fonctions du nœud, ce qui signifie que chaque nœud notre arbre de scènes possède déjà ces fonctions, mais ils ne font rien. Notre script remplace les définitions de ces fonctions pour un nœud particulier auquel ce script est attaché Dans notre script, nous pouvons voir quand une fonction remplace une définition de fonction lorsqu' elle est précédée d'une flèche bleue Lorsque nous lançons le jeu, le moteur reconstruit l' arbre des scènes de cette scène, commençant par la racine, en ajoutant un nœud à la fois de haut en bas La fonction prête pour chaque nœud sera appelée après son ajout à l'arborescence des scènes, mais également une fois que tous ses enfants auront été ajoutés et que leurs fonctions prêtes auront été appelées en premier. Cela signifie que les parents peuvent compter sur l' ajout de leurs enfants à l'arbre des scènes avant qu'ils ne soient considérés comme prêts. Une fois que l'arbre de scène complet est prêt, les cadres de processus démarrent. Le processus sera appelé sur chaque nœud l'arbre de scène de haut en bas dans un ordre séquentiel Contrairement à ce qu'ils sont prêts, les parents ne laisseront pas leurs enfants s' en occuper d'abord. Maintenant que nous avons une compréhension de base du fonctionnement de Godot, dans la prochaine vidéo, nous allons commencer à configurer le projet de création de notre jeu Je vous verrai dans la prochaine vidéo. 7. Jeu 0-6: Bonjour, mes amis. Avant de commencer notre projet de jeu , nous devons préparer certaines choses. Tout d'abord, nous pouvons soit tout supprimer soit démarrer un nouveau projet afin d'avoir une table rase. Je vais tout enlever sauf la collision au sol. Renommez ensuite cette scène et son nœud racine en jeu. La scène de jeu sera une scène centralisée où se déroulera tout le gameplay principal. Le nœud racine du jeu comportera deux branches secondaires principales, un nœud d'environnement mondial et un nœud de couche de toile. Ils font clairement la distinction entre ce qui existe dans le monde du jeu, comme le niveau dans lequel le joueur joue actuellement, tous les objets du personnage, etc., et ce qui existe en dehors de ce existe en dehors de ce monde uniquement pour le bénéfice du joueur, informations affichées sur un écran tête haute ou sur une interface utilisateur Le nœud mondial de l'environnement aura plusieurs enfants. Un ou plusieurs nœuds pour les niveaux actuels qui sont chargés. Pour l'instant, nous allons simplement les représenter sous la forme d'un corps statique tutti Un nœud tutti avec le corps du personnage est le plus souvent utilisé pour le personnage du joueur et un nœud tutti avec caméra qui suit généralement le Je vais rétablir la position de la collision avec le sol à l'origine de la scène. Avec un nœud de caméra dans la scène, le rectangle bleu ne représente plus la partie du monde dessinée à l'écran, mais le port de vision de la caméra est affiché en magenta, actuellement centré sur l'origine. Le sol sera donc au centre du champ de vision de cette caméra. La couche de canevas comportera des enfants pour des tâches telles que l'affichage des informations du joueur à l'écran, dans les menus, etc. Ils seront tous représentés par des nœuds de contrôle. Les nœuds Canvas et de contrôle utiliseront toujours le rectangle bleu comme fenêtre d'affichage pour organiser leurs positions à l'écran Cela fonctionne pendant que le joueur joue au jeu la caméra visualise le monde et dessine ce qu'elle voit, tous les enfants du World Environment Node. Une fois que la caméra a produit une image Toti rectangulaire du monde, la couche Canvas dessine ses enfants par-dessus, créant ainsi l' écran de jeu typique que nous avons l' habitude de voir Ces deux branches partagent également une autre distinction claire. Le monde devra être suspendu, mais pas la couche de toile Ainsi, la sélection du nœud de jeu dans l'inspecteur situé sous le nœud, l'extension du processus, fera passer son mode de processus à toujours. Le nœud de l'environnement mondial sera configuré pour suspendu et la couche Canvas restera l'héritage par défaut Il héritera du mode de processus de son parent, qui est le nœud de jeu, il le sera donc toujours Le mode de traitement par défaut étant l'héritage, tous les enfants de l' environnement mondial hériteront pausible, tandis que les enfants de la couche Canvas hériteront La première fois que nous appuierons sur le bouton Exécuter le projet dans un nouveau projet, nous serons invités à définir la scène principale. Nous pouvons sélectionner la scène actuelle ou en sélectionner une autre dans le projet. La scène de jeu étant actuellement ouverte, nous pouvons la définir comme scène principale pour le moment et la modifier ultérieurement lorsque nous aurons une scène de titre. Cela peut être modifié dans les paramètres du projet sous les paramètres d'exécution. Il est également conseillé de définir les paramètres d'affichage avant de commencer. Sélectionnez donc la fenêtre. Ici, nous pouvons définir la largeur et la hauteur de la fenêtre d'affichage mesurées en pixels. Je trouve que 12 80 x 720 est une bonne taille pour la plupart des jeux, et c'est compatible avec la plupart des plateformes. Dans Stretch, le fait de passer du mode d' étirement désactivé aux éléments Canvas permet à deux nœuds D de s' étirer ou de se rétrécir pour s'adapter à la fenêtre de jeu. Comme je vais utiliser le pixel art, je vais changer le mode d'échelle du mode fractionnaire au mode entier Ainsi, les pixels ne doubleront que de moitié ou de moitié, évitant ainsi les pixels de tailles mixtes. Dans le cadre du rendu des textures, je vais également changer le filtre de texture par défaut du linéaire au plus proche. Cela permettra de dessiner mes éléments de pixel art exactement tels qu'ils sont, évitant ainsi qu'ils ne soient flous. Après avoir fermé les paramètres du projet, vous devrez peut-être déclencher une mise à jour en zoomant ou en faisant un panoramique sur la fenêtre d'affichage pour forcer le rectangle bleu ou la caméra Nous sommes maintenant prêts à commencer à décomposer le projet en ses composants individuels et à les aborder un par un. Dans la section suivante, nous allons créer un personnage de plateforme Tutti de base que le joueur pourra contrôler Je vous verrai dans la prochaine vidéo. 8. Corps de personnage 1-1: Bonjour, mes amis. Dans cette section, nous allons créer un personnage de plateforme en deux D que le joueur pourra contrôler Si votre scène de jeu ne comporte pas déjà un corps de personnage, deux Dnode, vous devez en ajouter un dès maintenant Le corps en deux D du personnage n'est pas un corps au sens d'une personne, mais un corps physique, comme le corps rigide ou le corps statique. Contrairement aux corps rigides, le corps d'un personnage n'est pas automatiquement soumis à la gravité mais réagit aux collisions, contrairement à un corps statique. Le nœud du corps du personnage a donc également besoin d'une forme de collision en tant enfant de celui-ci avec une ressource de forme pour lui indiquer de quelle forme il s'agit. La plupart des jeux utilisent une capsule pour représenter un personnage, mais des rectangles et des cercles sont également utilisés Pour l'instant, je vais utiliser un rectangle aux dimensions de 128 x 128. Nous pouvons toujours modifier ou redimensionner en fonction de la forme de collision une fois que nous avons dessiné le personnage pour le baser ultérieurement En plus d'une forme de collision, nous aurons également besoin d'un nœud sprite pour dessiner le personnage Il est important de ne pas utiliser un nœud Animated Sprite car ce n'est pas son objectif Les nœuds Animated Sprite sont uniquement destinés à dessiner de simples sprites animés Dès que vous devrez synchroniser d' autres nœuds avec vos animations, telles que des sons, particules ou des fonctions, vous aurez besoin d' une flexibilité supérieure peut offrir le nœud Animated Sprite Pour l'instant, je vais simplement utiliser l'icône Godot comme texture du personnage, soit un carré de 128 x 128 pixels correspondant à la forme de collision Renommons le nœud Toti du corps du personnage avec le nom du Bien que nous n' ayons pas l'intention d' avoir plusieurs copies de ce personnage, il est tout de même judicieux de composer sa structure dans une scène séparée, isolée de la scène de jeu. Nous pouvons accomplir cela en cliquant avec le bouton droit sur le nœud, puis en sélectionnant Enregistrer la branche en tant que scène. Créons un nouveau sous-dossier pour les scènes, un autre pour les personnages, puis enregistrons-le sous le nom de ce personnage Dans la scène du jeu, ce personnage est désormais représenté sous la forme d'un seul nœud avec une icône en forme de clapet, ce qui nous indique qu'il s'agit Tous ses nœuds enfants sont cachés désormais contenus dans la scène du personnage. Nous pouvons ouvrir la scène du personnage en cliquant sur l'icône en forme de clapet. Dans la scène du personnage, il est recommandé de considérer l'origine du personnage se trouve au centre entre ses pieds, comme si l'axe X était le sol. Cela garantit que tous les personnages auront leur point d'origine en commun, quelle que soit leur taille. Déplaçons donc le Sprite et les nœuds de forme de collision vers le haut le long de l'axe Y. En plus de la forme de collision et des nœuds Sprite, notre personnage aura besoin d' un lecteur d'animation pour jouer aux animations Sprite Également un arbre d'animation pour contrôler quelle animation est jouée à un moment donné. Un lecteur de flux audio à deux nœuds D nous permettra également de jouer des effets sonores. Nous pouvons également avoir besoin d'un émetteur de particules GPU pour créer des effets de particules tels que les pas et les sauts Chacun de ces nœuds sera couvert dans sa propre vidéo pour les expliquer plus en détail. Pour le moment, il est important de comprendre comment une scène peut représenter n'importe du jeu avec sa propre scène comportant de nombreux nœuds enfants utilisés pour la construire. Le nœud racine de cette scène est généralement associé à un script. Selon la manière dont vous préférez organiser vos fichiers, vous pouvez conserver ce script dans le même dossier que la scène à laquelle il est joint ou dans un dossier distinct réservé aux scripts. Vous devez donner à vos scripts un nom aussi vague que possible en fonction de leur destination. Ce script ne sera pas spécifique au personnage de mon enfant, mais devrait être écrit de telle sorte qu'il puisse s'appliquer à n'importe quel personnage, du moins pour le moment Le but du script sera non seulement de contrôler le nœud du corps du personnage lui-même, mais également de mener les opérations de tous les nœuds enfants afin qu'ils fonctionnent en harmonie selon les besoins pour créer notre personnage. Ce script attaché au nœud racine de notre scène de personnage est également accessible depuis la scène de jeu et servira à deux autres fins. Il masquera le traitement des composants individuels de la scène du personnage tout en fournissant une interface claire et concise pour l' interaction avec les autres scripts et objets de la scène de jeu Cela sera exploré plus en détail dans le reste de cette section. Maintenant que la structure de base des personnages est prête, nous devons recevoir des informations du joueur pour les contrôler. Je vous verrai dans la prochaine vidéo. 9. 1-2 cartes en entrée: Bonjour, mes amis. Dans cette vidéo, nous allons recevoir les informations du joueur et les envoyer au personnage. Comme j'ai créé le script pour nœud Tu Di du corps de mon personnage à partir d'un modèle, il contient déjà du code qui recevra les entrées et déplacera le personnage vers la gauche ou la droite. Si nous lançons la scène de jeu, appuyez sur les flèches gauche et droite pour déplacer le personnage, mais cela ne fait pas très plaisir et n'est pas très bien implémenté. Le commentaire fourni nous indique même que nous devrions au moins remplacer les actions gauche et droite de l'interface utilisateur par nos propres actions de jeu personnalisées. Pour ce faire, nous allons ouvrir les paramètres du projet, puis passer à l'onglet Carte d'entrée. Dans le champ Ajouter une nouvelle action, nous allons taper le nom de notre action, commençant par déplacer vers la gauche. Il ne doit pas contenir d'espaces et est généralement écrit en minuscules, toutes les minuscules étant séparées par des traits de soulignement Appuyez sur la touche Entrée ou cliquez sur le bouton Ajouter pour ajouter l'action de saisie, puis créez-en une autre pour vous déplacer vers la droite. Et nous en aurons également besoin pour Jump plus tard. À droite de chacune de ces actions, cliquez sur le bouton plus pour ajouter un événement à cette action de saisie. Ce sera le bouton sur lequel vous appuierez pour le déclencher. Le champ d'écoute détecte automatiquement les événements d'entrée, ou vous pouvez effectuer une recherche parmi les événements d'entrée disponibles. Pour me déplacer vers la gauche, je vais utiliser la touche flèche gauche, déplacer vers la droite avec la touche flèche droite, et sauter sera la touche Z. Nous pouvons ajouter plusieurs événements différents à chaque action, ce qui signifie que nous pouvons facilement ajouter le support du contrôleur en ajoutant des événements supplémentaires pour le contrôleur. J'utiliserai le pavé directionnel gauche et droite pour déplacer le personnage, ainsi que le joystick gauche vers la gauche et la droite, et aussi le bouton inférieur pour sauter. Lorsque vous avez terminé, fermez les paramètres du projet. Dans cette vidéo, nous allons uniquement modifier cette ligne où nous récupérons les entrées et, plus important encore, les déplacer vers un script distinct Il est recommandé que tous vos scripts n'aient qu'un seul objectif. Ce script ne sera utilisé que pour contrôler un personnage, pas pour recevoir des informations du joueur. En ajoutant un nouveau nœud à l'arbre de scène, celui-ci peut simplement être un nœud normal puisqu'il ne fera rien d'autre que d'exécuter notre script. Appelons-le Player. Joignez-y ensuite un nouveau script. Il existe plusieurs manières de recevoir des informations. La plus courante consiste à remplacer la fonction de saisie. Les remplacements de fonction doivent correspondre exactement à la fonction remplacée Le nom doit donc avoir exactement la même orthographe, les mêmes types de paramètres et le même type de retour. La fonction d'entrée possède un paramètre, un événement d'entrée, que nous pouvons nommer comme bon nous semble. Mais je préfère utiliser leurs noms par défaut, et cela ne renvoie rien. La fonction de saisie sera appelée pendant n'importe quelle image lorsqu'un événement d' action d'entrée se produit, qu' il s'agisse d' appuyer sur un bouton, d' incliner un stick analogique ou de déplacer la souris Dans cette fonction de saisie, nous pouvons accéder à l'événement d'entrée par son nom et accéder à son contenu par un point. Nous voulons appeler une fonction de l'événement d'entrée appelée Is action pressed. Lorsque vous appelez une fonction, le nom de la fonction doit être suivi de parenthèses Entre parenthèses, nous fournissons des arguments à la fonction correspondant à ses paramètres Dans ce cas, une chaîne, le nom de l' action d'entrée que nous vérifions. Nous allons donc écrire le saut entre guillemets, en prenant soin de faire correspondre exactement les majuscules aux minuscules et orthographe de l'action de saisie que nous avons créée dans les paramètres du projet. Cette fonction renvoie un booléen, soit vrai si le bouton a été enfoncé, soit faux si ce n'est pas le cas En plaçant cette fonction après le mot clé if, suivi de deux points, nous pouvons créer un nouveau niveau d'indentation pour notre script Tout ce que nous mettons ici ne fonctionnera que si le résultat de l'instruction I est vrai, donc uniquement si le bouton a été enfoncé. Pour l'instant, nous allons simplement imprimer le mot jump. cours de jeu, si nous appuyons sur l'un des événements d'entrée que nous avons spécifiés comme action de saisie, nous verrons que le saut est imprimé dans le panneau de sortie. Nous n'avons pas besoin de la fonction Ready, alors supprimons-la. Pour des choses telles que le mouvement, en particulier lorsque vous utilisez des contrôleurs équipés de sticks analogiques, il peut être utile de vérifier cette entrée dans la fonction de processus. Tout comme le faisait le script du personnage, nous devrons utiliser le singleton d'entrée Cette classe de singleton possède une fonction appelée get axis. La fonction de l'axe G nécessite deux paramètres, une action négative et une action positive. La gauche est toujours considérée comme négative et la droite positive, correspondant à l'axe X dans notre monde à deux D. Nous allons donc écrire les noms des actions de saisie que nous avons créées dans les paramètres du projet entre guillemets, déplacer vers la gauche et se déplacer vers la droite. Cette fonction renvoie un nombre décimal compris entre moins un et un positif, représentant l'inclinaison du joystick gauche dans les deux sens, ou simplement un chiffre négatif ou positif si vous utilisez des touches ou Étant donné qu'une valeur de zéro, qui signifie qu'aucune entrée n'est donnée, est toujours une entrée valide, nous voudrons toujours envoyer cette information au joueur à chaque image. Il n'est donc pas nécessaire d'indiquer si ici. Imprimons simplement la valeur renvoyée ici pour que nous puissions la voir. En cours de jeu, le chiffre zéro est imprimé à plusieurs reprises. En appuyant sur les flèches gauche ou droite, sur les touches du pavé de direction de ma manette ou en inclinant le stick analogique gauche, la valeur passe de un à un positif Si vous souhaitez obtenir plus d'informations sur l'une de ces classes ou fonctions, vous pouvez accéder à leur documentation en maintenant la touche Ctrl ou Commande enfoncée et en cliquant dessus. En ouvrant le script de caractères précédent, nous avons une variable nommée direction déclarée dans la fonction de processus. Commentons cela et intégrons cette variable dans la portée globale de notre script en la déclarant plutôt en haut du script. Pour en revenir au script du joueur dans lequel nous avons reçu entrée de mouvement pour transmettre ces informations d' un script à un autre, nous aurons besoin d'une référence à l'autre script. Dans le script du joueur, nous allons créer une variable contenant une référence au corps d'un personnage à déchiffrer En ajoutant une balise d'exportation au début de la déclaration de variable, la variable sera accessible depuis l'inspecteur, et nous pourrons attribuer sa valeur à notre caractère. Ensuite, au lieu d'imprimer la valeur du point get axis en entrée, nous l'enverrons au personnage en affectant à la variable de direction du personnage Lorsque nous lançons le jeu, le nœud joueur vérifie à chaque image l'état de nos entrées de déplacement vers la gauche et de déplacement vers la droite. Attribuez-le ensuite à la variable de direction du personnage. La fonction de traitement des scripts de caractères vérifie la variable de direction chaque image et l'utilise pour déplacer le personnage vers la gauche et la droite. Notre joueur donne maintenant des informations pour déplacer notre personnage. Je vous verrai dans la prochaine vidéo. 10. 1-3 Mouvement: Bonjour, mes amis. Dans cette vidéo, nous allons améliorer le mouvement des personnages en appliquant la physique. Dans le script de caractères, nous pouvons voir que le modèle par défaut vérifie si la valeur de direction est nulle. Zéro est considéré comme faux et toute autre valeur est vraie. Ainsi, si une valeur de direction différente de zéro est donnée, la vélocité X du personnage est réglée sur la direction multipliée par la vitesse. Ou si la direction est nulle, cela déplace la valeur de la vélocité X du personnage vers zéro en fonction de la vitesse. Il en résulte que la vélocité du personnage est soit nulle, soit vitesse, sauf dans le cas de l' inclinaison du stick analogique Ce n'est pas très réaliste et ça ne fait pas du bien. Ces valeurs de vitesse et de vélocité de saut sont également définies comme des constantes qui, contrairement aux variables, ne sont jamais autorisées à changer. Cela pose problème, et nous devrions changer cela si nous voulons que les personnages se déplacent à des vitesses différentes dans notre jeu. Nous parlerons du saut plus tard. Une autre chose à noter est que ces valeurs sont mesurées en pixels, elles varient donc en fonction de la taille de votre personnage. Pour l'instant, remplaçons notre constante de vitesse par une variable de vitesse de déplacement de type float. Je vais régler le mien à 256 pixels par seconde. Il est conseillé de séparer variables et les fonctions entre ce qui est censé être public et ce qui est censé être privé en faisant précéder les noms privés d'un trait de soulignement Tout ce qui est privé est censé être accessible uniquement à partir de ce script lui-même, contrairement à la variable de direction, qui est accessible et modifiée depuis le script du lecteur, elle est donc publique. Dans le processus physique, nous remplacerons la constante de vitesse par notre variable de vitesse de déplacement. Et maintenant, tout fonctionne exactement comme avant, sauf que la vitesse est un peu plus lente. Si nous ajoutons une balise d'exportation au début de cette déclaration de variable, nous pourrons en modifier la valeur dans l'inspecteur. C'est un excellent moyen de tester et ajuster la valeur pour qu'elle soit parfaite Puisque nous pouvons exécuter notre jeu, voir s'il fait du bien, puis le modifier et le tester à nouveau. Un autre avantage est que si plusieurs caractères utilisent le même script, chacun peut avoir sa propre valeur pour cette variable. Mais les personnages ne passent généralement pas de l'immobilité au point de se déplacer instantanément à leur vitesse maximale Au lieu de cela, ils subissent une certaine accélération au fil du temps avant d'atteindre leur vitesse maximale. Cela peut être accompli en déclarant une autre variable nommée accélération, également flottante et qui sera mesurée en pixels par seconde au carré Si cela vous facilite la tâche, vous pouvez considérer que sa valeur est un multiple de votre vitesse. Si mon accélération est le double de ma vitesse, j'atteindrai ma vitesse maximale en une demi-seconde. Ou si c'est la moitié de ma vitesse, il me faudra 2 secondes pour atteindre la vitesse maximale. Pour appliquer l'accélération au processus physique, il suffit de déplacer la valeur de notre vitesse X actuelle vers la vitesse multipliée par la direction à un taux d'accélération. Mais cela se produira en une seule fois dans une seule image. Pour ajuster la vitesse au fil du temps, nous devons faire comme le modèle ici où il applique la gravité et multiplie par Delta. delta étant le nombre de secondes écoulées depuis l'image précédente, généralement un soixantième de seconde, le taux d'accélération sera appliqué au fil du temps plutôt qu'en une seule fois La fonction move towards prend le contenu du premier paramètre, le déplace vers la valeur du deuxième paramètre en de la valeur du troisième paramètre et renvoie le résultat. Cela ne modifie pas la valeur du premier paramètre, nous devons donc l'affecter pour remplacer la valeur précédente de notre vitesse X. La fonction de déplacement et de glissement est définie dans la classe Two D du corps du personnage et nous permet d' effectuer tous les calculs difficiles, tenant compte de la vélocité du personnage, forces externes telles que la gravité, collisions avec d'autres corps physiques, puis de décider où le personnage doit se trouver à chaque image. cours de jeu, nous appliquons une accélération progressive avant d' atteindre notre vitesse maximale, et nous pouvons également ajuster la valeur de notre accélération dans l'inspecteur pour obtenir l'impression que nous voulons. Nous pouvons supprimer ces commentaires. La même logique peut être appliquée à la décélération en ajoutant simplement une autre variable Cette valeur est généralement bien supérieure à l'accélération. Le code du processus physique utilise déjà move towards. Il suffit de remplacer la vitesse par temps de décélération Delta. Cependant, il se peut que nous souhaitions appliquer une décélération à un autre moment que lorsque le joueur ne donne aucune information, c' est-à-dire lorsqu'il veut faire demi-tour et repartir dans l'autre sens Nous pouvons étendre notre déclaration I pour examiner ce cas. Après avoir vérifié si la direction n'est pas nulle, si notre vitesse X est nulle, le personnage est immobile, alors nous voulons toujours accélérer. Mais aussi, si le sinus de direction est le même que le sinus de la vitesse X, alors le joueur essaie de continuer à se déplacer dans la même direction qu' se déplace déjà et nous voulons continuer à accélérer jusqu'à atteindre la vitesse maximale. La fonction sinus transforme n'importe quel nombre en moins un, zéro ou un positif, ce qui simplifie la comparaison entre ces deux valeurs positives ou négatives. Nous pouvons combiner les conditions avec ou. Donc, si l'une de ces valeurs est vraie, alors l'ensemble de l' énoncé est vrai. Si les deux réponses sont fausses, nous voulons faire demi-tour, c'est-à-dire appliquer la décélération au lieu de l'accélération, ce qui au lieu de l'accélération, se traduit par un revirement beaucoup plus rapide qu'en appliquant une accélération si la valeur de la décélération est appliquant une accélération si la valeur de la décélération testant cela, déplacer notre personnage vers la gauche et la droite devrait maintenant sembler beaucoup plus réaliste, et nous pouvons facilement ajuster les valeurs de notre vitesse, de notre accélération et de notre décélération dans l'inspecteur Je vous verrai dans la prochaine vidéo. 11. 1-4 Sauter: Bonjour, mes amis. Dans cette vidéo, nous allons améliorer la mise en œuvre du saut. Avant de commencer à sauter, je vais déplacer la caméra vers le haut le long de l'axe Y afin que le sol soit au bas de l'écran, et non au milieu. Le modèle de script de notre personnage possède déjà un bouton de saut utilisant l'interface utilisateur, sauf qu' il s'agit de la barre d'espace, qui définit la vélocité Y du personnage sur la vitesse de saut. Mais nous avons déjà ajouté notre propre bouton de saut dans une vidéo précédente. Contrairement à la gravité ou à l'accélération, qui sont multipliées par Delta et appliquées au personnage sur plusieurs images, cette vitesse de saut est appliquée au personnage en une seule fois et immédiatement. En cours de jeu, nous pouvons appuyer sur la barre d'espace pour sauter, mais les problèmes sont multiples. Le saut est toujours à la même hauteur, et le script de caractères vérifie les entrées. Supprimons d'abord cela du processus physique du personnage pour le placer dans une fonction publique. Nous l'appellerons « saut ». Ensuite, dans le script du joueur, lorsque vous appuyez sur le bouton de saut, au lieu d'imprimer le saut, nous pouvons demander au personnage de sauter à la place. Accès au contenu du personnage par un point suivi du nom de la fonction, et la fonction n'ayant aucun paramètre, y a donc rien entre parenthèses Mais maintenant, nous autorisons le personnage à sauter chaque fois que l' on appuie sur le bouton, même s'il n'est pas au sol. Nous devons d'abord vérifier si le personnage est au sol avant de le laisser sauter. Cette fonction au sol est définie dans la classe Two D du corps de caractère. Désormais, le personnage ne peut sauter que s'il est au sol, mais le saut est toujours à la même hauteur. Dans la plupart des jeux, le personnage saute plus haut en maintenant le bouton enfoncé que s'il appuyait simplement sur celui-ci. Parfois, nous pouvons mesurer la durée pendant laquelle le bouton de saut est maintenu avant de le relâcher, puis transmettre cette information par le biais de l'appel de la fonction de saut pour ajuster la force de saut. Mais surtout dans les jeux de plateforme en deux D, nous nous attendons généralement à ce que des sauts se produisent immédiatement lorsque nous appuyons sur le bouton, ce qui signifie que nous sommes impatients que le bouton soit maintenu enfoncé ou relâché Il est donc plus courant de supposer que le saut sera à la hauteur totale du saut, puis de l' écourter si le joueur relâche le bouton plus tôt. la même manière que nous avons réagi à appui d' un bouton dans le script du joueur, nous pouvons également réagir à sa libération. En utilisant le mot clé if, cela ne sera vérifié que si les conditions précédentes étaient fausses, ce qui évite de vérifier si le bouton a été enfoncé et relâché en même temps Si le bouton de saut est relâché, nous pouvons appeler une autre fonction pour annuler le saut en le raccourcissant. De retour dans le script du personnage, nous devons déclarer la fonction de saut annulée, ne nécessitant aucun paramètre et ne renvoyant aucune valeur. Un moyen simple de le faire serait de régler la vélocité Y du personnage à zéro, mais cela peut sembler peu naturel de s'arrêter complètement en vol. Je vais donc plutôt diviser la vitesse Y par deux. Mais nous voulons que cela se produise uniquement si la vélocité du personnage est actuellement inférieure à zéro, ce qui signifie qu'il monte, et uniquement si sa vélocité est inférieure à zéro parce qu'il a sauté. S'il y avait une autre raison pour laquelle le personnage montait mais qu'il ne sautait pas, nous ne voudrions pas le laisser annuler un saut et réduire sa vélocité. Nous pouvons contrôler cela en déclarant une nouvelle variable. Nous l'appellerons Is jump de type Boolean, qui sera naturellement défini par défaut sur false Si nous définissons cette variable sur true lorsque le personnage saute, nous pouvons vérifier si le personnage saute avant de lui permettre d'annuler le saut Dans le cas où ils n'annulent pas le saut, nous devons remettre automatiquement la variable is jump sur false. Donc, dans le processus physique, vérifier si le personnage saute et si sa vitesse y est supérieure ou égale à zéro, ce qui signifie que le personnage tombe ou du moins ne remonte pas, nous pouvons régler le saut à nouveau sur faux car il est trop tard pour que le personnage relâche le bouton pour annuler ce saut. Cela fonctionne très bien, mais maintenant nous devrions peut-être ajuster la hauteur à laquelle le personnage peut sauter. Le script modèle déclare la vitesse de saut comme constante. Tout comme nous l'avons fait pour la vitesse de déplacement, nous pouvons la transformer en variable. Mais connaître la vélocité requise pour atteindre une hauteur spécifique n'est pas très intuitif, et du point de vue du design, il est souvent préférable de pouvoir contrôler exactement la hauteur à laquelle un personnage peut sauter. Déclarons donc une autre variable appelée hauteur de saut sous forme d'entier. Cela sera mesuré en pixels. Je mettrai le mien à 256 , soit le double de la hauteur du personnage. À l'aide de la balise on ready, nous pouvons utiliser quelques calculs mathématiques pour calculer la force de saut requise pour atteindre cette hauteur exacte. La balise on ready exécutera cette ligne du script lorsque le nœud prêt avant la fonction ready. Je ne suis pas physicien, donc je ne pourrais pas expliquer pourquoi cette équation fonctionne, mais c'est le cas Il suffit de prendre la racine carrée de la gravité multipliée par la force de saut multipliée par deux. Ensuite, multipliez également tout cela par moins un puisque le négatif le long de l'axe y est supérieur. Pour ce faire, nous devons connaître la force de gravité appliquée au caractère sous forme de nombre décimal, à flot Donc, en déclarant une autre variable à l' aide de la balise on ready, celle-ci doit être au-dessus de la variable jump force, elle sera donc définie en premier. Nous pouvons obtenir la force de gravité à partir des paramètres du projet. Il suffit de spécifier le chemin vers le paramètre souhaité dans une chaîne. Enfin, lorsque le personnage saute, nous réglerons sa vélocité Y sur cette force de saut calculée Le joueur peut désormais contrôler la hauteur à laquelle il souhaite sauter. Et nous pouvons facilement modifier hauteur de saut maximale d' un personnage depuis l'inspecteur. Je vous verrai dans la prochaine vidéo. 12. 1-5 Chute: Bonjour, mes amis. Dans cette vidéo, nous allons ajuster la façon dont le personnage se sent et contrôle en plein vol. Notre personnage peut maintenant sauter plus haut, mais cela semble très flottant, et le personnage peut contrôler ses mouvements dans les airs aussi facilement qu'il le ferait au sol peut-être ce que vous voulez pour votre jeu, mais le joueur a souvent moins de contrôle sur le personnage lorsqu'il est dans les airs. Dans le script de caractères, nous pouvons supprimer ces anciennes constantes puisqu'elles ne sont plus utilisées nulle part. Comme notre script fait plusieurs choses, déplacer le personnage de gauche à droite et sauter, ce serait une bonne idée de le garder organisé. Je vais regrouper mes variables de vitesse de déplacement, d'accélération, de décélération et de direction et faire de même avec les variables liées au saut Nous pouvons même créer des catégories pour nos variables à l'aide la balise de catégorie d'exportation et spécifier le nom de la catégorie sous forme de chaîne. Créons une catégorie distincte pour les variables liées à la locomotion et une autre pour le saut Cela ajoute des en-têtes à l'inspecteur, sorte que nos variables exportées seront organisées dans ces catégories Notre catégorie de saut ne comporte qu'une seule variable, mais nous en ajouterons d'autres, en commençant par un multiplicateur de gravité. Ce sera un float et je lui donnerai une valeur par défaut de un. Multipliez ensuite notre gravité par le multiplicateur de gravité après l' avoir récupérée dans les paramètres du projet. Comme ce nombre est utilisé pour calculer la force de saut requise pour atteindre la hauteur de saut souhaitée, la hauteur de saut du personnage ne changera pas et la force sera automatiquement augmentée pour compenser. ouvrant les paramètres du projet , sous Physics two D, la gravité par défaut est définie sur 980 pixels par seconde au carré Nous pouvons modifier la force de gravité ici pour l'ensemble du projet et cela affectera tous nos corps physiques. Nous pouvons vouloir que certaines choses soient plus lourdes ou plus légères que d'autres, et un moyen simple de le faire est de multiplier leur propre gravité individuelle par un nombre différent. L'augmentation du multiplicateur de gravité de notre personnage accélérera son saut et le rendra plus lourd. abaissant le multiplicateur de gravité ils se sentiront plus légers et flottants Ensuite, nous pouvons réduire le contrôle le joueur a sur le personnage en utilisant davantage de multiplicateurs, communément appelés contrôle pneumatique et freins à air commande pneumatique est utilisée lorsque le joueur saisit le mouvement en vol et les freins à air lorsqu'il ne le fait pas en l'air Je vais régler les deux à 0,5, ce qui signifie que l' accélération et la décélération du personnage seront réduites de moitié Au cours du processus physique, nous pouvons mieux organiser tout ce qui se passe en le divisant en différentes fonctions, l'une n'étant appelée que lorsque le personnage est au sol et l'autre lorsqu'il ne l'est pas. Nous transmettrons la valeur de Delta aux deux fonctions. définissant une fonction physique du sol distincte, nous pouvons désormais nous concentrer uniquement sur l'application de la physique appropriée lorsque le personnage est au sol. Créez ensuite une autre fonction pour la physique de l'air et utilisez-la pour contrôler le personnage différemment que lorsqu'il est au sol. C'est ici que nous allons appliquer la force de gravité. Copiez ensuite également les commandes permettant au personnage de se déplacer et de ne pas bouger par rapport à la physique du sol. est moins important de faire demi-tour en vol puisqu'il n'y a pas de sol susceptible de créer de la friction Il ne serait donc pas logique de faire demi-tour plus rapidement Il suffit de multiplier l' accélération naturelle du personnage par le multiplicateur du contrôle de l'air et sa décélération par le multiplicateur des freins à air Une autre méthode consiste considérer la commande pneumatique et les freins à air valeurs alternatives qui remplacent l'accélération et décélération plutôt que de les utiliser comme Vous pouvez également envisager d' ajouter une vélocité terminale, en fonction de l'ampleur des chutes que fera le personnage sur de longues distances et de la nécessité pour le joueur d'avoir un meilleur contrôle dans de telles situations. Une vitesse terminale est la vitesse maximale qu'un objet pourra parcourir dans l'air, car la force de résistance de l'air finira par égaler la force de gravité et s'annulera mutuellement. Comme nous ne disposons pas encore d'un environnement approprié pour le tester, tout ce que nous pouvons faire est de régler la hauteur de saut du personnage à une hauteur très élevée, peut-être même de zoomer sur la caméra pour que nous puissions voir plus haut. Mais nous pouvons voir que le personnage se déplace très vite lorsqu'il parcourt de longues distances, et qu'il est très difficile pour le joueur de le contrôler avec précision. Exportons donc une autre variable pour notre vitesse terminale. Dans l'atmosphère de la Terre, un humain qui saute en parachute atteindra sa vitesse terminale à environ 54 mètres/seconde Si 100 pixels correspondent à 1 mètre, cela représente 5 400 pixels par seconde. Pour appliquer cette limite à la fonction de physique de l'air, nous pouvons simplement utiliser la fonction Min pour renvoyer soit la vitesse Y actuelle du personnage, soit la vitesse terminale, la valeur la plus faible étant retenue. Attribuez ensuite la valeur renvoyée à la vélocité Y du personnage. Nous pouvons désormais facilement limiter la vitesse à laquelle le personnage est autorisé à tomber dans l'inspecteur, ce qui donne au joueur plus de contrôle lorsqu'il suit de longues distances. Je vais fixer le mien à 4 096 pour le moment. Je vous verrai dans la prochaine vidéo. 13. 1-6 Running: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un bouton de course que le joueur peut maintenir enfoncé pour modifier sa vitesse de déplacement. Tout d'abord, je vais réinitialiser le zoom de l'appareil photo et le positionner là où il se trouvait auparavant. La vitesse de déplacement du personnage lorsqu'il joue avec le clavier est toujours la même, mais nous pouvons ajuster la vitesse de déplacement en n'inclinant que partiellement le stick analogique Dans certains jeux, cela suffit pour permettre au joueur de marcher ou de courir. Mais dans d'autres, il existe un bouton de course le joueur doit maintenir enfoncé pour se déplacer plus rapidement. En ouvrant les paramètres du projet, nous pouvons ajouter un bouton Exécuter à notre carte d'entrée. J'utiliserai la touche Shift ou le bouton droit de ma manette. Dans le script du joueur, nous utiliserons les mêmes fonctions que celles utilisées pour le saut pour vérifier si le bouton d'exécution est enfoncé ou relâché. Lorsque le bouton de course est enfoncé, nous pouvons demander au personnage de courir et, une fois relâché, lui demander de marcher. Pendant que nous sommes ici, nous pouvons gérer cet avertissement indiquant que la fonction de processus n'utilise pas réellement la valeur de Delta. Pour remplacer une fonction existante, les paramètres doivent correspondre exactement Nous ne pouvons donc pas supprimer complètement Delta Le moteur Godot préférerait plutôt que nous marquions ce paramètre comme inutilisé en faisant précéder son nom d'un trait de soulignement Nous pouvons également ouvrir le panneau des avertissements et cliquer sur Ignorer pour indiquer au moteur d'ignorer cet avertissement. Maintenant, le script du personnage aura besoin ces fonctions publiques : courir et marcher. Nous allons commencer par ajouter deux autres variables exportées dans la catégorie locomotion, une vitesse de marche et une vitesse de course Ensuite, la valeur de la vitesse de déplacement peut être modifiée, passant de « export à « prêt », et sa valeur peut être affectée à la vitesse de marche par défaut. donnant une déclaration aux fonctions de marche et de course , en n'acceptant aucun paramètre et en ne renvoyant aucune valeur , il suffit de définir la valeur de la vitesse de déplacement en vitesse de course ou de vitesse de marche. Ensuite, le processus physique s'occupera du reste en utilisant la valeur actuelle de la vitesse de déplacement. C'est tout ce qu'il faut pour modifier vitesse de déplacement de notre personnage tout en maintenant un bouton enfoncé. Nous pourrions facilement inverser cette tendance pour que le personnage court par défaut, mais en maintenant enfoncé un bouton pour marcher il suffit de changer la valeur par défaut de la vitesse de déplacement en vitesse de course et demandant au script du joueur d' appeler les fonctions opposées. Comme cette leçon était si courte, je vais également préparer la prochaine vidéo en ajoutant un bloc permettant au personnage de sauter à l'aide d'un nœud de corps statique. R Je vous verrai dans la prochaine vidéo. 14. 1-7 Coyote: Bonjour, mes amis. Dans cette vidéo, nous allons aider le joueur en ajoutant fonctionnalités d'accessibilité qui permettront notre personnage de se sentir plus indulgent à contrôler Je vais commencer par rétablir la hauteur de saut du personnage à un niveau raisonnable. Dans la plupart des jeux de plateforme en deux D, le jeu permet au joueur d'appuyer sur le bouton de saut pendant une courte période une fois son personnage est descendu d'un rebord et aussi lorsqu'il tombe et est sur le point d'atterrir. Dans les deux cas, la fonction is on floor renverra la valeur false, mais le joueur se sentira mieux dans le jeu s'il est toujours autorisé à effectuer un saut. Pour ajouter ces fonctionnalités, commençons par changer le type de retour de la fonction de saut de zéro à un booléen Nous retournerons donc vrai si le saut a réussi ou faux s'il ne l'a pas été. De cette façon, le script du joueur peut réagir si le bouton de saut est enfoncé trop tôt et réessayer le saut une fois que le personnage a atterri sur le sol passant au script player, au lieu de simplement appeler la fonction character point jump, nous pouvons réagir à sa valeur renvoyée en la plaçant dans une instruction if. Si jump renvoie true, nous n'avons rien à faire, mais s'il renvoie false, nous pouvons supposer que le joueur veut sauter dès que cela devient possible si cela se produit relativement rapidement. Donc, si ce n'est pas le cas, si le saut est retourné faux, nous allons mettre en mémoire tampon cette entrée de saut pendant une courte période. Le moyen le plus simple de suivre le temps est d'utiliser un nœud de temporisation. Nous pouvons l'ajouter en tant qu' enfant du nœud joueur, ou comme le nœud joueur n'a pas de type spécifique pour lequel nous l'utilisons, nous pouvons changer son type pour qu'il soit le chronomètre lui-même. En examinant ses propriétés dans l'inspecteur, nous pouvons définir la durée du chronomètre, qui sera la période pendant laquelle l'entrée sera mise en mémoire tampon, et définir sa propriété one shot sur true Cela signifie qu'une fois lancé, le compte à rebours ne décompte que jusqu'à 01 fois. Le comportement par défaut serait de compter jusqu'à zéro à plusieurs reprises. Déclarez ensuite une nouvelle variable. Nous l'appellerons entrée buffered de type callable. Callable est une classe qui contient un appel de fonction complet avec des arguments Donc, si notre saut échoue, nous voulons définir notre entrée mise en mémoire tampon comme saut par point de caractère sans parenthèses, car nous n'appelons pas la fonction maintenant, mais nous la stockons dans une variable Et lancez également le chronomètre. Puisque le type de ce nœud a été remplacé par un temporisateur, nous devrons changer le type de nœud que ce script étend en haut du script pour pouvoir accéder aux fonctions de la classe timer. Ensuite, dans la fonction de traitement, si ce temporisateur est en cours d'exécution, s'il n'est pas arrêté, appelez l'entrée mise en mémoire tampon Si l' entrée mise en mémoire tampon renvoie true, cela signifie qu'elle a réussi et nous pouvons arrêter le temps. Si l'entrée mise en mémoire tampon a renvoyé faux, cela ne peut pas encore se produire dans cette image, et nous voudrons réessayer l'image suivante jusqu'à ce que le temps imparti soit écoulé ou qu'elle réussisse À des fins de test, utilisons également des instructions d' impression pour indiquer quand le saut est mis en mémoire tampon, lorsque l'entrée en mémoire tampon échoue et lorsqu'il cours de jeu, si nous appuyons tôt sur le bouton de saut, l'entrée de saut est mise en mémoire tampon Il échoue plusieurs fois puis réussit lorsque le personnage touche le sol. Si nous appuyons sur le bouton de saut le personnage est bien en l'air, l' alors que le personnage est bien en l'air, l'entrée est mise en mémoire tampon, mais elle échoue jusqu'à la fin du temps imparti et n'aboutit jamais Une fois que nous sommes satisfaits des performances de notre mise en mémoire tampon d'entrée, nous pouvons supprimer ou commenter ces instructions d'impression Ensuite, nous voulons autoriser le personnage à sauter s'il est récemment descendu d'un rebord, ce que l' on appelle communément le temps du coyote, en référence au coyote Wiley référence au Dans la scène du personnage, nous pouvons ajouter un nœud de temporisation et le renommer coyote Comme le temporisateur de la mémoire tampon d'entrée, il s'agira d'un chronomètre ponctuel, et nous pouvons ajuster la durée du chronomètre. La scène du personnage étant ouverte dans le script du personnage, nous pouvons obtenir une référence à n'importe quel nœud enfant en maintenant la touche Ctrl ou Commande enfoncée, puis en cliquant et en faisant glisser le nœud dans le script Cela crée automatiquement une variable portant le même nom et utilise la balise on ready pour définir sa valeur en utilisant la notation du chemin du nœud commençant par le signe $1. L'utilisation de cette notation de chemin de nœud en signe de dollar nécessite que ce nœud existe avec le chemin de nœud exact par rapport au nœud auquel ce script est attaché. Dans le cas contraire, cela provoquera une erreur. Cependant, ce temps de coyote est une fonctionnalité qui ne s'applique généralement qu' au personnage du joueur Il se peut que nous ne voulions pas avoir ce nœud dans chaque scène de personnage. Nous pouvons donc utiliser la fonction get node ou null en passant le même chemin de nœud comme argument de chaîne. Cette fonction renverra soit une référence au nœud suivant ce chemin de nœud, soit null s'il n'existe pas sans provoquer d'erreur. Dans la fonction de saut, nous vérifierons si un saut est possible soit si le personnage est au sol, soit si le personnage dispose d' un chronomètre pour coyote et que le chronomètre pour coyote n'est pas un chronomètre pour coyote et que le chronomètre pour coyote Dans les opérations logiques, et sera évalué avant ou sauf si vous incluez des crochets. En ce qui concerne l'instruction A, le côté gauche sera vérifié avant le côté droit. Ainsi, si le chronomètre du coyote n'existe pas, l'instruction A sera considérée comme fausse Ainsi, le bon côté pour savoir si le chronomètre du coyote fonctionne ou non ne sera pas vérifié Il ne nous reste plus qu'à démarrer le chronomètre du coyote. Pour ce faire, nous devons savoir quand le personnage sort d'un rebord Je considérerai que cela est inclus dans la catégorie de saut, et nous déclarerons deux nouvelles variables. Is on floor pour stocker la valeur renvoyée par la fonction I on floor pour ce cadre. Cela nous permettra d' effectuer cette vérification une fois par image et de stocker les résultats afin de pouvoir l'utiliser plusieurs fois, ce qui nous d'avoir à appeler la fonction plusieurs fois par image et était au sol, ce qui contiendra la valeur de is on floor par rapport à l'image précédente. Au cours du processus physique, nous allons définir la valeur de was on floor à is on floor, puis is on floor à la valeur renvoyée par la fonction is on floor. Tout autre appel à la fonction is on floor peut utiliser notre variable à la place pour être plus efficace. Ensuite, si le personnage était au sol dans l' image précédente et non sur le sol de cette image et sa vitesse y est supérieure ou égale à zéro, qui signifie qu'il n'a pas sauté, la seule conclusion logique est que ce personnage est descendu d'un rebord ou le sol sur lequel il se trouvait a disparu, et c'est le moment exact quand le chronomètre du coyote doit démarrer. À des fins de test, ajoutons des instructions d'impression afin de savoir quand le chronomètre démarre et quand un saut de coyote Cela nécessitera une instruction if redondante, mais nous la supprimerons ultérieurement OK. Lancer le jeu pour le tester. Nous pouvons descendre d'un rebord et voir le chronomètre du coyote démarrer. Si nous appuyons sur le bouton de saut alors que le chronomètre du coyote est activé, le personnage est toujours autorisé à effectuer un Nous disposons désormais d'une plateforme Toti et d'un contrôleur de personnage solides plateforme Toti et d'un contrôleur de personnage Dans la section suivante, nous allons dessiner et animer le personnage Je vous verrai dans la section suivante. 15. Sprite 2-1: Bonjour, mes amis. Dans cette section, nous allons prendre notre simple icône Gadot et la peaufiner pour en faire un personnage entièrement animé Pour cela, nous allons avoir besoin de ressources, images et de fichiers audio. Ceux que j'utilise seront inclus si vous souhaitez les utiliser, mais je recommande aux étudiants de niveau intermédiaire d' utiliser les vôtres ou d'autres ressources gratuites. Avant de commencer à importer des actifs, il est conseillé de créer un dossier distinct pour les stocker. Nous pouvons également créer différents sous-dossiers pour différents types de ressources, tels que des feuilles de sprites et des effets sonores Cliquez sur le dossier dans lequel vous souhaitez placer vos actifs importés, puis cliquez et faites simplement glisser les actifs dans la fenêtre Gadot Le processus d'importation se fera automatiquement et ils seront triés dans le dossier ciblé. S'ils ne se trouvent pas dans le bon dossier, vous pouvez toujours les faire glisser dans l'onglet du système de fichiers pour les réorganiser également. Mais cela déclenchera une réimportation, il est donc préférable de les importer dans le bon dossier pour commencer, particulier pour les fichiers plus volumineux Ouvrez la scène de votre personnage si elle ne l'est pas déjà. Utiliser ces ressources pour dessiner le personnage peut être aussi simple que de remplacer l'icône Gadot par votre fichier image importé si vos ressources ne contiennent qu' un seul sprite par Les ressources que j'utilise sont organisées dans une feuille de sprites Il y a donc plusieurs sprites dans une seule texture, qui n'est pas ce que je veux dessiner À l'aide du menu déroulant, nous pouvons sélectionner d'autres types de textures, et celle qui permet d' utiliser une feuille de sprite s' appelle une texture d'atlas En cliquant sur la texture de l'atlas pour l'agrandir, nous pouvons la modifier ici même depuis l'inspecteur. Affectation de la feuille de sprites en tant qu'atlas. Nous pouvons ensuite modifier la région de l'atlas, qui sera dessinée par la texture de l'atlas. Lorsque vous sélectionnez une région de la feuille de sprites à utiliser, nous pouvons utiliser la fonction de découpage automatique pour sélectionner un seul sprite ou un capture de pixels pour cliquer et faire glisser une Comme ces sprites sont tous de taille et espacés de manière uniforme, je vais utiliser cette région de 32 x 36 pixels Lorsque vous modifiez le sprite, la largeur et la hauteur ne changeront pas Seules les positions X et Y seront incrémentées selon des valeurs uniformes Il est ainsi beaucoup plus facile d'animer le personnage. Avant de vous engager à utiliser un ensemble de ressources pour animer un personnage, il peut être intéressant de modifier votre feuille de sprites afin d' avoir un espacement uniforme, afin d' économiser du temps et des efforts Je vais déplacer le sprite vers le bas pour qu'il repose sur l'axe X. Sa position Y correspond désormais à la moitié de la hauteur de la région du sprite. Maintenant que nous avons une représentation visuelle précise de notre personnage, nous pouvons mieux adapter la forme de la collision. Nous pouvons réorganiser les nœuds enfants pour dessiner la forme de collision au-dessus du sprite du personnage afin de faciliter les choses J'utiliserai une forme de capsule et je la ferai assez grande pour inclure la tête, mais pas les oreilles et le corps, mais pas nécessairement les bras, la queue ou l'arme. Cela sera utilisé pour entrer en collision avec l'environnement, sorte que tout ce qui se trouve en dehors de la forme de collision chevauchera les murs, le plafond ou le sol Assurez-vous que votre forme de collision et votre sprite restent centrés sur l'axe Y et que vous vous asseyez confortablement sur l'axe X comme s'il s'agissait du sol Si la taille de votre personnage change de manière significative, vous souhaiterez probablement modifier les valeurs de ses variables pour des éléments tels que vitesse de déplacement et la hauteur de saut. Nous pouvons également taper des équations mathématiques dans ces champs, et le moteur déterminera le résultat pour nous. Mais je vais réorganiser la forme de collision se trouve à nouveau derrière le sprite Lorsque le caractère est centré sur l'axe Y, pour qu'il soit orienté vers la gauche ou vers la droite, pour qu'il soit orienté vers la gauche ou vers la droite, il suffit de modifier la valeur de la variable horizontale flip dans le nœud Sprite two D. Pour passer au script du personnage, nous allons saisir une référence au nœud Sprite two D et la stocker dans une variable en maintenant la touche Ctrl ou Commande enfoncée et en la faisant glisser dans le Ensuite, nous déclarerons une fonction publique nommée face left, n' acceptant aucun paramètre et ne renvoyant aucune valeur. Bien que l' intention actuelle soit de n' utiliser cette fonction qu'en privé dans ce script, vous pouvez probablement imaginer qu'il peut être utile de dire à un personnage de faire face à une direction dans un contexte public. Pour faire face à la gauche, il suffit de définir la valeur de la propriété sprites flip H sur true Nous pourrions également écrire une autre fonction nommée face right, mais la fonction ne ferait que remettre la valeur de cette variable à false. Il est parfois plus facile d'écrire nos fonctions pour être plus flexibles. Au lieu d'avoir à la fois une fonction face gauche et une fonction face droite, nous pouvons donner à la fonction face gauche un paramètre qui lui permet de faire les deux. Je vais juste le nommer left et lui donner la valeur par défaut true. L'attribution d'une valeur par défaut à un paramètre le rend facultatif. Ainsi, cette fonction nommée face left peut être appelée sans fournir d'arguments, et nous supposerons qu' ils veulent faire face à gauche. Nous pouvons ensuite régler la valeur de flip H sur la valeur de left. Pour que le caractère soit orienté vers la droite, il suffit d'appeler face gauche mais de fournir false comme argument plutôt que d'appeler une fonction complètement différente. Dans le processus physique, si la direction d'un personnage est négative, il doit faire face à la gauche. Et si c'est positif, alors ils veulent faire face et non à gauche, ce qui est juste. Si la direction est nulle, ils resteront orientés la même direction que dans l'image précédente. Pour mieux voir mon petit personnage, je vais zoomer la caméra d'un facteur quatre et la repositionner de manière à ce que le sol soit au bas de l'écran O. Lorsque nous appuyons sur Play, le personnage est dessiné et son sprite est retourné dans la bonne direction, mais il n'est toujours pas animé . J'aimerais que mon personnage soit plus rapide, donc je vais augmenter ses valeurs dans la scène des personnages. Je vous verrai dans la prochaine vidéo. 16. 2-2 joueurs d'animation: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter des animations à notre personnage. Si votre personnage ne possède pas nœud de lecteur d'animation, vous devez en ajouter un maintenant. Lorsque le nœud du lecteur d'animation est sélectionné, l'onglet d'animation devrait s'étendre automatiquement. S'il n'est pas ouvert, vous pouvez l' ouvrir en cliquant sur le bouton Animation. Le panneau d'animation est actuellement vide car il n'y a pas encore d'animations. En cliquant sur le bouton Animation, nous allons sélectionner Nouveau pour créer une nouvelle animation et la nommer inactive. Lorsqu'une animation est sélectionnée, il existe désormais une chronologie mesurée en secondes. Si vous préférez, vous pouvez changer les secondes en images par seconde, et la chronologie sera affichée en images à la place. Les images étant très rapprochées, je vais zoomer pour afficher les images plus éloignées les unes des autres. Nous pouvons également modifier la fréquence d'images. Je vais régler le mien à 12 images par seconde. Il est également utile d'appliquer la capture au curseur de la chronologie à l'aide de cette option Désormais, lorsque nous parcourons la chronologie de l'animation, elle est automatiquement redirigée vers l'image la plus proche À partir de ce panneau, nous pouvons ajouter des pistes à l'animation en cliquant sur le bouton plus. Le plus courant est le suivi des propriétés, qui nous permet de modifier n'importe quelle propriété de n'importe quel nœud de l'arbre de scène au fil du temps. Le nœud que nous voulons animer est le nœud sprite Ti, particulier sa propriété de texture Cela ajoute une piste à la chronologie de l'animation, et sur cette piste, nous pouvons ajouter des images-clés pour modifier la propriété à une nouvelle valeur à ce moment-là En cliquant avec le bouton droit sur la piste, nous pouvons sélectionner Insérer la touche pour ajouter une image-clé à cette piste Par défaut, la valeur de cette image-clé sera sa valeur actuelle, qui correspond à la texture que nous lui avons définie dans la vidéo précédente C'est suffisant pour les fichiers sprite uniques, car nous pouvons simplement changer la texture ici Mais comme j'utilise une feuille de sprite, je ne veux pas vraiment changer la texture Je veux juste changer la région de la texture utilisée. Il y a plusieurs façons de procéder. La première consiste à cliquer sur la piste des propriétés et à modifier le nom de la propriété, en ajoutant deux points et le mot « région » après la texture. Cela indique à l'animation que je souhaite modifier la propriété de région de la texture, et non la texture elle-même. Je vais réinitialiser l'animation pour qu'elle soit vide pour le moment. Assurez-vous que le nœud du lecteur d'animation sélectionné dans l'arborescence des scènes, puis sélectionnez le nœud Sprite two D. élargissant la propriété de texture de l'atlas, nous pouvons voir ses propriétés dans un panneau imbriqué Passez la souris sur le nom de la propriété de la région pour afficher le nom de la propriété dans la fenêtre contextuelle Cela est utile pour vous assurer que vous avez la majuscule et l'orthographe exactes lorsque essayez d' y accéder par le biais du code ou nom de la piste d'animation, comme nous venons de le faire. Mais la deuxième méthode pour ajouter des pistes de propriétés à une animation, qui est beaucoup plus simple, consiste à utiliser le bouton situé à droite de la propriété. Ce bouton ne sera présent que si le nœud du lecteur d'animation a déjà été sélectionné dans l'arborescence des scènes. Une animation est actuellement ouverte, puis un autre nœud de l'arbre de scène est sélectionné. Cliquez sur ce bouton clé pour ajouter une image-clé à l'animation en cours à la position du curseur de la chronologie La première fois que nous ajoutons une image-clé pour une propriété qui n'a actuellement pas de piste dans l'animation, Godot nous demandera si nous voulons créer une piste pour De plus, si nous voulons ajouter cette piste à l'animation de réinitialisation, nous dirons oui aux deux. Cela ajoute la piste à l'animation et ajoute également la première image-clé en même temps En cliquant sur le nom de l'animation inactive pour agrandir le menu déroulant, l'animation de réinitialisation a également été créée C'est ainsi que GoDo stockera les valeurs par défaut des propriétés Cela permet d'éviter les problèmes liés à l'exécution d'animations dans l'éditeur et à la modification permanente des valeurs des propriétés par inadvertance Godot rétablira toutes les propriétés aux valeurs par défaut spécifiées dans cette animation de réinitialisation Pour faciliter les choses, essayez de toujours ajouter des pistes de propriétés aux animations lorsqu'elles sont dans leur état par défaut. Nous sommes maintenant prêts à démarrer le processus d'animation proprement dit. Vous devez disposer soit d'une piste de texture pour modifier les sprites individuels, soit d'une piste de région de texture pour modifier les sprites au sein d'une feuille de sprites Vos ressources peuvent également utiliser différentes feuilles de sprites pour différentes animations Si tel est le cas, vous aurez également besoin d'une trace pour texture de l'atlas et pour la région de texture. Il suffit de parcourir une image dans la chronologie, puis de modifier la valeur de la texture ou de la région de texture et de cliquer sur le bouton clé pour ajouter une autre image-clé et recommencer Comme je sais que tous mes sprites ont la même taille et sont régulièrement espacés, je peux le faire encore plus facilement en insérant simplement nouvelles images-clés plutôt qu'en modifiant manuellement la propriété X, en l' augmentant de 32 par image Si nous testons cette animation, le moteur supposera que nous voulons interpoler les valeurs de ces propriétés entre les images-clés Étant donné que la fréquence d'images de l'ensemble du jeu est de 60 images par seconde, cette animation est de 12 images par seconde. Le moteur crée quatre images supplémentaires entre chaque image-clé afin de créer une transition plus fluide Ce n'est évidemment pas ce que nous voulons avec une animation de sprite, nous devrons donc changer le mode de mise à jour de cette piste du mode continu au mode discret Désormais, la propriété ne change que lorsque l'animation atteint une image-clé et la valeur change immédiatement L'animation étant trop longue, nous devons définir le nombre d'images de l'animation pour qu'elle se termine après la dernière image-clé Cette animation devra également être en boucle Cliquez donc sur le bouton de boucle de l'animation pour que l'icône en boucle soit bleue Si vous cliquez à nouveau dessus, il sera réglé sur Ping Pong, qui est un autre type de boucle Pour les animations de personnages, nous préférons généralement une boucle vers l'avant Il est également conseillé de définir les pistes d' animation de réinitialisation sur discrètes au cas où vous décideriez de les utiliser pour réinitialiser un personnage par le biais d'un script. Cette animation inactive est maintenant terminée, et nous pouvons continuer à créer les autres animations dont nous avons besoin pour notre plateforme et notre personnage. En cliquant sur le bouton d'animation, nous pouvons ajouter une nouvelle animation et repartir de zéro, ou nous pouvons dupliquer cette animation inactive et l'utiliser comme modèle. Comme je sais que mes sprites sont régulièrement espacés, me suffit de modifier les propriétés Y de mes images-clés pour passer des images inactives aux images Nous pouvons copier et coller des clés pour faciliter les choses. Une ligne reliant deux clés signifie que les valeurs ne changent pas entre elles. Lors de la création de l'animation en cours, je vais simplement doubler la fréquence d'images. Nous pouvons cliquer et faire glisser les touches pour les déplacer le long de la chronologie. Je devrai également créer des animations de sauts et de chutes. En fonction des ressources que vous utilisez, vous devrez peut-être créer différentes animations. Par exemple, vous pourriez avoir besoin d'animations « jump start », «   jump idle », « fall idle » ou « landing landing ». Assurez-vous de savoir quelles animations doivent être mises en boucle et lesquelles ne le doivent pas. Maintenant, le personnage possède toutes les animations, mais elles sont bloquées dans l'animation inactive. Nous devrons donc indiquer au personnage à quel moment il doit passer à d'autres animations. Je vous verrai dans la prochaine vidéo. 17. 2-3 Arbre d'animation: Bonjour, mes amis. Dans cette vidéo, nous allons contrôler quelle animation est exécutée dans le lecteur d'animation à l' aide d'un arbre d'animation. Si la scène de votre personnage ne possède pas nœud d'arbre d'animation, vous devez en ajouter un maintenant. Le but de l'arbre d'animation est de contrôler le lecteur d'animation, décidant quelle animation doit être jouée à un moment donné. Ainsi, une fois le nœud de l'arbre d'animation sélectionné dans l'arbre de scène affiché dans l'inspecteur, nous allons définir sa propriété de lecteur d'animation sur notre nœud de lecteur d'animation. La propriété tree root est une ressource qui sera utilisée pour déterminer quelle animation sera jouée par le nœud du lecteur d'animation. En cliquant sur le menu déroulant, nous avons plusieurs options différentes pour cela, dont la plupart sont plus applicables lorsque vous utilisez trois animations en D ou en os, qui mélangent souvent plusieurs animations. Comme il s'agit d'un simple sprite en deux D, nous allons utiliser une machine à états En cliquant sur notre nouvelle machine à états, nous allons ouvrir le panneau de l'arbre d'animation en bas de la fenêtre de l'éditeur avec une machine à états ouverte pour modification. Notre machine d'état possède actuellement un nœud de départ et un nœud de fin. ne s'agit pas des mêmes nœuds que les nœuds de l'arbre des scènes, mais des nœuds situés dans le contexte d'un graphe de nœuds. Nous pouvons cliquer dans un espace vide pour ajouter d'autres nœuds. Ajoutons l' animation inactive sous forme de nœud. Nous pouvons cliquer et faire glisser ces nœuds pour les organiser comme nous le souhaitons. Leurs positions dans cet espace n'ont aucune importance. changeant notre mode d'édition, passant de sélection et du déplacement de nœuds à des nœuds connectés, nous pouvons cliquer et faire glisser le pointeur d'un nœud à l'autre, créant ainsi une flèche qui les relie dans une direction. Il s'agit d'une transition entre le nœud de départ et le nœud inactif. Ainsi, lorsque la machine à états démarre, elle passe immédiatement au nœud inactif, ce qui indique au lecteur d'animation de jouer l'animation inactive. En revenant en mode édition pour sélectionner et déplacer des nœuds, ajoutons également les animations Walk and Run. Et en revenant à connecter les nœuds une fois de plus, passez de l'état inactif à la marche et de la marche à la course. Lorsque cette machine d'état démarre, elle passe immédiatement du nœud de départ au nœud d'exécution. Nous voulons donc ajouter des conditions à ces transitions afin de limiter moment où cette transition est autorisée à se produire. En sélectionnant la transition entre le mode veille et marche, élargissez la section avancée. Sous l' expression avancée se trouve une zone de texte. Ici, nous pouvons spécifier n'importe quelle expression logique que nous voulons contrôler quand cette transition est autorisée, à condition que le résultat soit un booléen, vrai ou faux Dans ce cas, nous voulons jouer l'animation de marche si la vélocité X du personnage est autre que zéro. Cela permettra donc de marcher à gauche et à droite. Cette expression sera vérifiée sur le nœud que nous spécifierons dans les propriétés du nœud de l'arbre d'animation, le nœud de base de l' expression avancée. En définissant ce nœud comme étant le nœud racine de la scène, les deux nœuds D du corps du personnage, nous pouvons faire en sorte que la machine à états d'animation réagisse automatiquement à la vélocité du personnage pour modifier l'animation. Pour en revenir à la machine à états, en passant de la marche à la course, nous allons vérifier si la valeur absolue de la vélocité X du personnage est supérieure à sa vitesse de marche Vous souhaiterez peut-être spécifier un seuil différent, exemple en exigeant que la valeur absolue de la vitesse X soit égale à vitesse de course ou supérieure la moyenne de la vitesse de marche et de course, etc. Nous devons maintenant ajouter une transition entre le mode veille et le mode marche. Lorsque vous créez des boucles de transition entre deux nœuds ou plus dans une machine à états comme celle-ci, les conditions de toutes les transitions ne doivent pas toutes être vraies en même temps. Cela empêcherait la machine étatique de décider quel État doit être actuellement actif, car elle circulera simplement entre les États indéfiniment. Étant donné que la condition pour passer du ralenti à la marche est que la vitesse X soit autre que zéro, le passage de la marche au ralenti doit se faire si la vitesse X est égale à zéro Ces deux conditions ne peuvent pas être vraies en même temps, sorte que la machine étatique ne peut pas rester coincée entre ces deux états en boucle En appliquant la même logique à la transition de la course à la marche, les conditions de cette transition doivent être logiquement incompatibles avec la transition de la marche à la course Ainsi, si la valeur absolue de la vélocité X du personnage est inférieure ou égale à sa vitesse de marche, cela ne sera jamais vrai en même temps qu'une valeur supérieure à. Lorsque nous lançons le jeu, la machine à états part du nœud de départ et effectue des transitions entre différents états, chaque état représentant une ou plusieurs animations. Dans certains cas, la machine d'état peut passer au nœud final. Dans ce cas, il cessera de fonctionner. Lorsque nous animons notre personnage, nous ne voulons jamais que cette machine à états atteigne le nœud final, il n'y a donc aucune transition qui y mène Cela permet d'animer le personnage au ralenti, marcher et de courir à gauche ou à droite, mais nous devons également ajouter des animations pour sauter Si nous devions ajouter l'animation de saut ici, nous devrions ajouter des transitions entre tous nos états existants et l'animation de saut, car le personnage peut sauter depuis n'importe lequel de ces états. Cela va devenir compliqué et difficile à gérer, surtout si votre personnage possède plusieurs animations de saut différentes Ce que nous pouvons faire à la place, c'est créer une machine à états imbriquée. Nous allons commencer par enregistrer notre machine d'état actuelle en tant que ressource de projet. Appelle ça de la locomotion. Remplacez ensuite cette machine d'état par une nouvelle. Dans notre nouvelle machine à état vide, cliquez avec le bouton droit de la souris dans un espace vide et sélectionnez Charger. Trouvez la machine d' état de locomotion et ajoutez-la à la nouvelle machine d'état en tant que nœud unique, et renommez-la de manière à ce que vous sachiez qu'il s' agit de la machine d'état de locomotion. Ajoutez ensuite une transition entre le départ et la locomotion. L'ensemble de la machine d'état Locomotion existe désormais sous la forme d'un seul nœud que nous pouvons ouvrir en cliquant sur son bouton Modifier avec une icône en forme de crayon Nous avons toujours les animations d'inactivité qui marchent et exécutent la transition comme avant, mais elles sont maintenant imbriquées dans une machine à états plus grande Nous pouvons revenir à l' autre machine à états en cliquant sur les miettes de pain Dans cette machine à états, nous ajouterons toutes les animations liées au saut et les associerons aux transitions. Voici à quoi ressemble une boucle infinie dans une machine à états. Nous voulons que le personnage passe de n'importe quel état de locomotion à un saut si sa vélocité Y est inférieure à zéro, ce qui signifie qu'il se déplace vers le haut Si leur vitesse Y est supérieure ou égale à zéro, ils ont atteint le sommet de leur saut, et je passerai à l'animation automnale. Passez ensuite du repli à la locomotion si le personnage est au sol Nous pouvons appeler la fonction ou utiliser notre variable privée que nous avons créée plus tôt. Nous devrions peut-être éviter de sauter et passer directement à la chute si le personnage sort d'un rebord Ajoutons donc cela comme une autre transition condition que le personnage ne soit plus au sol. Cela crée un conflit dans notre machine étatique lorsque le personnage est en état de locomotion et saute Leur vitesse est inférieure à zéro et ils ne sont pas au sol. Quelle transition doit donc être utilisée par la machine étatique ? Dans de tels cas, nous pouvons donner la priorité à nos transitions par rapport aux autres en abaissant leur propriété prioritaire. Si le personnage saute, sa vélocité Y est inférieure à zéro et il n'est pas au sol Mais la transition vers le saut est prioritaire. C'est donc cette transition qui sera utilisée. Si le personnage sort d'un rebord, sa vélocité est supérieure à zéro et il n'est pas au sol, y a donc pas de conflit Notre personnage de plateforme en deux D est désormais animé, mais nous pouvons le rendre beaucoup plus agréable en le peaufinant Je vous verrai dans la prochaine vidéo. 18. 2-4 effets sonores: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter des effets sonores à notre personnage animé. Pour cela, nous devrons importer des fichiers audio dans notre projet, triés dans un dossier approprié. Je vais inclure quelques effets sonores que vous pouvez utiliser pour suivre cette leçon, mais je recommande aux étudiants de niveau intermédiaire utiliser leurs propres ressources ou des ressources gratuites. abord, je vais me débarrasser du nœud de corps statique qu' est ce rectangle blanc puisque je ne l'utilise plus. Commencez par ajouter un flux audio Player Two D à la scène de votre personnage si vous n'en avez pas déjà un. Le nœud en deux D du lecteur de flux audio diffère d'un nœud de lecteur de flux audio en ce sens que le volume de l'effet sonore varie en fonction de sa proximité avec l'écouteur L'écouteur par défaut est la caméra. Nous pouvons renseigner la propriété de diffusion de notre lecteur de flux audio avec un effet sonore et cliquer sur le bouton de lecture pour l'entendre Si nous examinons les animations de notre personnage, en particulier l'animation de saut, nous pouvons ajouter une piste de lecture audio à l'animation et sélectionner le lecteur de flux audio à décoder comme étant le lecteur de cette piste Nous pouvons ensuite créer des effets sonores à utiliser dans le cadre de cette animation, mais cela comporte de nombreuses limites Si l'effet sonore est plus long que l'animation, il sera écourté. Si l'animation est en boucle, elle sera répétée, et avec les effets sonores, le joueur entendra plusieurs fois tout en jouant au jeu comme celui-ci C'est une bonne idée d' y ajouter de la variété et rendre aléatoire pour que le joueur ne se lasse pas de l'entendre Supprimons donc cette piste de l'animation et essayons une autre méthode. Comme nous connaissons le moment exact où le personnage sort du script, il serait plus facile de jouer le son de cette façon Renommons le lecteur de flux audio en DnoDet jump et récupérons une référence pour la stocker dans une variable Lorsque le personnage saute, suffit de lui dire de jouer En évitant l'effet sonore dans l'animation, celle-ci sera jouée dans son intégralité et une seule fois. Nous pouvons également dupliquer ce lecteur de flux audio à deux nœuds en D pour ajouter d'autres effets sonores , comme un nœud pour un son d'atterrissage. Ensuite, dans le script, nous pouvons le jouer de la même manière que le son du saut, mais nous n'avons pas encore de fonction pratique lorsque le personnage atterrit sur le sol. Dans le processus physique, nous avons une instruction if vérifie si le personnage est sorti d'un rebord En inversant cette logique, nous pouvons vérifier si le personnage a décroché ce cadre, s'il n'était pas au dernier étage et s'il se trouve au sol dans ce cadre Nous appellerons ensuite une nouvelle fonction privée. Disons qu'on Landed. Pour l'instant, cette fonction doit uniquement émettre l'effet sonore d'atterrissage. Ces effets sonores se produiront lorsque le personnage sautera et atterrira, mais ils seront toujours les mêmes, ce qui deviendra ennuyeux pour le joueur après un certain temps Nous pouvons améliorer cela en randomisant légèrement l'échelle de hauteur du son à chaque fois qu'il est joué Attachons donc un script à notre lecteur de flux audio deux dende et nommons-le quelque chose comme Sound Effect Randomizer sans utiliser de modèle et enregistrons-le dans le dossier approprié Ce script aura besoin d'une fonction publique lui demandant de jouer un effet sonore aléatoire, n' acceptant aucun paramètre et ne renvoyant aucune valeur Le résultat final sera d' appeler la fonction de lecture définie dans le lecteur de flux audio pour déchiffrer la classe Mais avant de reproduire l'effet sonore, nous voulons modifier la valeur de la propriété pitch scale. En utilisant la fonction intégrée rand F range, nous pouvons générer un flottant aléatoire entre une valeur minimale et maximale que nous spécifions. L'une étant l'échelle de hauteur par défaut, je vais la répartir aléatoirement entre 0,5 et 1,5, ce qui devrait produire une large gamme de sons similaires Nous pouvons associer ce même script à l'autre lecteur de flux audio Dnode en cliquant et en le faisant glisser depuis l'onglet du système de fichiers sur le nœud de l'arborescence des scènes en revenir au script du personnage, au lieu d'appeler la fonction de jeu Audio stream Player to D classes, nous appellerons plutôt notre fonction play random. Cela peut être suffisant pour réduire la monotonie de nos sons de saut et d'atterrissage, mais des pas seront constamment entendus pendant que vous jouez au jeu Vous pouvez donc avoir plusieurs effets sonores différents pour quelque chose comme ça et demander au lecteur de flux audio d'en choisir un au hasard Dupliquons un nœud 2D d'un lecteur AudioStream pour en créer un autre pour les sons de pas, toujours avec le même script de randomisation toujours attaché Dans le script, nous allons exporter une variable contenant tous les différents effets sonores de pas sous forme de tableau de flux audio Cela peut être rapidement renseigné par groupe en sélectionnant tous les sons de pas dans le dossier des actifs et en les faisant glisser vers le tableau exporté dans l'inspecteur Ensuite, lors de l' exécution d'un effet sonore aléatoire, nous vérifierons si la taille de ce tableau n'est pas nulle Si le tableau n'est pas vide, cela signifie que nous devons définir la valeur de stream comme un élément aléatoire de ce tableau. Accès à un membre du tableau dont numéro d'index un entier aléatoire compris entre zéro et la taille du tableau moins un. Cela choisira simplement un son aléatoire parmi notre gamme de sons. Dans le cas de nos autres sons aléatoires, puisqu'ils ne spécifient aucune valeur pour le tableau, sa taille est nulle et il n'essaiera pas de randomiser l'effet sonore, ajustera simplement son échelle de hauteur Il ne nous reste plus qu'à faire déclencher l'effet sonore par les animations Walk and Run. passer de la vue script à la vue en deux D, sélectionnez d' abord le nœud Animation Tree, puis le nœud Animation Player pour prévisualiser temporairement les animations sans l'arbre d'animation n'interfère Lorsque les animations Walk ou Run sont ouvertes, nous pouvons ajouter une piste de méthode d'appel à l'animation et appeler une méthode sur le lecteur de flux audio Footsteps pour la déchiffrer insérant une clé dans l' animation de cette piste, nous appellerons la méthode play random Dans ce contexte, une méthode est synonyme de fonction. Nous pouvons parcourir l'animation pour trouver les images lorsque les pieds du personnage entrent réellement en contact avec le sol et régler les images clés pour qu'elles se trouvent exactement sur ces images Répétez ensuite ce processus avec l'autre animation. Nous avons maintenant un tas de pas aléatoires, d' effets sonores de sauts et d'atterrissages, mais nous avons peut-être aussi besoin de nuages de poussière Je vous verrai dans la prochaine vidéo. 19. 2-5 Sprite animé: Bonjour, mes amis. Dans cette vidéo, nous allons créer des particules de poussière pour notre personnage de plateforme Pour cela, nous devrons importer davantage de feuilles de sprites. À partir de la scène du personnage, nous allons ajouter un sprite animé au nœud et le nommer quelque chose comme Jump Dust Le sprite animé à dender est différent d'un sprite à nœud normal en ce sens qu'il ne possède pas une seule Il possède une ressource Sprite frames. En cliquant sur le menu déroulant, nous pouvons créer une nouvelle ressource de cadres Sprite pour ce nœud 2D Animated Sprite. Cliquez ensuite sur la ressource pour l'ouvrir. Cela ouvrira un nouvel onglet dans le panneau inférieur intitulé Sprite frames Dans cette fenêtre, nous pouvons créer une ou plusieurs animations Sprite frame que ce nœud pourra jouer Ces animations ne peuvent modifier que le Sprite lui-même. Ils ne peuvent pas être synchronisés avec le son, appels de fonction ou d'autres propriétés comme le ferait un nœud Animation Player Selon les ressources que vous utilisez, vous pouvez ajouter des sprites à partir fichiers individuels ou à partir d'une seule feuille Sprite J'utilise Sprite Sheets, je vais donc cliquer sur le bouton « cadres publicitaires » de Sprite Sheet Parcourez le système de fichiers pour trouver les actifs souhaités. Si vous utilisez une feuille de sprites, vous serez invité à sélectionner cadres de la feuille de sprites que vous souhaitez Contrairement à une texture d'atlas, ces cadres de sprites doivent être régulièrement espacés Sélectionnez le nombre de cadres dans chaque ligne et colonne de la feuille de sprite, et ils seront découpés pour vous Vous pouvez ensuite sélectionner chacun des cadres que vous souhaitez utiliser en cliquant dessus. Le numéro dans le coin de chaque image de sprite correspond à l'ordre dans lequel elle sera ajoutée à l'animation S'ils ne sont pas dans le bon ordre, vous pouvez désélectionner et resélectionner les cadres Sprite ou les importer hors ordre et les réorganiser Tout comme les animations des personnages sont plus longues d'une image que la dernière, il est conseillé d'avoir une image vide à la fin pour animations de sprites comme celle-ci les Ainsi, la dernière image restera dessinée à l'écran pendant toute la durée d'une image avant que l'animation ne soit considérée comme terminée. Nous pouvons définir la fréquence d'images de l'animation. J'utiliserai 12 images par seconde pour savoir si cette animation doit tourner en boucle ou non, ce que je vais désactiver. Il existe également une option permettant de jouer automatiquement cette animation. Chaque nœud Animated Sprite Toti ne peut avoir qu'une seule animation à lecture automatique, et le nœud jouera cette animation lorsqu'il sera ajouté à l'arborescence Lorsqu'un nuage de poussière est créé par le joueur qui saute, nous voulions jouer cette animation. Faisons donc en sorte que cette animation soit exécutée automatiquement. Nous pouvons prévisualiser à quoi ressemblera l'animation en cliquant sur le bouton de lecture. Pour mieux voir l'animation, nous pouvons masquer temporairement le sprite du personnage et la forme de collision en cliquant sur l'icône en forme temporairement le sprite du personnage et la forme de collision en cliquant sur d'œil située à côté d' eux dans l'arbre de la scène Tout comme le personnage, cette animation doit reposer proprement sur le sol de l'axe X. Ainsi, dans la section de décalage de l'inspecteur, nous pouvons définir son décalage Y à la moitié de sa taille verticale. Avec les ressources que j'utilise, c'est 16 pixels de plus. Cela permet de maintenir l'origine des nœuds à 00 tout en dessinant le décalage du Sprite Si la couleur des sprites n'est pas tout à fait correcte ou si vous souhaitez ajuster leur transparence, vous pouvez le faire depuis la section des éléments du canevas des propriétés des nœuds dans l'inspecteur La propriété modulate est une couleur dont la valeur par défaut est le blanc, avec les valeurs d'un rouge, un vert, d'un bleu et d'un Alpha Chaque pixel du sprite aura sa propre couleur multipliée par cette couleur modulée avant d'être dessiné Nous pouvons donc ajuster ses valeurs rouge, verte, bleue ou alpha. Je vais donner à mon nuage de poussière une demi-transparence en réglant son modulateur Alpha sur 0,5 Nous pouvons réorganiser les sprites en cliquant et en les faisant glisser à l'aide des flèches, supprimer des cadres, ajouter des cadres vides ou importer d'autres cadres si nécessaire Une fois que vous serez satisfait de l' apparence de l'animation, pensez à dévoiler le sprite du personnage et la forme de collusion Je vais activer le bouclage à des fins de démonstration. Lorsque nous lançons le jeu, la poussière suit le personnage puisqu' il en est un enfant. Mais ce que nous voulons généralement pour quelque chose comme ça, c'est le nuage de poussière apparaisse à un endroit précis et ne bouge pas Ce nuage de poussière devra être un frère ou une sœur du personnage, pas un enfant En cliquant avec le bouton droit sur le nœud Animated Sprite two D, nous pouvons l'enregistrer en tant que scène à part entière Mettez-le dans un nouveau dossier pour les nuages de poussière. Supprimez-le de la scène du personnage. Ensuite, ouvrez-le afin que nous puissions le modifier isolément. Désactivons la boucle de cette animation. Nous voulons toujours qu'il se lance automatiquement lorsque le nuage de poussière est créé, mais nous en parlerons dans la prochaine vidéo Pour l'instant, nous avons encore deux nuages de poussière à créer. Un pour le moment où le personnage atterrit et un autre pour quand il marche ou court. Nous pouvons donc dupliquer notre scène de saut existante pour faciliter les choses. Cela ne fera aucune différence, mais je tiens à m' assurer que le nom du nœud racine de mes scènes correspond au nom de fichier de la scène. Ensuite, remplacez simplement les sprites par les bons dans chaque cas R Assurez-vous que tous sont correctement décalés pour reposer proprement sur le sol de l'axe X. Nous avons maintenant trois nuages de poussière différents que nous voulons utiliser avec notre personnage. Il suffit de les instancier. Je vous verrai dans la prochaine vidéo. 20. 2-6 Instantier: Bonjour, mes amis. Dans cette vidéo, nous allons instancier les nuages de poussière en réaction aux mouvements de notre personnage animé À partir de la scène du jeu, nous voulons que nos nuages de poussière existent dans le monde en tant que frères et sœurs de notre personnage, et non en tant qu'enfants Attachons un nouveau script au nœud d'environnement mondial. Je vais le nommer world et le mettre dans le dossier des scripts. objectif principal de ce script pour le moment sera de créer de nouvelles scènes en tant qu'enfants Nous allons donc écrire une nouvelle fonction publique nommée spawn, qui accepte une scène compressée comme premier paramètre Je vais juste l'appeler quelque chose de vague comme SN et aussi une position où il devrait être généré, qui est un vecteur deux Ensuite, cette fonction renverra le nœud qu'elle crée au cas où nous voudrions l'utiliser. Nous pouvons transformer une scène compressée en nœud en appelant sa fonction Instanciate. Nous devrons stocker ce nœud dans une variable pour pouvoir l'utiliser. Je vais l'appeler instance. La création d'un nœud ne l' ajoute pas à l'arborescence des scènes. C'est ce que nous devons faire également. Mais pour ajouter un nœud à l'arbre de scène, le nœud aura besoin d'un parent. Ce nœud d'environnement mondial sera le parent Nous l'appellerons fonction add child, en lui donnant l'instance comme argument. Cela ajoutera le nœud à l'arbre de la scène, mais sa position sera celle de l' origine de la scène, les coordonnées 00. Nous voulons donc définir la position du nœud nouvellement instancié comme étant la position d'apparition Toutefois, cela suppose que le nœud nouvellement instancié possède une propriété de position, ce qui n'est pas vrai pour tous les Cela ne provoquerait pas encore d'erreur, mais cela pourrait se produire à l'avenir si nous utilisons la fonction spawn pour créer différents types de nœuds Il serait donc judicieux de vérifier si cette instance est un élément du canevas avant d'essayer d'accéder à sa propriété position. Nous pouvons rendre le paramètre de position d'apparition facultatif en lui donnant la valeur par défaut du vecteur deux points zéro Enfin, nous pouvons renvoyer le nœud d'instance. Nous devons maintenant appeler cette fonction en réaction à certaines actions du personnage. Le moyen le plus simple de le faire est d'utiliser des signaux. Dans le script du personnage, nous pouvons déclarer des signaux en haut du script pour chacune des trois fois où nous voulons faire apparaître un nuage de poussière lorsque le personnage a fait un pas, sauté ou atterri Les signaux sont classiquement nommés au passé, pour indiquer que l'événement en question s'est produit Tout comme les fonctions, les signaux peuvent avoir des paramètres. Pour faire apparaître les nuages de poussière, nous devons connaître la position du personnage et la direction dans laquelle il se trouve, afin d' indiquer si le sprite doit être retourné Dans la fonction de saut, nous pouvons émettre le signal sauté, la position actuelle du personnage et en indiquant si le sprite du personnage est retourné horizontalement ou non comme arguments correspondant aux paramètres du signal La même chose peut être faite lorsque le personnage atterrit. Pour les traces de pas, nous pouvons déclarer une nouvelle fonction privée. Nommons-le à l'étape et émettons le signal. Si vous le souhaitez, vous pouvez également indiquer au son des pas de jouer dans cette fonction au lieu de l'inclure dans les animations sous forme de piste séparée Mais pour ce faire, j'ai besoin d'une référence au lecteur audio footstep à indiquer en haut de mon script Sélection du nœud Animation Player et de l'animation de marche. Nous pouvons ajouter une piste de méthode d'appel à l'animation, en appelant une méthode sur le nœud racine de la scène. Insérez ensuite des images-clés pour activer la fonction « on step pendant les images lorsque les pieds du personnage entrent en contact avec le sol Si vous déclenchez les effets sonores via le script, nous n'avons plus besoin de le faire depuis l'animation et nous pouvons supprimer cette piste. Ensuite, je devrai également répéter ce processus pour mon animation d'exécution. En passant à la scène de jeu, nous pouvons connecter des signaux à des scripts pour y réagir automatiquement. En sélectionnant le personnage, passant de l'onglet inspecteur à l'onglet nœud, nous pouvons voir notre liste de signaux. En double-cliquant sur un signal ou en cliquant avec le bouton droit de la souris et en choisissant Connecter, une nouvelle fenêtre s'ouvre. Dans cette fenêtre, nous pouvons sélectionner le nœud auquel nous voulons connecter le signal. Dans ce cas, le nœud de l'environnement mondial. Entrez ensuite le nom d'une fonction à appeler en réaction au signal ou choisissez-en une dans une liste. Je vais saisir manuellement le nom d' une nouvelle fonction et la nommer spawn Jump dust Cliquez sur Connect pour fermer la fenêtre et afficher le script World Environment Node avec cette fonction ajoutée automatiquement. Cette fonction possède également une icône verte indiquant qu'elle est appelée par une connexion de signal, et le nœud de personnage dans l'arbre de scène possède une icône de signal pour nous montrer qu'elle émet un signal avec une connexion. Cette connexion de signal est également répertoriée dans l'onglet nœud. Nous pouvons exporter des variables pour contenir nos trois scènes de nuages de poussière différentes, qui sont de type scène compressée. Remplissez ensuite chacune de ces variables avec les scènes appropriées dans l'onglet Système de fichiers Pour l'instant, appelons simplement la fonction spawn en passant Jump dust comme argument et également la position actuelle du personnage Godot n'aime pas que nous nommions paramètres de nos fonctions de la même manière que propriétés déjà existantes d'un nœud Mais nous pouvons renommer ce paramètre en quelque chose de plus spécifique, comme la position du caractère Cela instanciera automatiquement un nuage de poussière chaque fois que le personnage saute automatiquement un nuage de poussière chaque fois que le personnage Le nœud Animated Sprite two D exécutera automatiquement l' animation Sprite que nous avons créée, mais nous ne voulons pas que ce nœud de nuage de poussière continue d' exister une fois l'animation terminée Une fois que le personnage a sauté plusieurs fois, l'arbre des scènes contient de nombreux nœuds 2D Animated Sprite qui ne font rien Il va donc falloir les nettoyer. La méthode pour supprimer des nœuds de l'arbre de scène consiste à appeler leur fonction gratuite. Mais nous ne voulons pas le faire avant la fin de leur animation, qui est un signal du nœud 2D Animated Sprite Comme nous savons que le type de nœud de nos scènes de nuages de poussière est un sprite animé en deux D, nous pouvons les stocker dans une variable privée de ce type et la nommer poussière Nous pouvons connecter les signaux via le code comme nous l'avons fait via l'inspecteur et connecter son signal terminé d'animation à sa fonction libre. N'oubliez pas que lorsque nous référençons une fonction plutôt que d' appeler une fonction, nous n'utilisons pas de parenthèses Nous pouvons également retourner le nuage de poussière horizontalement si le sprite du personnage a été inversé lorsque ce signal a été omis En répétant ce processus pour les deux autres signaux, nous pouvons changer le type de nuage de poussière généré. Une fois le jeu lancé, nous retournerons dans la fenêtre de l'éditeur et cliquerons sur le bouton de la télécommande dans l'onglet scène. Nous pouvons voir l'arborescence des scènes du jeu en cours d'exécution. Agrandir l'arbre pour que nous puissions voir les enfants du World Environment Node. Nous pouvons voir que les deux nœuds D du Sprite animé sont créés et détruits lorsque nous sautons, atterrissons et marchons L'arborescence des scènes distantes ne met pas à jour toutes les images, sorte que certains nuages de poussière peuvent être créés et détruits sans être affichés dans l'arborescence des scènes distantes. Je vous verrai dans la prochaine vidéo. 21. 2-7: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un effet sonore distinct pour la voix du personnage. Je vais devoir importer d' autres fichiers audio pour les efforts du personnage. Les effets sonores vocaux diffèrent autres effets sonores en ce sens que nous ne voulons jouer qu'un seul son à la fois, car nos boîtes vocales ne peuvent produire qu'un seul son à la fois. Nous n'aurons donc besoin que d' un seul nœud TD de lecteur de flux audio pour toutes les vocalisations d'un personnage Dans la scène du personnage, dupliquons n'importe quel nœud TD du lecteur de flux audio existant pour créer un nouveau pour la voix du personnage. Vous pouvez également placer ce nœud quelque part autour du cou ou de la tête du personnage plutôt qu'à ses pieds. Mais cela ne fera pas beaucoup de différence notable sur mon petit personnage. Le randomiseur d'effets sonores n'est plus applicable à ce nœud Nous pouvons donc supprimer le script en cliquant sur le bouton de script détaché Nous allons le remplacer par un nouveau script. Appelons ça une voix. Dans ce script, nous pouvons exporter un certain nombre d'effets sonores vocaux standard, communément appelés efforts ou efforts. Exportons une variable pour son de Jump effort sous forme de flux audio , que nous pouvons renseigner dans l'inspecteur Nous pouvons avoir un aperçu de ce à quoi cela ressemblera en cliquant sur la ressource. Ensuite, nous ajouterons une fonction qui émettra un son d'effort de saut. Cependant, cette fonction n'aura aucune action si le lecteur de flux audio vocal à indiquer est actuellement occupé à émettre d'autres sons que si vous ne jouez pas que nous réglerons le stream sur Jump effort et que nous le jouerons. Cela empêchera toute nouvelle demande d'émission d' un autre son d'effort d'interrompre la précédente Nous pouvons également utiliser les mêmes techniques que celles que nous avons utilisées pour nos effets sonores ici, exemple en randomisant l'échelle de hauteur ou en utilisant un ensemble de flux audio et en choisissant un au hasard à chaque fois Et contrairement aux effets sonores classiques, qui sont censés être joués à chaque fois, efforts ne sont pas toujours nécessaires. Nous pouvons donc également ajouter une chance aléatoire que l' effort ne fonctionne pas, même si c'est possible. En utilisant la fonction rand F, cela renverra un nombre aléatoire de 0 à 1 Nous pouvons vérifier si c'est moins d'un pourcentage de chance, disons 25 %, exprimé par 0,25 ajoutant à l'énoncé conditionnel aide d'un opérateur et, la voix de ce personnage ne doit pas être occupée à émettre un autre son et doit également avoir une chance aléatoire de 25 % avant d'être autorisé à jouer cet effort Pour le déclencher, il suffit de connecter le signal sauté du personnage à la fonction Jump effort des voix. Mais le signal sauté du personnage fournit deux arguments et la fonction voice play jump effort n' accepte aucun paramètre, ils ne sont donc pas considérés comme compatibles. Si nous cliquons uniquement sur les méthodes compatibles, toutes les fonctions seront affichées même si elles ne correspondent pas, et nous pouvons sélectionner la fonction play Jump effort Pour éviter que cela ne provoque une erreur, nous allons développer la section avancée en cliquant sur le bouton Avancé Ici, nous pouvons lier de nouveaux arguments ou dissocier les arguments existants Il suffit de dissocier les deux arguments existants du signal sauté du personnage, et le signal est désormais compatible avec l'appel de fonction En le testant, nous entendrons son de l'effort joué au hasard avec 25 % de chances, et il ne s' interrompra jamais de lui-même. B. Une autre chose que nous pouvons faire pour séparer les voix autres effets sonores est de leur attribuer un bus audio distinct dans le schéma du bus audio. Cliquez sur le bouton Audio en bas de l'éditeur pour ouvrir le schéma du bus audio, qui ne comporte actuellement qu'un seul bus, le bus principal. Mais si nous cliquons sur Ajouter un bus, nous pouvons ajouter d'autres bus à la disposition du bus audio, un pour les effets sonores et un pour les voix. C'est aussi une bonne idée d'en avoir un autre pour la musique. Cela nous permet de classer notre contenu audio en différentes catégories et contrôler facilement l' ensemble de la catégorie une seule fois tout au long du jeu. Nous pouvons régler le volume de tous les effets sonores, des voix et de la musique indépendamment, et le volume principal les affectera tous. Il existe également de nombreux effets audio différents qui peuvent être ajoutés à chaque bus si nous le souhaitons. Dans notre scène de personnage, nous avons plusieurs lecteurs de flux audio à deux nœuds D différents , et chacun doit être informé à quel bus audio il appartient, le bus par défaut étant Master Bus. Il est possible de demander à chacun des effets sonores de jouer sur le bus d'effets sonores, tandis que le lecteur vocal AudioStream à deux nœuds D peut être chargé de jouer sur le bus vocal Nous pouvons maintenant régler le volume de nos effets sonores indépendamment des voix. M. M. Nous avons maintenant un personnage de plateforme en deux D très raffiné Ensuite, nous allons commencer à créer des environnements dans lesquels nous pouvons nous déplacer. Je vous verrai dans la section suivante. 22. Carte en 3-1 en tuiles: Bonjour, mes amis. Dans cette section, nous allons créer un environnement dans lequel notre personnage pourra se déplacer et sauter. Pour ce faire, je dois importer les actifs de mon terrain, triés dans un nouveau dossier pour les actifs de sprites de terrain En double-cliquant sur l'actif, nous pouvons le prévisualiser dans l'inspecteur. Nous pouvons voir que cet actif est une feuille de sprites, tout comme le personnage À l'exception des images d'animation, cette feuille de sprites contient différents sprites permettant de dessiner le terrain en fonction des tuiles environnantes À partir de la scène de jeu, nous allons rendre le corps statique du niveau actuel pour qu'il dénote sa propre scène Je vais créer un nouveau dossier pour les scènes de chambre. Et en fonction de la taille de votre jeu, vous pouvez également trier les salles par régions. Je vais donc créer un autre dossier pour les pièces de la région forestière et enregistrer cette pièce comme une salle de départ. Ouvrez ensuite cette nouvelle scène de pièce. Je ne veux plus que le nœud en deux D à corps statique soit le nœud racine, car cette pièce contiendra plus qu'un étage. Je vais donc ajouter un nœud normal deux D à cette scène étant enfant. Ensuite, en cliquant avec le bouton droit sur ce nœud, nous pouvons sélectionner make scene root pour réorganiser l'arbre des scènes afin que ce nœud soit désormais le nœud racine Maintenant, le sol est un enfant du nœud racine, et nous pourrions ajouter d'autres corps statiques à ce nœud pour les murs, le plafond, les plateformes et les obstacles afin de construire notre pièce. Je vais renommer le nœud racine pour qu'il soit le même que le nom de la scène Lorsque vous utilisez des tuiles provenant d'une feuille de sprites de même taille et espacées, nous pouvons utiliser un autre nœud fourni par Gadot appelé couche de carte de tuiles, pour les dessiner L'ajout d'un nœud de couche de tuiles à la scène ouvre le panneau de cartes en tuiles en bas de l'éditeur, mais nous ne pouvons rien faire pour le moment. abord, nous devons examiner propriétés des nœuds de la couche de cartes de tuiles dans l'inspecteur. Le nœud de la couche de carte de tuiles ne peut rien dessiner tant qu' il ne dispose pas d'un jeu de tuiles. En cliquant sur le menu déroulant, nous allons créer un nouveau jeu de vignettes. Cliquez ensuite sur le jeu de vignettes pour développer ses propriétés. La première option est la forme des carreaux de ce jeu de carreaux. Les carreaux que j'utilise sont carrés, mais il existe également des options pour les carreaux isométriques, carrés à moitié décalés et hexagonaux. Elles sont généralement utilisées pour les perspectives du haut vers le bas, et ce jeu est un jeu à défilement latéral Je vais donc utiliser des tuiles de forme carrée Ensuite, nous devons définir la taille des carreaux. Ma feuille de sprites importée a la taille de la vignette dans son nom, 32 x 32 pixels. Nous allons ignorer le reste des paramètres pour le moment et faire passer le panneau inférieur de l'éditeur de Tilemap à un ensemble de vignettes Nous pouvons maintenant ajouter des tuiles au jeu de tuiles que nous venons de créer. Cliquez sur le bouton Plus en bas, puis naviguez dans le système de fichiers pour trouver vos ressources ou cliquez sur les ressources et faites-les glisser depuis l'onglet du système de fichiers vers la zone des sources de vignettes Cela nous demandera au moteur de diviser automatiquement la feuille de sprite en tuiles pour nous Si nous sélectionnons « Oui » et si nous définissons correctement la taille des carreaux, les carreaux de la feuille de sprites seront automatiquement découpés à cette taille pour nous et ajoutés au jeu de carreaux En cliquant sur le bouton de la gomme, nous pouvons cliquer sur les tuiles pour les supprimer du jeu de tuiles Cliquez et faites glisser pour effacer toutes les vignettes sur lesquelles nous faisons glisser le maintenant la touche Ctrl ou Commande enfoncée, puis en cliquant et en faisant glisser, nous pouvons supprimer toutes les tuiles de la zone sélectionnée. En désactivant la gomme, nous pouvons utiliser les mêmes commandes pour ajouter des vignettes au jeu de vignettes Si vous souhaitez créer des vignettes surdimensionnées, vous pouvez le faire en maintenant la touche Shift enfoncée, puis en cliquant et en faisant glisser le pointeur sur plusieurs vignettes Cela traitera plusieurs carreaux comme s'ils étaient toujours destinés à être dessinés comme un plus grand groupe de carreaux. Mais cette feuille de sprites ne contient pas de vignettes surdimensionnées Je vais donc l'effacer et ajouter chacune de ces vignettes individuellement au jeu de vignettes Maintenant que notre jeu de tuiles contient des tuiles, notre couche de carte de tuiles peut utiliser ce jeu de tuiles pour dessiner les tuiles. Nous allons donc passer du panneau du jeu de tuiles au panneau de la carte de tuiles. fois l'outil de peinture sélectionné, nous pouvons sélectionner une source de carreaux dans le jeu de carreaux, puis un carreau à partir de la source de carreaux. Dans la vue de scène en deux D, l'éditeur fournit des directives orange indiquant comment les carreaux seront disposés et nous pouvons maintenant peindre ces carreaux où nous le voulons en cliquant. Si vous souhaitez modifier le décalage des tuiles, vous pouvez ajuster la position de transformation des nœuds de la couche tilemap transformation des nœuds de la couche Comme dans le jeu de carreaux, nous pouvons utiliser le bouton d'effacement pour effacer les carreaux au lieu de les peindre. L'outil de sélection peut être utilisé pour sélectionner une vignette dans la vue T D plutôt que dans le panneau du jeu de tuiles Nous pouvons dessiner des carreaux retournés horizontalement, verticalement ou les deux et les faire pivoter dans le sens horaire ou antihoraire selon les dans le sens horaire ou antihoraire Nous pouvons également regrouper, sélectionner plusieurs carreaux et les peindre tous en même temps. basculez pour placer une tuile au hasard, vous pourrez choisir parmi les tuiles sélectionnées au L'augmentation de la dispersion laissera certaines tuiles non peintes lorsque vous les déplacez. Vous pouvez également tracer des lignes. Lorsque plusieurs tuiles sont sélectionnées, elles seront répétées le long de la ligne. Et l'outil rectangle peut remplir très rapidement une zone entière de la couche cartographique en tuiles. L'outil bucket peut être utilisé pour remplir une zone fermée vide de la couche cartographique en tuiles. Les options aléatoires et de dispersion s'appliquent également aux outils de démolition et aux outils à godets L'outil bucket dispose également d'une bascule contiguë qui, lorsqu'elle est désactivée, peut être utilisée pour affecter toutes les tuiles correspondantes sur l'ensemble de la couche cartographique en tuiles sur l'ensemble de la Le nœud de la couche de carte en tuiles dessinant notre terrain, nous n'avons plus besoin du nœud body tutti statique et nous pouvons le supprimer de la scène De retour dans la scène du jeu, nous pouvons voir notre salle de départ. Le nœud n'est pas renommé. Il indique toujours le niveau actuel. Si nous lançons le jeu, le personnage n' entre pas en collision avec le terrain et tombe simplement à travers celui-ci Nous disposons désormais d'une couche cartographique utilisant un jeu de tuiles pour dessiner des tuiles, mais nous devons travailler davantage pour configurer notre jeu de tuiles. Je vous verrai dans la prochaine vidéo. 23. 3-2 Terrain: Bonjour, mes amis. Dans cette vidéo, nous allons utiliser davantage d'options de jeu de tuiles pour accélérer et faciliter la peinture de tuiles sur une couche cartographique en tuiles. À partir de la scène de la pièce, sélectionnez le nœud de la couche de cartes de tuiles, puis développez le jeu de tuiles dans l'inspecteur. En élargissant la section de la couche physique, elle est actuellement vide Nous allons donc ajouter une nouvelle couche physique. Nous n'avons pas besoin de modifier propriétés de la couche physique. Il faut juste qu'elle existe. Nous aborderons les couches de collision et le masquage des collisions plus tard dans le cours Mais si vous le souhaitez, vous pouvez également ajouter un matériau physique pour ajuster sa friction, sa rugosité, son élasticité ou son pouvoir absorbant. Je ne veux pas de matériel de physique, je vais donc le supprimer du menu déroulant. Une fois la couche physique ajoutée à notre jeu de tuiles, nous pouvons ouvrir l' onglet jeu de tuiles en bas de l'éditeur pour appliquer cette couche physique à nos tuiles. Passez de la configuration de l'atlas aux propriétés de peinture en cliquant sur ce bouton. Ici, nous pouvons peindre de nombreuses propriétés différentes sur nos carreaux, mais celle que nous voulons peindre en ce moment est la couche physique zéro. Sous peinture, le carreau entier doit être rempli par défaut de quatre nœuds blancs à tous les coins. Si ce n'est pas le cas, cliquez sur les trois points et sélectionnez Rétablir la forme par défaut ou appuyez sur la touche F. Nous pouvons maintenant peindre cette forme de collision physique sur nos carreaux. Tous ces carreaux sont conçus pour avoir la même forme carrée. Mais si vous utilisez différents actifs, vous devrez peut-être ajuster la forme de collision pour les différentes tuiles. Nous pouvons cliquer et faire glisser ces points blancs pour ajuster la forme de collision, les supprimer ou en ajouter d'autres selon les besoins pour créer la forme que nous voulons. Si vous avez besoin d'une meilleure vue pour être plus précis, vous pouvez étendre cet éditeur pour qu'il remplisse tout le panneau. Des options de capture de grille sont également disponibles. Régler le quadrillage à la taille en pixels vous permettra de créer une collision parfaite en pixels si vous le souhaitez R Après avoir peint des formes de collision sur les tuiles et relancé le jeu, le personnage entrera en collision avec nos tuiles Nous avons maintenant une collision, mais dessiner le terrain une tuile à la fois est très fastidieux Nous pouvons utiliser des outils intégrés à l'éditeur pour faciliter les choses. En élargissant la section de terrain, nous pouvons ajouter un ensemble de terrains à cet ensemble de tuiles. L'ensemble de terrain doit également être complété par un terrain. Nous allons donc également créer un élément ici. Nous pouvons nommer le terrain comme bon nous semble. Je vais donner un nom à ma forêt et lui donner une couleur. Cette couleur ne sera pas dessinée dans le jeu uniquement dans l'éditeur pour le configurer. Il est utile de choisir une couleur qui contrastera avec les couleurs utilisées dans la feuille de sprite pour qu'elle se démarque. J'utiliserai le rose pour contraster avec mes carreaux de terrain verts et bruns. Ouvrez ensuite le panneau du jeu de vignettes en bas de l'éditeur. Les terrains sont une façon de dessiner des tuiles conçues pour se connecter les unes aux autres, comme l'est cette feuille de sprite Passez aux propriétés de peinture, et la propriété que vous souhaitez peindre est la propriété du terrain. Nous pouvons ensuite sélectionner notre ensemble de terrains (nous venons de créer le terrain zéro) et le terrain de cet ensemble de terrains, le terrain forestier. Pour peindre la propriété du terrain, nous devons d'abord sélectionner chacune des tuiles qui font partie du terrain afin qu'elles ne soient plus sombres. Dans cette feuille de sprites, c'est tout. Lorsque vous passez la souris sur une tuile ajoutée à ce terrain, celle-ci est divisée en neuf carrés carré du milieu doit être rempli pour que cette tuile fasse partie de notre terrain. Les autres cases indiquent l'éditeur de dessiner cette tuile s'il y a une autre tuile de terrain adjacente à celle-ci dans cette direction. En commençant par cette tuile, celle-ci est destinée à être dessinée si aucune autre tuile de terrain n'est adjacente. Ainsi, seul le carré du milieu est peint. La tuile située à l' extrême gauche est destinée à être dessinée s'il y a une autre tuile de terrain à sa droite Le carré droit sera donc peint. La tuile opposée à droite suit la même logique à gauche, et la tuile du milieu est dessinée s'il y a terrain adjacent à la fois à gauche et à droite. Les carreaux verticaux sont les mêmes, juste en haut et en bas. Le grand bloc dans le coin supérieur gauche combine les deux, ajoute des coins et possède également la tuile pleine au milieu avec tous les carrés peints. Cela sera suffisant pour dessiner des blocs de terrain de forme convexe Ouvrez le panneau cartographique en tuiles, passez des tuiles aux terrains, puis sélectionnez le terrain que vous venez de créer. Une fois l'outil de peinture sélectionné, nous pouvons peindre librement des carreaux de terrain sur la couche de carte de tuiles, comme auparavant. Mais maintenant, si nos tuiles de terrain sont adjacentes à d'autres tuiles de terrain et forment des formes rectangulaires, elles seront automatiquement mises à jour avec la bonne tuile correspondant au terrain. L'effacement des vignettes actualisera également les vignettes environnantes. Cela fonctionne également avec les outils d'épave de ligne et de godet. Si nous voulons créer des coins concaves, nous devrons revenir à la peinture du terrain En ajoutant chacune des tuiles restantes au terrain, nous remplirons toutes les cases qui indiqueront s'il doit y avoir une autre tuile de terrain adjacente à celle-ci dans cette direction. Si vous suivez ces éléments et ne savez pas quel motif doit être dessiné sur chaque vignette, vous pouvez suspendre la vidéo et copier la mienne. Certaines ressources de tuiles fournissent un guide ou une référence pour vous aider à comprendre les règles de contiguïté pour les tuiles, ou vous pouvez simplement expérimenter et voir ce qui vous convient. Essayez de dessiner un terrain sous différentes formes pour voir si toutes les combinaisons possibles sont prises en compte et dessinez correctement. Les tuiles du bas sont également destinées à être dessinées avec le terrain adjacent dans toutes les directions. Chaque tuile d'une carte de tuiles est généralement conçue pour avoir un motif unique. Mais si vous avez plusieurs tuiles avec le même motif, l'outil de terrain en choisira une au hasard avec le même motif lors du dessin. Nous pouvons ajuster la probabilité de ce caractère aléatoire en peignant une autre propriété à partir de la liste déroulante des probabilités Entrez simplement une probabilité. J'utiliserai 0,01, soit 1 %, et je le peindrai sur les carreaux du bas Chaque fois que l'outil de terrain dessine une tuile adjacente dans toutes les directions, il a 1 % de chances de dessiner chacune de ces tuiles en bas ou d'utiliser la vignette vide par défaut Lorsque vous peignez un terrain à partir de la carte à tuiles, si la distribution aléatoire de ces tuiles ne semble pas très bonne, vous pouvez facilement continuer à dessiner dessus. L'éditeur de terrain recalculera la distribution aléatoire à chaque fois Nous pouvons désormais facilement dessiner des pièces pour notre jeu à l'aide d'un nœud de couche de cartes en tuiles, mais la caméra ne bouge pas, nous ne pouvons donc pas déplacer notre personnage très loin. Je vous verrai dans la prochaine vidéo. 24. 3-3 caméra: Bonjour, mes amis. Dans cette vidéo, la caméra suivra le personnage afin qu'il puisse se déplacer plus loin dans l'environnement. Dans la scène du jeu, nous avons le personnage et la caméra (deux nœuds en D) en tant que frères et sœurs. Évidemment, si nous attribuons la caméra le rôle d'enfant du personnage, elle suivra le joueur partout. Cependant, ce n'est pas une très bonne façon de procéder car la plupart des jeux comportent des transitions, des cinématiques ou d'autres zones du jeu qui s'adaptent à la vue de la caméra indépendamment du personnage du joueur Dans certains jeux, le joueur choisir le personnage qu'il veut incarner, et ce personnage doit être chargé Il n'est donc pas possible de déterminer dans la scène de jeu que la caméra doit suivre ce personnage. Il est préférable de laisser la caméra en tant que frère ou sœur et de lui demander suivre le personnage du joueur long d'un script. Attachons un script à notre caméra pour le décoder. Nous pouvons l'appeler caméra ou le nommer d'après le comportement, suivre le joueur ou combiner les deux, suivre la caméra. Nous pourrions exporter le personnage du joueur sous variable, comme nous l'avons fait avec le gestionnaire de saisie, mais supposons plutôt que cette caméra soit invitée à suivre plus d'un personnage tout au long du jeu et définissons plutôt une fonction publique nommée follow, qui accepte un sujet comme paramètre Théoriquement, ce sujet peut être n'importe quoi tant qu' il existe dans le monde des deux D et qu'il a une position Nous allons donc lui donner un type de nœud deux D plutôt qu' type plus spécifique de corps de personnage deux D. De cette façon, on pourrait demander à cette caméra de suivre un corps rigide ou tout ce que nous voulons. Cette fonction n'a pas besoin de renvoyer de valeur. Tout ce qu'il a vraiment besoin de faire est de stocker ce sujet dans une variable privée. Ensuite, en annulant la fonction de traitement, si cet appareil photo a un sujet, il réglera sa position pour qu'elle soit la même que la position globale du sujet Comme le sujet peut faire partie d'une scène plus vaste, nous ne voulons pas utiliser sa position locale par rapport à son parent, mais plutôt sa position globale dans le cadre de l'ensemble de la scène de jeu. Nous n'utilisons pas le paramètre Delta, je vais donc procéder avec un trait de soulignement Nous avons maintenant besoin d'un autre script pour appeler cette fonction depuis un nœud qui a accès à la fois à la caméra et à notre personnage, qui sera le nœud du jeu. En joignant un script au nœud de jeu, nous l'appellerons le gestionnaire de jeu, et je le mettrai dans un nouveau dossier de scripts pour les scripts de gestionnaire. Il sera de la responsabilité du game manager de gérer le moment où le joueur joue au jeu, se trouve dans une scène coupée ou passe d'une scène à l' autre Pour l'instant, lorsque le game manager prêt à annuler la fonction Ready, nous demanderons à la caméra de suivre le joueur et d'activer le gestionnaire de saisie Pour ce faire, nous devons stocker chacun de ces nœuds dans des variables. La hiérarchie de la scène de jeu étant assez complexe par rapport à d'autres scènes, il se peut que nous devions réorganiser les nœuds, modifiant leur filiation au cours du processus Lorsque cela se produit, le chemin du nœud dans notre script ne sera plus valide, ce qui entraînera des erreurs. Nous pouvons éviter cela en cliquant avec le bouton droit de la souris sur les nœuds notre arborescence de scènes et en sélectionnant Access comme nom unique. Cela ajoute un signe de pourcentage à droite du nœud dans l'arbre de la scène. Cela nous permet de remplacer le chemin du nœud annoté en signe dollar par le nom unique annoté en signe de pourcentage Si un nom unique a déjà été attribué au nœud, il sera automatiquement appliqué lorsque vous maintenez la touche Ctrl ou Commande enfoncée et que vous le glissez dans le script Maintenant que nous avons toutes ces références de nœuds, lorsque le gestionnaire de jeu sera prêt, nous pouvons demander à la caméra de suivre le personnage du joueur et d' activer le gestionnaire de saisie Nous n'avons pas encore écrit de fonction d'activation pour le gestionnaire d'entrées, alors passons à ce script et écrivons-le La création d'une variable privée est activée sous forme de booléen, qui sera définie par défaut sur false, et une fonction d'activation publique que nous pouvons définir est activée sur true Ensuite, avant de traiter les entrées du lecteur, nous vérifierons si le gestionnaire d'entrées est activé et retournerons si ce n'est pas le cas, nous quitterons la fonction si la valeur activée est fausse, empêchant ainsi l'exécution du code restant Nous aurons également besoin d'une fonction de désactivation qui redonne à la variable is enabled la valeur false. Cela peut sembler excessif, car nous pourrions simplement rendre publique la variable is enabled. Mais en utilisant cette structure encapsulée, nous pouvons appliquer une autre logique à l'intérieur de ces fonctions Par exemple, lorsque le gestionnaire de saisie est désactivé, dites au personnage d' arrêter de bouger en réglant la direction sur zéro et demandez-lui également de marcher Lorsque vous activez le gestionnaire de saisie, étant donné que le mouvement est en cours de vérification, il sera déjà détecté automatiquement Mais si le joueur a commencé à appuyer le bouton d'exécution avant que le gestionnaire de saisie ne soit activé, la saisie aura été ignorée, mais le joueur s'attend toujours à ce que son personnage court Nous pouvons vérifier l'état du bouton d'exécution lors l' activation du gestionnaire de saisie et indiquer au personnage de courir en conséquence Si vous utilisez la fonction de saisie pour le mouvement, nous pouvons vérifier sur le singleton de saisie l'état du déplacement vers la gauche et l'axe droit, et demander au personnage de se déplacer ici également. Pour en revenir à la scène du jeu, puisque la position du personnage est également à l'origine, c'est ce que la caméra va dessiner au début du jeu. Ce n'est pas un très bon cadrage du personnage ou de la pièce En général, le joueur a besoin de mieux voir ce qui se trouve au-dessus de lui ou ce qui l'attend. Nous pouvons décaler la position de la caméra pour la déplacer vers le haut le long de l'axe Y et vers la droite le long de l' axe X pour y parvenir. Je vais le placer de 64 pixels vers le haut et vers la droite et aussi changer mon zoom à deux. Ainsi, lorsque la position de la caméra est réglée pour correspondre à la position du personnage, chaque image sera ensuite décalée de cette valeur, donnant au joueur une vue légèrement vers le haut à droite du personnage. Notre caméra suit maintenant le personnage, mais elle ne regarde que vers la droite. Je vous verrai dans la prochaine vidéo. 25. 3-4 Regarder l'avenir: Bonjour, mes amis. Et cette vidéo permettra la caméra de regarder devant le personnage, soit vers la gauche, soit vers la droite. En commençant par le script de caractères, nous pouvons nous faciliter les choses en fournissant des noms de classe pour certains de nos scripts en utilisant le mot clé nom de classe en haut du script. Appelons cette classe quelque chose de plus générique, comme character. Cela permettra à Godot de compléter automatiquement les noms des variables et des fonctions lors de l'accès aux membres de cette classe dans d'autres scripts Tout comme nous avons utilisé des signaux pour réagir aux actions du personnage afin de produire des nuages de poussière, nous devrons émettre un autre signal lorsque le personnage change de direction. déclarant un signal nommé «   changement de direction », nous devons indiquer en paramètre la direction dans laquelle En déclarant un signal nommé «   changement de direction », nous devons indiquer en paramètre la direction dans laquelle le personnage se trouve actuellement . En ajoutant une autre variable à la section de locomotion, nous devrons savoir dans quelle direction le personnage fait actuellement face pour savoir s'il a changé de direction Comme une variable booléenne prend naturellement la valeur false par défaut, je vais nommer la variable orientée vers la gauche, ce qui, lorsqu'elle est fausse, implique qu' Dans la fonction face gauche, nous pouvons émettre notre nouveau signal et passer la valeur de direction comme argument. Au cours du processus physique, lorsque le joueur demande au personnage de faire face à la direction, cela se produit chaque fois le joueur donne une entrée à chaque image. Nous ne voulons pas émettre ce signal à chaque image, uniquement sur les images lorsqu' elles changent de direction. Nous allons donc ajouter la condition que le personnage soit orienté vers la gauche et que la direction soit supérieure à zéro, ou que le personnage ne soit pas orienté vers gauche et que la direction soit inférieure à zéro. Désormais, ces fonctions ne seront appelées que pendant l'image lorsque le personnage changera réellement de direction, ce qui émettra le signal pour que nous réagissions. Pour passer au script de caméra, nous aurons besoin d'une fonction correspondant à la signature du signal que nous venons de créer pour le connecter. Disons que le sujet change de direction, puisque le personnage sera le sujet, en acceptant la direction dans laquelle il fait face sous forme de virgule flottante et en ne renvoyant aucune valeur. Ce que nous voulons faire, c'est que le décalage X de la caméra corresponde au signe de direction. Nous devrons donc stocker la valeur du décalage dans une autre variable sans modification Nous l'appellerons offset par défaut et lui donnerons la valeur de offset à l'aide d'une balise ready. Nous pouvons maintenant modifier en toute sécurité la valeur du décalage sans oublier la valeur d'origine. H. Lorsque le sujet change de direction, nous définirons la valeur du décalage comme étant le décalage par défaut multiplié par le signe de direction. Ainsi, si la direction est positive, le décalage de la caméra sera également positif, et il en va de même pour le négatif. Pour connecter ce signal lorsque vous demandez à la caméra de suivre un sujet, si le sujet n'est pas nul et que le sujet est un personnage, classe que nous venons de nommer, nous pouvons accéder en toute sécurité au signal de direction modifié du personnage et le connecter à notre fonction. Un Godot ne reconnaîtra pas les nouveaux noms de classe tant que vous n'aurez pas enregistré vos scripts Mais si nous appelons cette fonction de suivi sur le même sujet plusieurs fois pour une raison quelconque, cela provoquera une erreur car le signal est déjà connecté. abord, vérifions-nous si le sujet que l'appareil photo est censé suivre est le même que le sujet qu'il suit déjà. Dans ce cas, nous n'avons rien à faire et nous pouvons simplement le renvoyer à cette fonction. Nous savons maintenant que le sujet est autre chose que le sujet actuel. Vérifie si le sujet actuel n'est pas nul et s'il s' agit d'un caractère. Si les deux conditions sont vraies, nous devons également vérifier si le signal de changement de direction du personnage a été connecté à la fonction de changement de direction du sujet. Et si c'est le cas, nous déconnecterons le signal, car l'appareil photo ne suit plus le sujet et n'a pas besoin de réagir. Au cours du jeu, cela positionnera la caméra devant le personnage, mais cela se produira instantanément, ce qui est assez choquant serait préférable d'ajuster progressivement la valeur du décalage au fil du temps, ce que nous pouvons facilement faire en utilisant un tween, abréviation de « in between Nous allons donc déclarer une nouvelle variable, appeler quelque chose comme look ahead tween A puis, lorsque le personnage change de direction, il affecte la valeur de cette variable pour créer un interpolation Create tween est une fonction de la classe node, donc n'importe quel nœud peut l'utiliser Lorsque l'interpolation sera créée, nous accéderons à sa fonction de propriété d'interpolation Cela accepte un objet comme premier argument, qui est ce nœud lui-même. Nous pouvons le spécifier avec le mot clé self. Ensuite, la propriété que nous voulons interpoler sous forme de chaîne, qui est la propriété offset, particulier le composant X, que nous pouvons spécifier avec deux L'argument suivant est la valeur finale, qui est le décalage X par défaut multiplié par le signe de direction que nous avons calculé précédemment. Et enfin, la durée de l'interpolation en secondes. Pour l'instant, je vais le régler sur 1 seconde. Comme cette interpolation prend une seconde, mais qu'il est très possible que le personnage change de direction plusieurs fois au cours de cette seconde, cela créerait plusieurs interpolations essayant toutes de modifier la valeur du décalage en même temps Donc, avant de créer l'interpolation, nous devons d'abord vérifier s'il existe déjà et s'il le tue De cette façon, il ne peut y avoir qu' un seul de ces préadolescents à la fois et essayer de modifier le décalage X. heure actuelle, le décalage X de la caméra s'ajuste pour devancer le personnage pendant une seconde, mais cela reste un peu choquant Nous pouvons ajuster la façon dont cette interpolation se produit en exportant d' autres variables abord, exportons la durée de cette interpolation sous forme flottante et donnons-lui une valeur par défaut de 1 seconde Remplacez ensuite celui de notre fonction par cette variable. Ensuite, nous allons ajouter un type de transition et un type d'assouplissement. Ensemble, ces trois variables nous permettront de créer une grande variété d' interpolations différentes en ajustant la rapidité avec laquelle la valeur change au début et à la fin de l'interpolation Puisque create tween renvoie un tween, nous pouvons accéder à sa fonction set trans et transmettre notre type de transition en argument sur la même ligne La fonction set trans renvoie également l'interpolation Nous pouvons donc continuer cette ligne et appeler la fonction set Es immédiatement après. Passer notre variable Es en argument. Tout cela renverra le tween avec le type de transition et de facilité défini et attribuera le résultat à la variable Depuis la scène de jeu, en sélectionnant le nœud camera tutti, en examinant ses propriétés dans l'inspecteur, nous pouvons modifier les valeurs de ces variables avec les types de transition et d'assouplissement qui fournissent des listes déroulantes pratiques Nous pouvons également raccourcir ou allonger la durée de la préadolescence Je vais faire en sorte que le mien utilise un quad entre deux secondes. Essayez d'expérimenter les différentes options pour vous faire une idée de leur fonctionnement Le type de transition détermine la formule mathématique utilisée pour modifier le comportement, tandis que le type d'assouplissement détermine impact sur la première ou la seconde moitié de l'interpolation Maintenant, la caméra se déplace doucement vers la gauche ou vers la droite pour montrer ce qui se trouve devant la direction dans laquelle le personnage fait face, mais parfois le joueur peut également vouloir regarder vers le haut ou vers le bas Je vous verrai dans la prochaine vidéo. 26. 3-5 Regarder vers le haut: Bonjour, mes amis. Dans cette vidéo, nous allons permettre au joueur de demander au personnage de regarder vers le haut ou vers le bas. Tout d'abord, nous devons ajouter d' autres événements d'entrée à la carte d'entrée dans les paramètres du projet pour les consulter vers le haut et vers le bas. J'utiliserai les flèches haut et bas. Les touches du pavé directionnel vers le haut et vers le bas, et le joystick droit incliné vers le haut et vers le bas. Ensuite, dans le script du joueur, contrairement à la direction du mouvement, qui n'est utilisée que par le personnage, la direction du regard sera utilisée la fois par le personnage et par la caméra, ce qui signifie que nous aurons besoin d'une référence à la caméra. Il est intéressant de stocker la direction de l'apparence dans une variable, nous n'avons donc besoin de la calculer qu'une fois par image. Ensuite, dans la fonction de processus, obtenez sa valeur à partir du singleton d'entrée, la même manière que nous l'avons fait pour la direction du mouvement en utilisant la fonction get axis, en modifiant le nom des actions d'entrée N'oubliez pas que puisque up est négatif, ce sera le premier argument. Nous pouvons ensuite envoyer cette direction du regard au personnage et à la caméra. Pour l'appareil photo, je vais utiliser un appel de fonction. Mais pour le personnage, je vais modifier la valeur d'une variable publique Pour rendre le nom de la variable de direction de la classe de caractères un peu plus clair, il peut être judicieux de le renommer en direction du déplacement Comme cette fonction n' existe pas dans le script de caméra, je vais la commenter pour le moment afin d'éviter les erreurs jusqu'à ce que je sois prêt à l'écrire. Dans le script du personnage, nous pouvons ouvrir la boîte de dialogue de remplacement avec Control ou Command R et remplacer la direction par la direction du déplacement afin de mieux comprendre à quoi elle servira. Ajoutez ensuite une nouvelle variable publique pour la direction du look. La variable de direction L n'a pas besoin d'être utilisée n'importe où dans le script. Il ne sera lu que par l'arbre d'animation. Depuis la scène des personnages, en sélectionnant le lecteur d'animation, je dois créer des animations LU et L down. Je vais dupliquer mon animation inactive pour faciliter les choses. Ensuite, modifiez simplement les valeurs Y de mes images clés pour dessiner le personnage en regardant vers le haut ou vers le bas en conséquence. Ensuite, dans la machine d'état Animation Tree qui édite la machine d' état Locomotion, je peux ajouter les animations de recherche vers le haut et de bas en bas Transition vers eux en fonction de la valeur de la direction du regard. Et en s'assurant que leur vitesse X reste nulle, sinon ils devraient plutôt passer à la marche. Et revenez au mode veille dans le cas où la direction du regard est égale à zéro. Ou s'ils ont commencé à marcher, le personnage s'animera pour regarder vers le haut ou vers le bas lorsque nous appuyons sur les directions haut et bas, mais que la caméra ne bouge pas encore Dans la scène de jeu, essayez de modifier le décalage Y de la caméra et décidez jusqu'où vous souhaitez que la caméra se déplace lorsque le personnage regarde vers le haut ou vers le bas. J'utiliserai 128 pixels et rétablirai la valeur par défaut de 64 pixels. Pour en revenir au script du lecteur, je vais maintenant décommenter la fonction caméra, puis passer au script caméra pour déclarer cette fonction J'accepterai une direction sous forme de valeur flottante et je ne retournerai aucune valeur. Le corps de cette fonction sera presque identique à celui de la fonction de changement de direction sur le sujet. Il suffit de remplacer toutes les instances d' une tête par du haut vers le bas. Déclarez-les ensuite en tant que nouvelles variables. Nous aurons également besoin d'une autre variable exportée pour la distance d'observation maximale que nous avons choisie plus tôt, que nous utiliserons à la place du décalage par défaut, et le décalage X sera le décalage Y. Cependant, lorsque nous relâcherons que nous utiliserons à la place du décalage par défaut, et le décalage X sera le décalage Y. les flèches vers le haut ou vers le bas, nous voulons que la caméra revienne à la valeur de décalage par défaut, et non à zéro Cela nécessitera donc un peu de logique supplémentaire. Une autre façon d'ajouter des instructions if simples à vos scripts consiste à utiliser une opération ternaire qui, dans GDScript, utilise les mêmes mots clés if qu'une instruction if normale, commençant par le cas par défaut, qui est la valeur que nous avons déjà calculée, mais uniquement si la direction n'est pas nulle, suivie Donc, si la direction est nulle, nous voulons utiliser notre décalage Y par défaut à la place. Cela fonctionne, mais dans la plupart des jeux dotés de ce mécanisme, le joueur doit maintenir le bouton enfoncé pendant un certain temps avant que la caméra ne bouge. Nous pouvons y parvenir en ajoutant un nœud de temporisation au nœud de joueur. Donnons-lui un nom. Regarde, attends. Nous pouvons ajuster le temps d'attente à partir de l'inspecteur, mais une seconde suffit, et le chronomètre devra être ponctuel. En connectant le signal de temporisation de ce chronomètre au script du joueur, c'est à ce moment-là que le script du joueur indiquera la caméra de commencer à regarder dans la direction En haut du script, nous devrons récupérer une référence à l'ancien nœud Timer, et nous aurons également besoin d' un booléen pour savoir si le joueur recherche actuellement ou non Dans la fonction process, après avoir obtenu la valeur de direction du regard à partir du Singleton d'entrée, si le joueur regarde déjà, puis si la direction du regard est égale à zéro, nous réinitialiserons la caméra en appelant sa fonction look et en passant zéro comme argument Ensuite, le set semble être faux. La raison pour laquelle je n'ai pas utilisé d' instruction and est de pouvoir utiliser une autre instruction si je suppose ici et maintenant que la recherche est fausse. Vérifiez également si la direction du regard n'est pas nulle. Dans ce scénario, où le joueur ne regarde pas encore, mais qu'il indique la direction du look, alors si le chronomètre est arrêté, nous devrons le démarrer. En ajouter une autre si le joueur ne regarde pas et ne donne aucune information sur la direction du look, puis si le chronomètre n'est pas arrêté, cela signifie que nous devons l'arrêter et annuler le look. En ajoutant des instructions d'impression pour tous ces éléments, nous pouvons confirmer que chacun d'entre eux n'est appelé qu'une seule fois lorsque cela est approprié. Nous devrons également régler la variable is looking sur true lorsque le temporisateur d' attente expire et que l'appareil photo commence à effectuer l'interpolation lancez le jeu, appuyez sur les flèches vers le haut ou vers le bas sans les maintenir enfoncées, le chronomètre démarre mais s'arrête et la caméra ne bouge pas, mais le personnage continue de s' animer en regardant de haut en bas En maintenant les touches haut ou bas enfoncées, le chronomètre expire au bout seconde et indique à l' appareil photo de regarder vers le haut ou vers le bas. En relâchant les touches haut ou bas, la caméra revient à sa position de décalage par défaut. Je vais commenter ces instructions d'impression et ajuster mes paramètres d'interpolation dans l'inspecteur pour qu'ils s'écoulent en une demi-seconde Le joueur peut désormais maintenir les directions haut et bas enfoncées pour regarder vers le haut et vers le bas, mais nous souhaiterons peut-être limiter la distance de déplacement de la caméra afin d'éviter de diffuser du contenu en dehors de la pièce actuelle. Je vous verrai dans la prochaine vidéo. 27. 3-6 limites: Bonjour, mes amis. Dans cette vidéo, nous allons restreindre la caméra pour qu'elle reste dans les limites de l'environnement. À partir de la scène de la pièce, nous pouvons transformer le nœud racine en un nœud de zone deux D plutôt qu'un nœud à deux D normal. Ceci est similaire à un corps physique en ce sens qu'il a une forme de collision, mais il n'a aucune masse et ne réagit pas aux forces. Vous pouvez plutôt le considérer comme un détecteur de mouvement ou de chaleur. Il représente une région de l'espace et émet un signal lorsque des corps physiques y entrent ou en sortent. Cela sera utile ultérieurement pour détecter le moment où le personnage du joueur entre dans la pièce. Mais pour l'instant, il suffit de savoir de quelle forme il s'agit. En ajoutant une forme de collision pour désigner un enfant, nous pouvons lui donner une ressource de forme Nous utiliserons une forme rectangulaire. Nous pouvons ensuite déplacer et redimensionner la forme pour créer des limites de pièce un attachez un script au nœud racine de la scène, nous le nommerons Room et le trierons dans le dossier des scripts. Nous aurons besoin d'une référence à la forme de collision pour se déformer. Je vais le renommer en shape node. Ensuite, nous avons besoin de fonctions qui peuvent être utilisées pour récupérer le coin supérieur gauche et le coin inférieur droit de ce rectangle afin qu'ils renvoient les deux coordonnées du vecteur. Nous pouvons accéder à la propriété de forme de collision à deux dénœuds par son nom shape Ensuite, nous voulons également appeler une fonction sur la ressource de forme, Get wrecked La fonction G wrecked renvoie une épave deux, si nous ouvrons la documentation de cette classe, nous pouvons voir qu'elle a une position et une fin La position est le coin supérieur gauche et l'extrémité est le coin inférieur droit. Mais celles-ci sont relatives à la position des nœuds. Nous aurons besoin de ces coordonnées dans l'espace global, nous les ajouterons donc à la position globale du nœud. La position globale d'un nœud sera relative à l'origine du jeu, non à la position du nœud parent. Nous pouvons ensuite renvoyer ces valeurs. Il ne nous reste plus qu'à dire à la caméra de respecter ces limites. la scène du game manager, pour le moment, nous allons simplement récupérer une référence à la salle de départ et la stocker dans une variable nommée salle actuelle. Lorsque la scène de jeu est prête, nous pouvons obtenir le coin supérieur gauche et le coin inférieur droit de la pièce actuelle, et nous les transmettrons à la caméra en appelant une fonction qui définit ses limites. passant au script de caméra, nous allons déclarer que cette fonction accepte les deux vecteurs récupérés dans la pièce actuelle et ne renvoie aucune valeur Dans cette fonction, nous allons déterminer quelle distance la caméra peut atteindre les coins supérieur gauche et inférieur droit de cette pièce sans rien voir au-delà de ces points. Pour ce faire, nous devons créer ces variables sous forme de vecteurs deux, et il sera utile d' avoir un booléen si la caméra est actuellement liée ou non Nous devons également connaître la taille de la fenêtre, nous pouvons récupérer automatiquement avec la fonction Get Viewport, puis accéder à sa propriété de taille et la stocker dans une variable à l'aide de la balise on ready La fonction Get Viewport est déclarée dans la classe node et renvoie un vecteur deux, correspondant à la taille de la fenêtre définie dans les paramètres du projet taille de cette fenêtre d'affichage n'est pas nécessairement la même que le nombre de pixels qui seront dessinés par l'appareil photo, car celui-ci peut effectuer un zoom avant ou Nous devrons diviser la taille de la fenêtre par le zoom de la caméra pour obtenir la taille réelle en pixels de la zone visible par la caméra Mais un vecteur ne peut pas être divisé par un autre vecteur. Nous devons utiliser un flotteur. Je vais utiliser uniquement le zoom X et supposer que le zoom de l'appareil photo sera toujours uniforme. Mais cela ne suffit toujours pas , car la position de la caméra est au centre de son champ de vision. La position la plus proche dans laquelle la caméra peut se positionner dans le coin supérieur gauche ou inférieur droit de la pièce sans dessiner au-delà ces points sera en fait la moitié de la taille. En divisant cette valeur par deux, je renommerai la variable pour refléter sa nouvelle valeur Lorsque vous définissez les limites, la position la plus à gauche sera le coin supérieur gauche de la pièce, plus la moitié de la taille de la vue de la caméra. Alors que la position la plus basse à droite sera le coin inférieur droit de la pièce moins la moitié de la taille de la vue de la caméra, nous pouvons définir la valeur limite sur true. H. Dans la fonction de traitement, après avoir indiqué à l'appareil photo de correspondre à la position du sujet, nous appliquerons ces restrictions de limites l'aide de la fonction Clamp F. La fonction clamp F prend un paramètre flottant tel que la position de la caméra, puis une valeur minimale et une valeur maximale, puis renvoie une valeur qui restera dans ces limites. Nous allons ensuite remplacer la position de la caméra par le résultat bloqué et répéter cette opération pour le Y. Mais comme notre caméra possède également un décalage, sa position n'est pas une représentation suffisamment précise du centre de sa fenêtre d' Nous modifions également la valeur du décalage à des moments imprévisibles. Ce n'est donc pas quelque chose que nous pouvons prendre en compte dans les calculs en haut à gauche et en bas à droite, car la valeur changera probablement souvent. Nous devrons donc prendre en compte le décalage dans les fonctions de serrage en le soustrayant en haut à gauche et en bas à droite Si vous souhaitez que votre caméra zoome et dézoome pendant le jeu tout en respectant ces limites, vous devez également en tenir compte dans les calculs de la fonction de processus Cela fonctionne, mais les préadolescents semblent avoir du mal à franchir les limites L'interpolation déplace le décalage de la caméra légèrement en dehors des limites L'image est dessinée, puis la boucle de traitement suivante éloigne la position de la caméra de la limite pour compenser le nouveau décalage Cela se produit à plusieurs reprises jusqu'à ce que l'interpolation s'arrête. En effet, les tweens sont exécutés après le processus à la fin du cadre juste avant de tout dessiner à l'écran Pour résoudre ce problème, nous pouvons remplacer l'utilisation de la propriété tween par la méthode tween En appelant une méthode, nous pouvons appliquer les limites en même temps que nous modifions la valeur du décalage. Les arguments de la méthode tween, au lieu d'une référence à un objet, nécessitent une méthode appelable Nous dirons set Y offset. Suivi par la valeur de départ, qui est la valeur actuelle du décalage Y de la caméra , les arguments restants sont les mêmes. Deux est la valeur finale à la fin de l'interpolation et la durée de l'interpolation Nous pouvons faire la même chose avec le look ahead tween two. Il suffit d'écrire cette fonction de décalage set X, acceptant un seul paramètre correspondant au type du formulaire et deux arguments. Après avoir modifié la valeur du décalage X, nous pouvons appliquer la limite limite à la position de la caméra pour compenser immédiatement et faire de même pour le décalage y. En procédant ainsi, les préadolescents décalés atteindront pas leur maximum au-delà des limites de la pièce La caméra est désormais limitée à l'affichage de ce qui se trouve dans la pièce actuelle, mais l'environnement semble très plat. Je vous verrai dans la prochaine vidéo. 28. Parallaxe 3-7: Bonjour, mes amis. Dans cette vidéo, nous allons corriger le défilement parallaxe du premier plan et de l'arrière-plan à l' aide À partir de la deuxième scène de pièce, je vais copier toutes mes couleurs de modulation des nœuds Parallax Tut vers leurs nœuds enfants Ensuite, je peux dissocier les sprites et supprimer les nœuds Parallax Tut tout en conservant Je vais ensuite joindre un nouveau script à l'un de ces sprites, le nommer Parallax et le placer dans le dossier des scripts Ce même script peut être attaché à tous les sprites que je souhaite ajouter à Parallax Pour créer un comportement personnalisé, il est utile de prendre le temps de réfléchir à ce que vous essayez d'atteindre, aux références de nœuds et aux autres informations qui seront nécessaires. J'ai plusieurs sprites différents. Je veux me déplacer à des distances différentes par rapport à la position de la caméra, et je sais que la caméra est actuellement bloquée dans les limites de cette pièce. Je vais ajouter temporairement une caméra à deux nœuds D à la scène et zoomer d'un facteur deux pour prétendre qu'il s' agit de la scène du jeu. Si l'appareil photo est exactement au centre de cette pièce, je voulais tout dessiner exactement tel quel. Mais lorsque la caméra s'éloigne du centre, je déplace tous les sprites de parallaxe une quantité relative, les éléments d' arrière-plan se déplaçant moins que la caméra et les éléments premier plan se déplaçant dans la Pour ce faire, chaque sprite devra connaître la position de la caméra par rapport au centre de la pièce, ainsi que sa propre position d'origine Dans le script Parallax, je vais déclarer une variable exportée contenant le facteur selon lequel le sprite se déplace par rapport à la caméra et je vais lui donner le nom d'échelle de défilement sous la forme d'un vecteur deux Cela fonctionnera de la même manière que la variable d'échelle de défilement dans le nœud Parallax Two D. Lorsque cette pièce est chargée dans l'arbre de scène, nous pouvons utiliser la balise on ready pour obtenir sa position et la stocker dans une variable comme position d'origine. Il est facile d'obtenir une référence à la caméra actuelle grâce à la fonction node G Viewport Renvoie la fenêtre d'affichage dans laquelle se trouve ce nœud, qui possède également la fonction Get camera to D pour obtenir la caméra Nous pouvons également le stocker dans une variable, en utilisant la balise on ready. remplaçant la fonction du processus, nous n'avons pas besoin de Delta et nous pouvons la marquer comme non utilisée Je vais simplement régler la position du sprite comme sa position d'origine plus la distance entre la caméra et le centre de la pièce multipliée par l'échelle de défilement Désormais, la caméra a juste besoin d'une fonction publique qui peut nous indiquer sa position par rapport au point médian de la pièce actuelle Pour passer au script de caméra, j'écrirai cette fonction, offset par rapport au point médian, qui sera la position de la caméra plus son décalage moins le point médian de la pièce actuelle déclarant qu'il s'agit d'une nouvelle variable, je peux la calculer comme la moyenne des coins supérieur gauche et inférieur droit de la pièce lorsque je les accepte à partir de la fonction de définition des limites Nous pourrions modifier cette fonction pour accepter le milieu et la taille du rectangle plutôt que ses coins supérieur gauche et inférieur droit, mais cela ne fera aucune différence en termes d'efficacité de toute façon, donc je ne m'embêterai pas Nous pouvons maintenant définir l'échelle de défilement pour chacun des sprites de parallaxe afin de leur donner à chacun une distance différente par rapport à la caméra Je n'utiliserai toujours que la parallaxe horizontale, ce qui donne à mes collines une échelle de défilement d'un tiers le long de l'axe X, et aux collines situées plus en arrière des deux tiers Pour le premier plan, ils devront se déplacer dans la direction opposée à celle de la caméra, ils auront une échelle de défilement de moins un tiers et de moins deux tiers Cela sera suffisant pour créer une illusion de profondeur dans nos pièces. lançant le jeu, nous pouvons passer à la deuxième pièce et constater que l'effet de parallaxe est identique à celui de la salle de départ, bien qu'il soit réalisé par un script très simple Comme les sprites du premier plan se déplacent dans la direction opposée à celle de la caméra, ils devront soit répéter et enrouler leur position pour créer une boucle infinie, ils devront soit répéter et enrouler leur position pour créer une boucle infinie, soit nous pouvons simplement agrandir le sprite par rapport à la Si mes arbustes sont 1,5 fois plus longs que la pièce et que le gazon double la longueur de la pièce, il en restera suffisamment de chaque côté pour que les bords n' atteignent jamais le champ de vision de la caméra. R Il serait possible d' Il serait utiliser le nœud Parallax Two D pour dessiner le premier plan et l' arrière-plan à dessiner le premier plan et l' l'aide d'une fenêtre séparée et de les dessiner sur différentes couches de toile ou d'essayer de toujours dessiner la pièce actuelle à l'origine de la scène de jeu Ces solutions entraîneraient d'autres complications et limitations par la suite lorsqu'il s' agira de dessiner la carte du jeu, par exemple. Je trouve qu'il est parfois plus facile d'écrire des solutions personnalisées comme celle-ci que d'utiliser les nœuds fournis. La solution permet également centraliser tous les éléments nécessaires à une pièce, ce qui simplifie la conception et la construction des pièces de manière plus intuitive. Je n'ai plus besoin de ce nœud de caméra Tuti, je vais donc le supprimer En supprimant les nuages du nœud Parallax touti, nous pouvons modifier le script Parallax également faire défiler automatiquement les En élargissant l'étendue de la région, il suffit de diminuer la valeur d' exposition au fil du temps pour déplacer les nuages vers la droite diminuer la valeur d' exposition au fil du temps pour déplacer les En attachant le script Parallax à ce nœud, nous pouvons d'abord régler son échelle de défilement un afin qu'elle corresponde au mouvement de la caméra Cela fera apparaître les nuages une distance infinie par rapport aux collines de Parallax exportant un autre vecteur deux pour la vitesse de défilement automatique, nous devons maintenant utiliser Delta dans la fonction de traitement et nous pouvons supprimer le trait de soulignement En accédant à la propriété region rect et à sa position, commençant par le X, nous allons soustraire la valeur AutoScrollX Cela fera donc de la vitesse de défilement automatique des pixels par seconde. Attribuez ensuite le résultat à la position X de la région. Mais si nous devions l'exécuter pendant très longtemps, ce nombre se rapprocherait des limites d' un nombre à virgule flottante et pourrait poser des problèmes. La valeur de la position X correspond à la taille, le résultat est en fait le même. Il serait préférable de remettre la position X à zéro lorsque cela se produit, afin que nous puissions la contourner pendant une durée infinie. En utilisant la fonction AP F, nous pouvons fournir une valeur minimale et maximale pour la limiter à une valeur comprise entre zéro et la taille du rec. Cette fonction renverra un résultat qui doit être compris entre ces deux valeurs, mais contrairement au bridage, le reste sera toujours inclus dans le résultat Et nous pouvons faire la même chose si nous voulons utiliser le défilement automatique vertical Je vais faire défiler automatiquement les nuages le long du X à des fins de démonstration. Et lorsque nous lançons le jeu, les nuages défilent automatiquement vers la droite, en boucle à l' Maman. Maman. Je vais rétablir la valeur de défilement automatique à un montant raisonnable. Nous avons maintenant le défilement parallaxe du premier plan et de l' arrière-plan Mais les transitions entre les pièces sont très soudaines. Je vous verrai dans la prochaine vidéo. 29. 4-1 Synthèse: Bonjour, mes amis. Dans cette section, nous autoriserons le joueur à se déplacer entre plusieurs pièces de notre jeu. ouvrant la scène de la pièce de départ, nous pouvons constater que les composantes visuelles de cette pièce dépassent les limites de la caméra. Si nous étions dans une pièce adjacente à celle-ci, nous ne voudrions pas voir ces sprites dessiner alors qu'ils sont censés se trouver dans une autre pièce De plus, si nous devions imaginer l'ensemble de notre jeu rempli de nombreuses pièces différentes, ce serait un énorme gaspillage de ressources que d'avoir tous leurs composants visuels chargés alors que nous n'en visionnons qu'une à la fois. Nous allons donc ajouter un autre nœud deux D à la scène. Nommez son contenu. Replacez ensuite tous ces autres nœuds sur le nœud de contenu, à l' exception de la forme de collision En cliquant avec le bouton droit sur le nœud de contenu, nous l'enregistrerons en tant que scène à part entière. Je vais créer un nouveau dossier dans le Forest Rooms pour le contenu. Nommez ensuite le contenu de la scène Start Room. Supprimez ensuite le contenu de cette scène. Lorsque le personnage du joueur entre dans cette pièce, ne nous reste plus qu'à charger son contenu et à l'ajouter à la scène. Supprimez ensuite le contenu lorsqu'il est parti. Nous pouvons détecter le moment où le personnage du joueur entre dans la pièce en connectant le signal saisi par son corps, puisque le nœud Tutti du personnage est un corps physique En connectant ce signal au script de la pièce, il ajoutera automatiquement une fonction pour nous lorsque le corps est saisi, acceptant le corps comme paramètre. Nous n'avons pas besoin du corps, nous pouvons donc le faire précéder d'un trait de soulignement pour le marquer comme non utilisé En haut du script, il sera utile de donner un nom de classe à ce script. Appelons-le Room. Exportez ensuite le contenu sous la forme d'une scène compressée. Et renseignez cette variable en cliquant et en faisant glisser la scène de contenu depuis l'onglet du système de fichiers vers l'inspecteur Nous allons également déclarer une variable de contenu sous la forme d'un nœud deux D. Déclarer une nouvelle fonction nommée load contents. Si le contenu est nul, nous lui attribuerons la valeur du contenu vu instancié Ajoutez ensuite le nœud de contenu à la scène en tant qu'enfant. Lorsque le personnage du joueur entre dans cette pièce, nous appelons la fonction de chargement du contenu. Imprimons temporairement la valeur du corps pour voir de quoi il s'agit. Nous aurons également besoin d' une autre fonction pour décharger le contenu de la pièce lorsqu'il ne sera plus nécessaire, mais nous ne pourrons pas la tester avant la prochaine vidéo Tout d'abord, vérifiez s'il y a du contenu à décharger. S'il y a du contenu, appelez sa fonction Qu free et définissez la variable sur null. fait de libérer un nœud de l'arbre de scène n' efface pas automatiquement le contenu de la variable Donc, si nous devions quitter une pièce, décharger son contenu, puis y entrer à nouveau, cette instruction if, vérifiant si la valeur du contenu est nulle, dirait « oui, il y a réellement quelque chose dans cette variable de contenu Cependant, le nœud qui a été stocké ici a été précédemment libéré de l'arbre de scène, ce qui provoquera une erreur. Ainsi, le fait de définir la variable sur null après l'avoir supprimée de l' arborescence de la scène résout ce problème. En cours de jeu, notre personnage se trouve dans la zone de collision de la salle de départ, ce qui déclenche le chargement du contenu de la salle de départ. Cependant, nous ne voulons pas que d' autres corps physiques déclenchent le signal et chargent accidentellement le contenu de la pièce. Nous devons nous assurer que le personnage du joueur sera le seul à pouvoir faire en sorte que cela se produise. passant à la scène du personnage du joueur, nous pouvons sélectionner le nœud Tutti du corps du personnage et étendre la section de collision dans les propriétés héritées de collision Object Nous avons ici une couche de collision et un masque de collision, chacun avec 32 boutons numérotés. Ce sont des masques de bits, qui ne sont que des nombres entiers utilisés d'une manière particulière. Comme les nombres entiers sont stockés sous forme de 32 zéros et uns binaires, nous pouvons utiliser chaque bit comme couche Lorsque vient le temps de vérifier l'absence de collisions, en appliquant des opérations logiques simples entre masque de collision d' un objet et la couche de collision de l'autre objet, nous pouvons déterminer s'ils doivent entrer en collision ou non ne peut être déclenchée que si le masque du premier objet possède une position binaire identique collision ne peut être déclenchée que si le masque du premier objet possède une position binaire identique à celle de la couche du second objet. Sinon, il passera comme s'il n'y était pas. remplaçant la couche de collision du personnage par un autre numéro, elle existera désormais sur une couche de collision unique En remplaçant la couche de collision du personnage par un autre numéro, elle existera désormais sur une couche de collision unique, séparée de tout le reste du jeu. Comme les chiffres sont par groupes de huit, j'aime utiliser les huit premières couches pour les couches de collision environnementale, les huit suivantes pour le personnage du joueur, les huit suivantes pour les ennemis, etc. Le corps du personnage masque toujours la première couche Il continuera donc à entrer en collision avec le terrain pendant son processus physique lorsque nous appelons move et slide Nous pouvons nommer ces couches dans les paramètres du projet sous le nom de couche Physics two D. Je vais nommer la couche 1 comme terrain et la couche 9 comme joueur. Ces noms seront affichés lorsque vous passez la souris sur les boutons des couches dans l'inspecteur, ainsi que leur valeur en bits et en nombres entiers Dans la scène de la salle de départ, nous pouvons changer le masque de collision. Ainsi, cette zone à deux dende ne masquera que la couche de collision entre le joueur et le personnage du joueur, seul le personnage du joueur déclenchera des collisions avec cette zone En relançant le jeu, rien ne changera, mais nous pouvons être sûrs qu'aucun autre corps chargera le contenu de la pièce. Notre salle charge désormais son contenu de manière dynamique lorsque le personnage du joueur y entre, mais nous n'avons toujours qu'une seule pièce. Je vous verrai dans la prochaine vidéo. 30. 4-2 pièces: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter une deuxième pièce dans laquelle le personnage pourra se déplacer. Nous allons commencer par dupliquer la scène de la salle de départ. Je vais appeler cette chambre une seconde. Ensuite, dupliquez également la scène du contenu de la salle de départ et ouvrez-la pour que je puisse la modifier, puis retirez les arbres et la canopée pour qu'elle soit visuellement distincte de la pièce de départ. Nous pouvons également modifier le terrain et les limites si nous voulons rendre les deux pièces encore plus distinctes. En ouvrant la deuxième scène de pièce, je vais renommer le nœud racine de la scène pour qu'il corresponde à son nom de fichier N'oubliez pas d'attribuer la scène de contenu de la deuxième pièce à la scène de l' espace de la deuxième pièce afin qu'elle charge le contenu correct lors de la saisie. Dans la scène du jeu, comme mon monde sera divisé en régions, j'ajouterai un nœud deux D et je le nommerai forêt. Alors fais de mes deux chambres des enfants de la région forestière. Enregistrez la région forestière en tant que scène propre dans le dossier des pièces et ouvrez la scène de la région forestière pour la modifier. Dans la scène de la région forestière, nous pouvons désormais facilement positionner ces deux pièces l'une à côté de l'autre. Nous voulons placer les pièces les unes à côté des autres afin de pouvoir changer de pièce lorsque le joueur quitte une pièce pour entrer dans une autre. Activez la capture de grille, puis étendez les options de capture et sélectionnez Configurer la capture d'écran et Nous pouvons régler le pas de la grille en fonction de la taille des tuiles de nos tuiles de terrain, soit 32 pixels. Il est ainsi très simple de positionner les pièces exactement alignées les unes à côté des autres. Le signal saisi par le corps du nœud de Tutti dans la zone sera émis dès que la forme de collision du personnage Tutti chevauche la forme de collision de la pièce Pour simplifier les choses, nous devrons laisser un peu d' espace entre les pièces suffisamment grand pour que le corps du personnage ne puisse pas chevaucher plus d' une pièce à la fois. Sinon, il faudrait ajouter une logique supplémentaire lorsque le personnage entre dans une pièce sans quitter complètement la pièce précédente. Leur corps de personnage chevauche les espaces des deux pièces en même temps, puis fait demi-tour et retourne dans la première pièce C'est beaucoup plus facile si les pièces sont espacées. Lorsque le personnage entre dans une nouvelle pièce, on sait qu'il est déjà sorti de la pièce précédente Cela permettra également au personnage de se déplacer complètement en dehors limites de la caméra avant déclencher la transition vers la nouvelle pièce. Comme la forme de collision de mon personnage ne mesure que 12 pixels large et que l'écart entre les pièces est de 32 pixels de large, je suis certain que le personnage trouvera ces deux pièces sans toucher les deux en même temps. Cet écart signifie que toutes nos pièces devront également étendre leur collision avec le sol suffisamment loin des limites de la caméra pour empêcher le personnage tomber avant qu'il n'atteigne la pièce adjacente Je vais légèrement dézoomer sur la caméra et commenter la ligne de code qui lie la caméra aux limites de la pièce actuelle. cours de jeu, nous pouvons constater que le contenu de la salle de départ chargé immédiatement car le personnage était déjà dans cette pièce. En se déplaçant vers l'endroit où se trouvera la deuxième pièce, son contenu est chargé dès que le personnage du joueur franchit le seuil. Mais nous voulons également décharger le contenu de la pièce précédente que nous venons de quitter Il sera de la responsabilité du game manager de gérer les transitions, car cela impliquera la collaboration de nombreux acteurs de la scène de jeu. Nous devrons envoyer un signal depuis la pièce dans laquelle nous avons accédé au game manager, qui ne se trouve même pas dans la même scène que dans notre projet. Nous aurons également de nombreuses pièces différentes dans notre jeu et ce serait pénible devoir connecter manuellement ce signal pour chaque pièce à la fois. Il serait donc plus facile d'utiliser nos scripts pour l'automatiser. À partir du script de salle, nous allons ajouter un nouveau signal en haut du script que nous pouvons émettre pour indiquer que le personnage du joueur est entré dans cette pièce avec la pièce saisie comme paramètre. Ensuite, lorsque le signal saisi par le corps est reçu, nous émettons ce signal au lieu de charger le contenu et nous passons cette pièce elle-même comme argument. Lorsque cette pièce sera prête, nous pouvons accéder à la racine de l' arbre des scènes en démarrant une poupée ou en signant le chemin annoté d'un nœud avec une barre oblique, puis le mot racine et une autre barre oblique À partir de la racine de l'arbre de scène, le premier nœud auquel nous voulons accéder s'appelle game, comme il est nommé dans la scène de jeu. Cela nous donne accès au script du gestionnaire de jeu avec un point. Ensuite, nous pouvons faire référence à une fonction que nous n'avons pas encore écrite. Disons que c'est le cas lorsque le joueur est entré dans la salle. Ensuite, nous pouvons écrire cette fonction dans le script du gestionnaire de jeu avec un paramètre de pièce correspondant. Je vais l'appeler room Entered pour être plus clair dans ce contexte. Afin de décharger le contenu de la pièce précédente, nous devons savoir quelle était la pièce précédente Nous aurons donc besoin d'une variable pour indiquer la pièce dans laquelle se trouve actuellement le personnage du joueur Je vais remplacer ce niveau actuel par la chambre actuelle et le laisser vide. Je n'ai plus besoin de l'étiquette On Ready. La première chose à faire est de vérifier si la pièce entrez est la même que celle dans laquelle se trouve actuellement le personnage du joueur. Dans ce cas, nous n'avons pas vraiment besoin de faire quoi que ce soit et nous pouvons simplement revenir de cette fonction. Nous pouvons maintenant supposer que la pièce actuelle et la pièce saisie sont des pièces différentes. Au premier démarrage du jeu, il n'y a pas de place actuellement. Nous allons d'abord vérifier si la chambre actuelle n'est pas nulle. S'il y a une pièce en cours, nous devons lui dire de décharger son contenu en utilisant la fonction que nous avons écrite dans la vidéo précédente En assignant ensuite la pièce actuelle à la pièce dans laquelle nous entrons, nous pouvons maintenant demander à cette pièce actuelle de charger son contenu et enfin lier la caméra aux limites de la pièce actuelle Mais je vais le commenter afin que nous puissions voir ce qui se passe avec le zoom arrière. Maintenant, lorsque nous lançons le jeu, entrer dans la deuxième pièce envoie un signal au game manager pour qu'il décharge le contenu de la salle de départ avant de charger le contenu de la deuxième salle Nous avons maintenant plusieurs pièces dans notre jeu, mais le défilement parallaxe au premier plan et à l'arrière-plan ne fonctionne pas pour les pièces qui ne sont pas fonctionne pas pour les pièces qui ne sont pas centrées sur Je vous verrai dans la prochaine vidéo. 31. Parallaxe 4-3: Bonjour, mes amis. Dans cette vidéo, nous allons corriger le défilement parallaxe du premier plan et de l'arrière-plan à l' aide À partir de la deuxième scène de pièce, je vais copier toutes mes couleurs de modulation des nœuds Parallax Tut vers leurs nœuds enfants Ensuite, je peux dissocier les sprites et supprimer les nœuds Parallax Tut tout en conservant Je vais ensuite joindre un nouveau script à l'un de ces sprites, le nommer Parallax et le placer dans le dossier des scripts Ce même script peut être attaché à tous les sprites que je souhaite ajouter à Parallax Pour créer un comportement personnalisé, il est utile de prendre le temps de réfléchir à ce que vous essayez d'atteindre, aux références de nœuds et aux autres informations qui seront nécessaires. J'ai plusieurs sprites différents. Je veux me déplacer à des distances différentes par rapport à la position de la caméra, et je sais que la caméra est actuellement bloquée dans les limites de cette pièce. Je vais ajouter temporairement une caméra à deux nœuds D à la scène et zoomer d'un facteur deux pour prétendre qu'il s' agit de la scène du jeu. Si l'appareil photo est exactement au centre de cette pièce, je voulais tout dessiner exactement tel quel. Mais lorsque la caméra s'éloigne du centre, je déplace tous les sprites de parallaxe une quantité relative, les éléments d' arrière-plan se déplaçant moins que la caméra et les éléments premier plan se déplaçant dans la Pour ce faire, chaque sprite devra connaître la position de la caméra par rapport au centre de la pièce, ainsi que sa propre position d'origine Dans le script Parallax, je vais déclarer une variable exportée contenant le facteur selon lequel le sprite se déplace par rapport à la caméra et je vais lui donner le nom d'échelle de défilement sous la forme d'un vecteur deux Cela fonctionnera de la même manière que la variable d'échelle de défilement dans le nœud Parallax Two D. Lorsque cette pièce est chargée dans l'arbre de scène, nous pouvons utiliser la balise on ready pour obtenir sa position et la stocker dans une variable comme position d'origine. Il est facile d'obtenir une référence à la caméra actuelle grâce à la fonction node G Viewport Renvoie la fenêtre d'affichage dans laquelle se trouve ce nœud, qui possède également la fonction Get camera to D pour obtenir la caméra Nous pouvons également le stocker dans une variable, en utilisant la balise on ready. remplaçant la fonction du processus, nous n'avons pas besoin de Delta et nous pouvons la marquer comme non utilisée Je vais simplement régler la position du sprite comme sa position d'origine plus la distance entre la caméra et le centre de la pièce multipliée par l'échelle de défilement Désormais, la caméra a juste besoin d'une fonction publique qui peut nous indiquer sa position par rapport au point médian de la pièce actuelle Pour passer au script de caméra, j'écrirai cette fonction, offset par rapport au point médian, qui sera la position de la caméra plus son décalage moins le point médian de la pièce actuelle déclarant qu'il s'agit d'une nouvelle variable, je peux la calculer comme la moyenne des coins supérieur gauche et inférieur droit de la pièce lorsque je les accepte à partir de la fonction de définition des limites Nous pourrions modifier cette fonction pour accepter le milieu et la taille du rectangle plutôt que ses coins supérieur gauche et inférieur droit, mais cela ne fera aucune différence en termes d'efficacité de toute façon, donc je ne m'embêterai pas Nous pouvons maintenant définir l'échelle de défilement pour chacun des sprites de parallaxe afin de leur donner à chacun une distance différente par rapport à la caméra Je n'utiliserai toujours que la parallaxe horizontale, ce qui donne à mes collines une échelle de défilement d'un tiers le long de l'axe X, et aux collines situées plus en arrière des deux tiers Pour le premier plan, ils devront se déplacer dans la direction opposée à celle de la caméra, ils auront une échelle de défilement de moins un tiers et de moins deux tiers Cela sera suffisant pour créer une illusion de profondeur dans nos pièces. lançant le jeu, nous pouvons passer à la deuxième pièce et constater que l'effet de parallaxe est identique à celui de la salle de départ, bien qu'il soit réalisé par un script très simple Comme les sprites du premier plan se déplacent dans la direction opposée à celle de la caméra, ils devront soit répéter et enrouler leur position pour créer une boucle infinie, ils devront soit répéter et enrouler leur position pour créer une boucle infinie, soit nous pouvons simplement agrandir le sprite par rapport à la Si mes arbustes sont 1,5 fois plus longs que la pièce et que le gazon double la longueur de la pièce, il en restera suffisamment de chaque côté pour que les bords n' atteignent jamais le champ de vision de la caméra. R Il serait possible d' Il serait utiliser le nœud Parallax Two D pour dessiner le premier plan et l' arrière-plan à dessiner le premier plan et l' l'aide d'une fenêtre séparée et de les dessiner sur différentes couches de toile ou d'essayer de toujours dessiner la pièce actuelle à l'origine de la scène de jeu Ces solutions entraîneraient d'autres complications et limitations par la suite lorsqu'il s' agira de dessiner la carte du jeu, par exemple. Je trouve qu'il est parfois plus facile d'écrire des solutions personnalisées comme celle-ci que d'utiliser les nœuds fournis. La solution permet également centraliser tous les éléments nécessaires à une pièce, ce qui simplifie la conception et la construction des pièces de manière plus intuitive. Je n'ai plus besoin de ce nœud de caméra Tuti, je vais donc le supprimer En supprimant les nuages du nœud Parallax touti, nous pouvons modifier le script Parallax également faire défiler automatiquement les En élargissant l'étendue de la région, il suffit de diminuer la valeur d' exposition au fil du temps pour déplacer les nuages vers la droite diminuer la valeur d' exposition au fil du temps pour déplacer les En attachant le script Parallax à ce nœud, nous pouvons d'abord régler son échelle de défilement un afin qu'elle corresponde au mouvement de la caméra Cela fera apparaître les nuages une distance infinie par rapport aux collines de Parallax exportant un autre vecteur deux pour la vitesse de défilement automatique, nous devons maintenant utiliser Delta dans la fonction de traitement et nous pouvons supprimer le trait de soulignement En accédant à la propriété region rect et à sa position, commençant par le X, nous allons soustraire la valeur AutoScrollX Cela fera donc de la vitesse de défilement automatique des pixels par seconde. Attribuez ensuite le résultat à la position X de la région. Mais si nous devions l'exécuter pendant très longtemps, ce nombre se rapprocherait des limites d' un nombre à virgule flottante et pourrait poser des problèmes. La valeur de la position X correspond à la taille, le résultat est en fait le même. Il serait préférable de remettre la position X à zéro lorsque cela se produit, afin que nous puissions la contourner pendant une durée infinie. En utilisant la fonction AP F, nous pouvons fournir une valeur minimale et maximale pour la limiter à une valeur comprise entre zéro et la taille du rec. Cette fonction renverra un résultat qui doit être compris entre ces deux valeurs, mais contrairement au bridage, le reste sera toujours inclus dans le résultat Et nous pouvons faire la même chose si nous voulons utiliser le défilement automatique vertical Je vais faire défiler automatiquement les nuages le long du X à des fins de démonstration. Et lorsque nous lançons le jeu, les nuages défilent automatiquement vers la droite, en boucle à l' Maman. Maman. Je vais rétablir la valeur de défilement automatique à un montant raisonnable. Nous avons maintenant le défilement parallaxe du premier plan et de l' arrière-plan Mais les transitions entre les pièces sont très soudaines. Je vous verrai dans la prochaine vidéo. 32. 4-4 Transition: Bonjour, mes amis. Dans cette vidéo, nous allons faciliter la transition entre les pièces en passant simplement au noir. Dans la scène de jeu, la plupart des jeux commencent avec un écran de chargement ou sont complètement noirs, puis s'estompent au début du jeu. En ajoutant un nœud à la couche de toile, nous pouvons utiliser un nœud coloré pour dessiner facilement des couleurs simples En élargissant la section de mise en page, nous allons modifier le préréglage des ancres pour qu'il soit complètement détruit Cela indiquera à la couleur détruite de remplir toute la toile Il est actuellement blanc, mais le noir est plus courant, nous pouvons donc changer la couleur en noir en haut. Lorsque le jeu démarre, il suffit changer progressivement cette couleur du noir au clair, pour révéler la fenêtre de la caméra située derrière elle Avec nos petites salles simples, elles se chargent instantanément. Le chargement et le déchargement du contenu de la chambre n'entraînent actuellement aucun retard Mais si nous imaginons que nos salles seront composées de beaucoup plus de sprites en particulier d'effets sonores et de musique de fond, la pièce chargement de la pièce prendra plus de temps qu'une seule image Nous pouvons utiliser le même effet vers l' arrière pour passer au noir, décharger et charger notre pièce, puis réapparaître une fois que tout est terminé Ce projet ne deviendra pas trop grand que nous ayons besoin d'un véritable écran de chargement. Renommons ce nœud fade et donnons-lui un nom unique. Nous devrons nous assurer que ce nœud reste au bas de l'arbre de la scène pour être dessiné par-dessus tout le reste ou augmenter son indice Z. fait d'avoir ce grand rectangle noir dans la scène du jeu peut vous empêcher de travailler sur d'autres choses. Nous souhaiterons peut-être que ce nœud soit masqué par défaut. En joignant un script à ce nœud, je le nommerai fade et je l' enregistrerai dans le dossier des scripts. remplaçant la fonction ready, la première chose que je veux faire est définir sa propriété visible sur true, afin qu'elle couvre tout en noir Nous aurons besoin de deux fonctions publiques pour régler la couleur en noir ou en clair. Pour ajuster la valeur d' une propriété au fil du temps, le moyen le plus simple consiste à utiliser une interpolation Nous allons donc en déclarer une en tant que variable. Bien que je ne pense pas autoriser décoloration plus d'une fois de suite, c'est quand même une bonne idée de vérifier si le préadolescent existe déjà et de le tuer au cas où Créez ensuite une nouvelle interpolation. Pas besoin de types de transition ou d'assouplissement sophistiqués ici, un interpolation linéaire fonctionnera parfaitement Et il faudra intercaler ce nœud lui-même, sa propriété de couleur et changer sa couleur pour qu'elle soit transparente au fil du temps Pour l'instant, je vais mettre 1 seconde. Une couleur transparente est définie dans la classe, mais si nous passons la souris dessus, nous pouvons voir qu'elle contient des valeurs rouge, verte et bleue égales à un, valeurs rouge, verte et bleue égales à un, ce qui signifie qu'elle est en blanc transparent et non en noir transparent Cela ne créera pas l'effet souhaité. Je vais donc définir ma propre couleur transparente en tant que constante et la nommer claire. L'utilisation de toutes les majuscules est classique pour nommer des constantes Il s'agira d'une couleur sans aucune valeur rouge, verte, bleue et alpha. Nous pouvons également définir une constante pour la durée de l'interpolation et remplacer la 1 seconde par cette constante Il est ainsi un peu plus facile modifier la durée sans avoir à parcourir le script et sans exporter une variable vous souhaitez conserver la cohérence pour l'ensemble de votre projet. Pour la fonction feed to black, nous pourrions copier et coller tout ce code, en ne modifiant que l'argument de valeur finale de l' appel de la fonction de propriété d'interpolation, mais il serait préférable d' éviter la redondance Nous allons plutôt en faire sa propre fonction privée nommée tween color, en acceptant la couleur finale comme paramètre, puis en la transmettant à l' appel de la fonction de propriété d'interpolation en tant qu'argument Ensuite, la fonction fate to black et deux fonctions clear peuvent appeler cette fonction en passant des arguments différents. Dans le script du gestionnaire de jeu, nous allons saisir une référence au nœud de fondu en haut. Lorsque le personnage du joueur entre dans une pièce après avoir chargé le contenu de la pièce, nous pouvons indiquer que le fondu change de couleur pour qu'il soit clair début du jeu, il n'y aura pas de pièce à décharger actuellement, donc elle aura pas de pièce à décharger actuellement, Au début du jeu, il n'y aura pas de pièce à décharger actuellement, donc elle disparaîtra immédiatement. Après être entrés dans la deuxième pièce, nous devons passer au noir avant de décharger le contenu de la pièce actuelle, puis procéder au chargement de la deuxième pièce et y revenir Mais cette fonction n'attendra pas la fin du préadolescent pour décharger le contenu de la pièce Il le fera immédiatement. Pour suspendre cette fonction pendant que l'interpolation passe au noir, nous pouvons utiliser le mot clé await L'attente sera suivie d'un signal. Le signal que nous voulons attendre est le signal de fin de l'interpolation dans le script de fondu Nous pouvons donc renvoyer ce signal à partir de notre fonction d'interpolation. Changer le type de retour de notre fonction de void à signal. Faire passer à nouveau le même signal de retour par les fonctions de fondu au noir et d'effacement. De retour dans le script du gestionnaire de jeu, le game manager peut désormais accéder à ce signal chaque fois qu'il appelle ces fonctions. Nous pouvons attendre que le fondu passe au noir ou que le fondu disparaisse Cette fonction s'arrêtera donc et attendra la fin de l'interpolation avant de continuer Nous ne voulons généralement pas que le joueur ait le contrôle du personnage pendant que cela se produit. Nous pouvons donc appeler player point Disable en haut de la fonction avant de commencer la transition et réactiver le nœud joueur à la fin fois la transition terminée. J'ai oublié de mettre à jour cette variable de direction pour déplacer la direction lorsque je l'ai renommée. Bien que ces pièces soient assez petites et devraient être déchargées et chargées assez rapidement, nous pouvons tout de même observer un cas où la pièce précédente se décharge et, comme il n'y a pas de terrain sur lequel le personnage peut observer un cas où la pièce précédente se tenir debout, elle tombe par terre avant que se tenir debout, le contenu de la pièce suivante ne soit chargé pour créer un nouvel étage contenu de la pièce suivante ne soit chargé pour créer un nouvel Nous devons donc également désactiver et activer le personnage en même temps que le nœud joueur. Une autre façon d' activer et de désactiver les nœuds consiste à modifier leur propriété de mode de processus. En le désactivant au début de la transition, puis en héritant une fois la transition terminée Désormais, le joueur ne peut plus contrôler le personnage et celui-ci ne sera pas affecté par la gravité lors de la transition entre les pièces Ensuite, nous allons travailler à dessiner nos chambres sur une carte. Je vous verrai dans la prochaine vidéo. 33. 4-5 Fenêtres de vue: Bonjour, mes amis. Dans cette vidéo, nous allons commencer à dessiner nos chambres sur une carte. Bien qu'il soit possible de dessiner la carte séparément du monde du jeu, il est encore plus difficile de maintenir la cohérence entre le maintenir la cohérence entre monde et la carte si vous devez les mettre à jour séparément chaque fois que vous modifiez quelque chose Positionner les icônes sur la carte, en particulier les icônes qui peuvent se déplacer comme le personnage du joueur, peut devenir une tâche encore plus ardue. Une méthode beaucoup plus simple pour créer une carte consiste simplement à avoir une deuxième caméra pour visualiser le monde dans une perspective zoomée, mais à dessiner le monde et son contenu de manière plus simple Ajoutons donc une autre caméra à notre scène de jeu et renommons celle-ci en caméra cartographique Par défaut, seule la première caméra sera utilisée et elle dessinera la fenêtre principale du jeu Pour dessiner la carte, la caméra cartographique devra dessiner une fenêtre différente Nous allons donc en ajouter une en tant que nœud dans l'arbre de la scène, qui est un nœud secondaire Renommez-le en Map Viewport et donnez-lui un nom unique. Dans certains de nos scripts, nous avons déjà utilisé la fonction G Viewport pour obtenir la fenêtre principale du jeu, qui est utilisée pour dessiner le monde en deux D du jeu Dans ce contexte, le monde à deux D n'est pas le même que le nœud environnemental mondial. Il contient tous les nœuds TD actuellement situés au centre, y compris le gestionnaire de jeu. Si nous adaptons la caméra cartographique à la fenêtre cartographique, cette caméra dessinera désormais la fenêtre cartographique au lieu de la fenêtre principale du jeu, mais elle n'a aucun endroit sur l'écran pour la Nous devrons donc ajouter un nœud texturé à la couche de toile pour permettre à la caméra de dessiner la fenêtre d'affichage Appelons-la texture Map Viewport. Je vais supprimer tous ces nœuds de contrôle factices et m'assurer que le nœud endommagé par la texture est dessiné avant le nœud fondu en le plaçant plus haut dans la hiérarchie de la scène En cliquant sur le menu déroulant des textures, nous pouvons sélectionner la texture de la fenêtre d'affichage , puis sélectionner la fenêtre d'affichage de la carte à dessiner comme texture pour cette texture mouillée Le rectangle de texture sera automatiquement redimensionné pour correspondre à la taille de la fenêtre d'affichage moment, il dessine simplement la couleur d' arrière-plan gris par défaut, car la caméra cartographique et le Viewport ne peuvent rien voir Par défaut, chaque Viewport aura son propre monde. Vous pouvez considérer ces mondes comme des mondes parallèles ou des plans d'existence. Ils peuvent occuper le même espace en même temps mais exister indépendamment les uns des autres. Mais nous voulons que cette fenêtre dessine le même monde que notre fenêtre principale Dans le script du gestionnaire de jeu, nous allons récupérer une référence au nœud Map Viewport Ensuite, dans la fonction Ready, définissez la propriété world two D du Viewport Nous pouvons accéder à la fenêtre principale en appelant la fonction get Viewport du gestionnaire de jeu, puis en accédant à sa propriété World Two D. Désormais, la fenêtre principale et la fenêtre cartographique dessineront le même monde Nous voulons généralement que nos cartes permettent de visualiser une plus grande partie du monde Je vais donc régler le zoom sur un huitième. Si nous voulons modifier les dimensions de la texture de la carte, nous pouvons définir les dimensions en pixels de la fenêtre d' affichage en la sélectionnant dans l'arbre de la scène Je vais lui donner la moitié des dimensions de mon jeu de 640 x 360 pixels. Plutôt que de dessiner cette couleur grise alors qu'il n'y a rien, je préfère que l'arrière-plan de ma fenêtre cartographique soit transparent Je vais passer à un arrière-plan transparent. Cependant, cela rend la carte difficile à lire J'aimerais que cette texture de carte soit contenue dans un panneau pour qu'elle apparaisse séparément du jeu principal. En ajoutant un conteneur de panneaux à la couche Canvas, je vais redéfinir la texture de la carte pour qu'elle soit un enfant du nœud de conteneur de panneaux, puis renommer le conteneur de panneaux Map et lui donner un nom unique Avec le thème par défaut, le conteneur du panneau dessinera une couleur noire transparente et comme il s'agit d'un conteneur, il se redimensionnera automatiquement pour contenir ses enfants Cela indique clairement que la texture de la carte est dessinée sur le canevas, non comme une partie du monde, et nous pouvons ajuster l' apparence du conteneur de panneaux ultérieurement via l'éditeur de thème. Je vais utiliser les ancrages du panneau pour l'ancrer au centre de l'écran Nous voulons généralement que la caméra cartographique suive le personnage du joueur comme le fait la caméra principale, mais sans aucune fonction d' interpolation ou autre. Contrairement à la caméra principale, la caméra cartographique n'aura jamais besoin de faire autre chose pouvez donc toujours faire en sorte qu'elle corresponde exactement à la position du personnage du joueur. Il est impossible de placer la caméra de la carte le personnage du joueur, car celui-ci doit rester un enfant de la fenêtre de la carte pour dessiner la Nous pourrions écrire un autre script pour déplacer cette caméra, mais il existe un nœud que nous pouvons utiliser pour faciliter les choses, la transformation à distance de deux D. Avec la transformation à distance deux D en tant qu'enfant du personnage du joueur, nous pouvons définir son chemin à distance vers la caméra cartographique. Désormais, les propriétés de transformation, la position, la rotation et l'échelle de la caméra seront automatiquement mises à jour pour être identiques à celles du personnage du joueur. Nous pouvons désactiver la rotation et l' échelle en élargissant la section de mise à jour Même si nous modifiions la rotation ou l'échelle du personnage du joueur, nous ne voudrions pas que la carte copie ces propriétés. Mm. Le monde de nos jeux est maintenant dessiné sur le Canvas, mais nous voulons en dessiner une version simplifiée plutôt qu'une copie exacte. Je vous verrai dans la prochaine vidéo. 34. 4-6 Visibilité: Bonjour, mes amis. Dans cette vidéo, nous allons demander à la caméra cartographique dessiner une version simplifiée du monde. En commençant par la salle de départ, ajoutons temporairement le contenu de la pièce. Je ne veux pas dessiner tous ces sprites sur la carte, juste un aperçu de la forme et du terrain de la pièce Nous pouvons utiliser n'importe quel nœud à deux D le dessiner en fonction du style souhaité. Je vais utiliser un nœud de couche Tile Map. Donnez-lui un nouveau jeu de vignettes de 32 x 32 pixels. Je vais importer un nouveau sprite, qui n'est qu'un simple carré blanc de 32 x 32 pixels Ajoutez-le ensuite au jeu de vignettes. dessinant ce carré blanc sur ma couche Tile Map, je vais dessiner le contour de la pièce en utilisant le terrain comme sol plutôt que la limite de la caméra et laissant les portes reliées aux autres pièces Nous voulons que la caméra principale dessine uniquement le contenu, tandis que la caméra cartographique dessine cette note de la couche Tile Map à la place. Pendant que les deux regardent la même pièce, ils en verront deux versions différentes. Maintenant que j'ai la forme de ma pièce, je vais supprimer le contenu de la scène. Comme le nœud de la couche Tile Map sera toujours visualisé par la caméra cartographique, il restera toujours chargé au lieu d'être chargé et déchargé comme le contenu élargissant la section de visibilité, je peux utiliser la propriété moduler la couleur pour transformer mes carrés blancs en carrés colorés si je le souhaite Comme cela fait partie de la région forestière, je vais dessiner sa carte en vert. Pour que la caméra cartographique le dessine , mais pas la caméra principale, je vais modifier sa couche de visibilité 1-2. La couche de visibilité par défaut sera composée de tout ce qui est dessiné par la caméra principale du jeu, tandis que la couche deux sera que je souhaite dessiner sur la carte. Tout comme pour les couches de collision, nous pouvons nommer ces couches de visibilité dans les paramètres du projet sous les noms des couches (rendu en deux D). Je vais nommer la couche 1 monde et la couche 2 Map. Ces couches de visibilité dépendent des couches de visibilité de leurs parents. Si le Viewport ne peut pas voir le nœud de la zone de la pièce de départ, il ne se donnera pas la peine de vérifier s'il peut voir le nœud enfant de la couche Tile Map La couche de visibilité du nœud parent de la salle de départ devra être définie à la fois sur un et sur deux, car ses enfants pourront être dessinés par les deux fenêtres. En progressant dans la hiérarchie, la visibilité de la région forestière doit être configurée pour utiliser les deux couches de visibilité, tout comme le nœud racine des scènes de jeu. Le nœud d'environnement mondial ne possède pas de propriété de couche de visibilité. En sélectionnant maintenant la fenêtre d'affichage de la carte, nous pouvons configurer son masque d'appel Canvas pour afficher uniquement la couche deux et non la couche un Cela fonctionne de la même manière que la propriété du masque de collision pour les objets en collision. Ce n'est que si le bit du masque est défini sur un que celui-ci pourra voir tout ce dont la couche possède le même bit défini sur un ? Mais nous ne pouvons pas accéder à la fenêtre principale depuis l'éditeur pour modifier son masque d'appel Canvas afin n'afficher que la couche un et non la couche deux Par défaut, toutes les couches seront masquées. Nous devrons donc le modifier par le biais d'un script. Dans la fonction Game Manager Scripts Ready, nous pouvons accéder à la fenêtre principale avec la fonction G Viewport, puis définir sa propriété de masque d' appel Canvas survolant la couche 1, nous pouvons voir que sa valeur entière est également un Nous pouvons simplement définir la valeur des masques d'appel Canvas sur un. Désormais, il ne visualisera que la couche de visibilité 1 et non la couche deux ou toute autre couche d'ailleurs. copiant le nœud de la couche Tile Map dans la salle de départ, je vais le coller dans la deuxième pièce pour dessiner également cette pièce sur la carte. J'instancierai le contenu de la pièce, puis je modifierai les carreaux pour qu'ils reflètent plus précisément la forme de cette pièce et je supprimerai le contenu lorsque j'aurai terminé N'oubliez pas de définir la couche de visibilité des nœuds parents pour qu'elle existe sur les deux couches de visibilité afin que les enfants soient visibles dans leurs fenêtres d'affichage respectives. Désormais, les deux pièces sont clairement visibles sur la carte très peu d'efforts étant donné que nous ajoutons de nouvelles pièces Il suffit d'ajouter la carte de chaque pièce de sa scène sur une couche de visibilité distincte. Nous pouvons facilement ajouter d'autres éléments à la deuxième carte en y ajoutant plus de sprites et en les plaçant sur la deuxième couche de visibilité, comme l'icône d'un personnage de la carte d'un joueur En ouvrant la scène des personnages du joueur, ajoutons un sprite à déchiffrer et nommons-le icône de la carte Je vais remplir la texture avec une texture d'atlas, utiliser la même feuille de sprites et sélectionner une région à utiliser comme icône de carte J'utiliserai la tête du personnage quelque part dans la feuille de sprites, là où la queue ne le gêne pas Après avoir renseigné la propriété de texture, nous allons définir sa couche de visibilité sur deux et non sur une Le nœud racine de cette scène devra alors comporter à la fois les couches 1 et 2. Je vais m'adapter au décalage du sprite pour qu'il repose sur le sol comme le fait le personnage Sachant que le zoom de l'appareil photo est d'un huitième, je vais agrandir cette icône huit fois pour qu'elle apparaisse très grande dans la scène. Comme je ne veux pas que cette icône recouvre mon personnage chaque fois que je travaille dans la scène, je préfère qu'elle soit cachée . Cela vaut tous les personnages de mon jeu auxquels je souhaite associer une icône cartographique. Je vais ajouter un script à ce nœud, le nommer Map icon. Et je vais juste lui demander de définir la propriété de visibilité sur true une fois prêt. Maintenant, cette très grande icône cartographique n'a pas besoin d' être dessinée dans l'éditeur pendant que je travaille sur mon personnage, mais elle le sera lorsque je lancerai le jeu. Notre carte dessine maintenant les contours des pièces et le personnage du joueur à l'aide d'une icône, mais nous souhaiterons peut-être activer ou désactiver la carte à l'aide d'un bouton Je vous verrai dans la prochaine vidéo. 35. Carte 4-7: Bonjour, mes amis. Dans cette vidéo, nous allons permettre au joueur d' ouvrir et de fermer la carte à l'aide d'un bouton. À partir de la scène de jeu, je masquerai la carte par défaut en activant la visibilité du nœud conteneur qui la contient. Attachez ensuite un nouveau script au conteneur. Bien que j'utilise actuellement un conteneur de panneaux pour cela, je n'ai besoin d'accéder à aucune des fonctionnalités du conteneur de panneaux dans ce script et je peux hériter du type de contrôle plus générique Si je souhaite utiliser un autre type de nœud de contrôle à l'avenir, je n'ai pas besoin de modifier mon script. Ce script aura besoin de fonctions publiques pour ouvrir et fermer la carte. Pour simplifier les choses, je vais simplement définir la visibilité du nœud sur true ou false en conséquence. Il existe également des fonctions d'affichage et de masquage définies dans la classe d'éléments Canvas qui font la même chose. Bien que cela puisse sembler inutile d'avoir une fonction qui appelle simplement une autre fonction, garder vos implémentations encapsulées dans fonctions publiques de ce type signifie nous pouvons facilement la mettre à jour à l' avenir Nous pouvons ajouter une logique supplémentaire à ces fonctions pour faire bouger les choses lorsque la carte est ouverte ou fermée, ou nous pouvons utiliser une interpolation pour déplacer la carte hors écran ou la faire grossir ou rétrécir au lieu déplacer la carte hors écran ou la faire grossir ou rétrécir au lieu de simplement modifier sa visibilité Si je souhaite apporter ces modifications, me suffit de modifier ce script, plutôt que de modifier également le script du lecteur ou tout autre script qui appelle ces fonctions. Comme j'ai décidé d'utiliser un bouton à bascule pour activer ou désactiver la carte, au lieu d'appeler les fonctions d'ouverture ou de fermeture, je préférerais avoir une seule fonction de bascule qui En ajoutant une variable privée indiquant si la carte est actuellement ouverte ou non, je vais demander à la fonction de bascule de fermer la carte si elle est ouverte ou de l' ouvrir si elle est fermée Ensuite, les fonctions d'ouverture et de fermeture peuvent définir la valeur de I open en conséquence. ouvrant les paramètres du projet, dans l'onglet Carte d'entrée, nous devons ajouter une nouvelle action de saisie pour ouvrir et fermer la carte. J'utiliserai la touche de retour arrière et le bouton de sélection de ma manette La plupart des jeux avec ce type de carte de jeu permettront également au joueur de déplacer la caméra. J'ai déjà consulté les entrées vers le haut et vers le bas. J'ajouterai simplement regarder à gauche et regarder à droite. À l'aide des flèches gauche et droite ou du joystick droit incliné vers la gauche ou la droite sur ma manette Dans le script du lecteur, nous pouvons exporter une variable contenant une référence au nœud de la carte et la renseigner dans l'inspecteur Ensuite, dans la fonction de saisie, indiquez à la carte d'activer ou de désactiver si le bouton de la carte a été enfoncé cours de jeu, la carte commence à être masquée, mais en appuyant sur le bouton de la carte, la carte s'affiche et en appuyant à nouveau dessus, elle se ferme. Pour déplacer la caméra cartographique , il suffit d' ajuster sa valeur de décalage. Nous allons donc donner au script cartographique une référence à la caméra cartographique. Ajout d'une fonction publique nommée pan, acceptant un argument vectoriel deux pour la direction dans laquelle effectuer le panoramique de la caméra. Nous allons ajouter au décalage de la caméra cette direction multipliée par la vitesse Pan, et nous pouvons accéder à Delta même si nous ne sommes pas dans une fonction de processus en appelant la fonction Get Process Delta t de la classe de nœuds. En exportant cette variable de vitesse de panoramique, je mettrai la mienne à 1024. Cela peut sembler rapide, mais n'oubliez pas que la caméra cartographique est zoomée très loin, elle semblera donc se déplacer à un huitième de sa vitesse Pour que le script du joueur contrôler cette caméra lorsque la carte est ouverte, il doit être capable de savoir si la carte est ouverte Plutôt que de rendre publique la variable is open, ce qui permet à un autre script de modifier sa valeur, nous pouvons écrire une fonction qui renvoie la valeur de la variable. Lorsque la carte sera fermée, je remettrai le décalage de la caméra à zéro, afin qu'elle soit à nouveau centrée sur le personnage du joueur. Pour passer au script du joueur, nous allons ajouter les commandes permettant déplacer la carte dans la fonction de traitement Mais uniquement si la carte est ouverte. Si la carte est ouverte, nous lui demanderons de se déplacer. Tout comme nous avons utilisé l'axe G pour obtenir l'état de deux directions opposées sous forme de flotteur, nous pouvons utiliser le vecteur G pour obtenir un vecteur deux dans quatre directions. Il suffit de lui donner les noms des quatre actions d'entrée correspondant aux axes X et Y. Regardez à gauche, regardez à droite, regardez en haut et regardez en bas. Le dernier argument est une zone morte, qui est la longueur minimale du vecteur qui sera utilisé. Si le vecteur est trop court, nous pouvons l'ignorer, ce qui est utile pour les sticks analogiques qui ignorent la dérive. Cela ne posera aucun problème sur une manette puisque j'utilise le joystick analogique droit, mais commandes de mon PC utilisent les touches fléchées pour les mouvements et pour regarder. Donc, si la carte est ouverte, je mettrai le reste des commandes d' apparence et de mouvement dans un bloc pour les ignorer. Si vous souhaitez permettre au personnage du joueur de continuer à se déplacer et à regarder vers le haut ou vers le bas lorsque la carte est ouverte, vous devez modifier les actions de saisie afin qu'elles ne se chevauchent pas. Pour empêcher le personnage de continuer à se déplacer après avoir ouvert la carte, je mettrai sa direction de déplacement à zéro lorsque la carte sera ouverte. Le joueur peut désormais appuyer sur un bouton pour accéder à une carte du monde, affichant nos deux pièces et la position actuelle du joueur, et nous pouvons déplacer la caméra de la carte si nous le voulons. Dans la section suivante, nous allons commencer à suivre les statistiques du joueur et à les dessiner sur l'écran tête haute. Je vous verrai dans la section suivante. 36. 5-1 HUD: Bonjour, mes amis. Dans cette vidéo, nous allons commencer à afficher des informations sur le personnage du joueur sur l'écran tête haute. Depuis le début de ce cours, Godot 4.6 est sorti La mise à jour du projet vers Godot 4.6 n'a posé aucun problème, je vais donc continuer les leçons dans la version mise à jour Je ne recommande pas de passer à une version plus récente d'un moteur de jeu pendant que vous travaillez sur un projet, sauf si vous avez contrôle des versions pour revenir en arrière si nécessaire Je vais devoir importer des sprites d'interface utilisateur dans mon projet pour afficher les statistiques des personnages à l'écran Dans la scène du jeu, nous avons une couche de canevas qui est définie comme la première couche dans l'inspecteur. La fenêtre principale qui dessine le monde en deux D du jeu est considérée comme la couche zéro Ainsi, tous les éléments du monde en deux D du jeu seront dessinés sur la couche zéro, quel que soit leur indice z. La couche de toile, la première couche, dessinera par-dessus tout cela pour dessiner des éléments tels que des menus et la tête haute de nos personnages comme leur santé et leur magie. Les nœuds de la couche Canvas sont généralement des nœuds de contrôle Goy, qui ont tous des icônes vertes pour les distinguer des deux nœuds D qui sont bleus Commençons par ajouter un nœud de contrôle en tant qu'enfant de la couche Canvas, renommez-le en HUD, réorganisez-le pour qu'il figure en haut des enfants de la couche Canvas et faisons de la carte un enfant du Nous pouvons ensuite ajouter autant d'icônes, de jauges et de texte que nécessaire à ce nœud parent pour créer notre affichage tête haute Il est utile qu'un nœud de contrôle de base agisse en tant que parent de l'ensemble de votre HUD pour plusieurs raisons Certaines propriétés du nœud HUD parent seront héritées par tous les nœuds enfants Comme le nœud de la couche de canevas n'est pas un nœud de contrôle, il n'a pas les mêmes propriétés ne peut donc pas offrir cet avantage. Si vous souhaitez donner à tous vos éléments du HUD une apparence cohérente, vous pouvez ajouter un thème au nœud parent et il sera automatiquement appliqué à tous les nœuds enfants Cela permet également de conserver naturellement la transition de fondu en bas de l'arbre de scène, étant donné que vous n' ajouterez que des enfants au-dessus, vous n'aurez donc pas à vous soucier réorganiser l' arbre de scène à chaque fois Contrairement à deux nœuds D, qui utilisent leur propriété de position de transformation pour définir leur position par rapport à l'origine de la scène, nœuds de contrôle utilisent à la fois une position et une taille pour définir leur position dans un espace défini. Généralement, la fenêtre du jeu, qui s'affiche sous la forme de ce rectangle bleu. Nous pouvons voir que le nœud HUD a une taille de 40 x 40 pixels et se trouve à la position 00, qui est le coin supérieur gauche de la fenêtre Bien que nous puissions simplement déplacer et redimensionner le nœud de contrôle en modifiant ces valeurs, ces modifications ne seront pas adaptées ou ne fonctionneront efficacement si nous devions modifier la taille de la fenêtre dans les paramètres du projet Les nœuds de contrôle ont donc ces ancres vertes que nous pouvons utiliser pour définir la position et la taille de chaque nœud de contrôle par rapport à son parent, la couche de canevas représentant la fenêtre entière Nous voulons que le Hud couvre la totalité de la fenêtre afin de pouvoir régler son ancrage préréglé sur une panne complète. Cela place les ancrages à chacun des quatre coins de la fenêtre, puis met automatiquement à jour les valeurs de taille et de position en conséquence. Si nous rendons la carte visible, sa position n'a pas été mise à jour Je vais donc remettre ses ancres au centre Nous pouvons maintenant voir que, puisqu'il est ancré au centre de son parent, déplacement ou le redimensionnement du nœud HUD déplacera la carte pour qu'elle reste centrée Pour tirer parti de la santé et de la magie du personnage, je vais ajouter un nouveau nœud de contrôle pour regrouper ces éléments et les nommer vitaux. Je vais le laisser ancré en haut à gauche mais remettre sa taille à zéro. Ensuite, je vais ajouter un nœud détruit par une texture pour dessiner une texture simple, un profil du personnage, et renseigner sa propriété de texture en faisant glisser la ressource depuis l'onglet du système de fichiers En ajoutant un autre nœud détruit par de la texture, je vais nommer cette icône de santé et lui donner une texture d'atlas, en sélectionnant un sprite dans ma feuille de sprites J'en aurai besoin de plusieurs pour représenter la santé totale de mon personnage. Je vais donc le dupliquer plusieurs fois et les positionner approximativement dans l'ordre. Il serait judicieux de regrouper ces icônes sous un seul nœud parent. Je vais donc ajouter un autre nœud de contrôle nommé Health Counter et redéfinir toutes les icônes de santé pour qu'elles soient un enfant de ce nœud Positionner manuellement chacune de ces icônes est un peu pénible. Godot fournit donc des nœuds de contrôle appelés conteneurs pour le faire à notre place. Comme je souhaite que ces icônes soient disposées horizontalement, je vais changer le type du nœud parent pour qu'il soit un conteneur de boîtes horizontales. Cela organise automatiquement tous les nœuds enfants. Ils sont étirés pour remplir la hauteur verticale du conteneur horizontal, dont la taille par défaut est de 40 pixels. La réinitialisation de cette valeur la forcera à se réduire à la taille de l'enfant le plus grand J'aimerais qu'elles soient plus proches les unes des autres, donc sous le thème remplacements des constantes de section, je vais régler la séparation à moins huit pixels ajouter d'autres icônes à ce compteur , il suffit de dupliquer le nœud enfant C'est une bonne idée de disposer les éléments de votre HUD en tenant compte de leurs limites maximales J'aurai donc neuf icônes de santé, soit le maximum que je prévois d'inclure dans mon jeu. En sélectionnant l'un des nœuds enfants, leurs valeurs de position ne peuvent plus être modifiées manuellement, puisque le nœud conteneur est désormais chargé de contrôler leur position. Gardez donc cette limite à l'esprit. Si vous vouliez animer les positions de ces textures individuellement, vous ne pourriez pas le faire lorsqu' elles se trouvent dans un conteneur parent Ensuite, je vais ajouter un autre nœud endommagé par de la texture pour dessiner la jauge magique du personnage Renseignez ensuite sa propriété de texture avec la ressource depuis l'onglet du système de fichiers Bien que cette texture ne soit pas fonctionnelle en tant que jauge, elle permet de dessiner tout ce que vous souhaitez inclure sur votre capot pour avoir une idée de la façon dont vous souhaitez le disposer avant de passer à la mise en œuvre. Tout comme les icônes de santé, je veux voir comment cette jauge magique s'intégrera dans ma mise en page lorsqu'elle aura atteint sa limite maximale. étirement de cette image pour allonger la jauge étire les pixels individuels de l'image, ce qui n' étire les pixels individuels est pas satisfaisant. Nous en parlerons dans la prochaine vidéo, mais pour l'instant, nous avons juste besoin d'une idée de la taille de la jauge magique. Vous voudrez peut-être prendre le temps de mettre en page les éléments de votre cabane comme vous le souhaitez. Cette mise en page semble bonne. Mais lorsque je lance mon jeu, il est très petit et ne correspond pas à la densité de pixels du reste du jeu. Comme j'utilise un zoom de deux, taille de tous mes pixels est doublée. Je vais donc régler l'échelle de mon nœud vital à deux, doublant ainsi la taille de tous ses enfants C'est plus facile à lire et correspond mieux à l'esthétique de mon jeu. En modifiant les préréglages d'ancrage du nœud parent des signes vitaux, nous pouvons facilement le modifier pour définir sa position par rapport à n'importe quel coin de l'écran ou au centre d' Ou au centre de l' écran, comme la carte. Vous pouvez ensuite ajuster les positions des nœuds enfants par rapport au nœud parent ancré, et ils conserveront leur position relative même si vous décidez de modifier la résolution de votre jeu. Je vais garder le mien dans le coin supérieur gauche et lui donner 20 pixels de rembourrage à partir du bord de la fenêtre Nous avons maintenant quelques textures dessinées sur l'écran tête haute, mais elles ne font encore rien. Je vous verrai dans la prochaine vidéo. 37. Calibre 5-2: Bonjour, mes amis. Dans cette vidéo, nous allons implémenter la jauge magique à l'aide de boîtes de style. Commençons par changer le type du nœud de la jauge magique. Il existe un nœud de contrôle qui fait exactement ce dont nous avons besoin : une barre de progression. La modification du type entraîne la suppression de la texture. La barre de progression est dessinée sous la forme d'un rectangle gris semi-transparent et son pourcentage est affiché dans le texte. Je ne veux pas cette étiquette de pourcentage, je vais donc la désactiver dans l'inspecteur. Le bouton indéterminé ne s'applique pas à une jauge, mais est destiné aux barres de progression qui ne mesurent aucune progression. Après avoir défini les valeurs minimale et maximale de notre jauge magique, nous pouvons définir la valeur sur n'importe quel nombre intermédiaire pour voir la barre de progression se remplir. La valeur de l'étape est la plus petite que la valeur peut incrémenter, ce qui la force à passer à l'étape la plus proche Les autres propriétés héritées de la plage ne sont pas vraiment appropriées pour une jauge et peuvent être ignorées. Nous pouvons également modifier la direction dans laquelle la barre de progression sera remplie si nous le souhaitons. Je vais laisser le mien du début à la fin. L'apparence de la barre de progression dépend du thème. Comme nous n'avons pas encore de thème, il utilise le thème par défaut fourni par Godot Si nous voulons uniquement modifier le thème de ce nœud par lui-même, nous pouvons étendre la section des remplacements de thème Comme je n'utilise pas l'affichage du texte en pourcentage, les couleurs, les constantes, polices et les tailles de police ne sont pas pertinentes. Mais vous pouvez les utiliser pour modifier la façon dont la police est écrite sur votre barre de progression si vous le souhaitez. Dans la section des styles, vous trouverez les boîtes de style indiquant comment l' arrière-plan et le remplissage des barres de progression sont dessinés. En cliquant sur le menu déroulant, nous pouvons sélectionner une boîte de style vide, qui ne dessinera simplement rien. Donnez du style à la ligne de boîte pour dessiner uniquement une ligne simple, boîte de style à plat pour dessiner un simple rectangle ou texture de la boîte de style pour utiliser une ressource de texture importée. En cliquant sur la texture de la boîte de style pour développer ses propriétés, nous pouvons renseigner la propriété de texture avec un actif depuis l'onglet du système de fichiers Si nous changeons la taille de la barre de progression, la texture sera étirée pour remplir l'espace, ce qui n'est pas très beau. Les boîtes de style ont davantage de propriétés pour modifier la façon dont l'image sera dessinée une fois étirée. Les marges de texture transformeront la texture en neuf tranches, découpant l'image deux fois horizontalement et deux fois verticalement, afin de la diviser en neuf segments Les coins ne seront pas étirés. Les bords seront étirés dans une seule direction pour relier les coins, et le milieu sera étiré dans les deux sens pour remplir le reste de l'espace. Ou nous pouvons désactiver le dessin du centre de la texture et ne dessiner que les bordures Si vous ne souhaitez pas que les segments individuels soient étirés, les propriétés d'étirement des axes permettent d' utiliser le tuilage à la place, ou l'option d'ajustement des carreaux utilisera une combinaison de tuilage et d'étirement pour s'adapter au mieux à l'espace alloué extension des marges dessinera la texture au-delà du rectangle défini par la position et la taille des nœuds. Une sous-région peut être utilisée pour dessiner une région d'une feuille de sprites Modulate fonctionne exactement comme il fait avec la visibilité de l' élément Canvas, en multipliant la couleur de chaque pixel par cette Les marges de contenu sont destinées boîtes de style utilisées pour dessiner les nœuds de conteneur Elles ne seront donc pas applicables ici. L'ajout d'une autre texture de boîte de style pour les barres de progression permet de les remplir et de les remplir avec la texture appropriée Si vous ne souhaitez pas saisir les valeurs des zones de texture manuellement, l' éditeur de sous-régions peut également être utilisé pour modifier visuellement les marges de texture. Grâce à ces actifs, la jauge magique n'est pas conçue pour être étirée verticalement. Je vais régler sa hauteur de manière à ce qu'elle soit la même que celle des actifs à 16 pixels. Mais en utilisant les boîtes de style, la jauge peut être étirée autant que nécessaire horizontalement, et elle sera dessinée sans étirer les pixels. La valeur peut également être modifiée et la texture de remplissage s'étirera également autant que nécessaire sans étirer les extrémités de la barre. Si nous voulions appliquer ces boîtes de style à plusieurs barres de progression, nous pouvons le rendre automatique en modifiant le thème plutôt que d' utiliser des remplacements de thème En sélectionnant le nœud HUD puis en élargissant la section du thème, nous pouvons créer un nouveau thème à partir de la liste déroulante. Cliquez sur la ressource du thème pour ouvrir le panneau du thème en bas de la fenêtre de l'éditeur. Ici, nous pouvons voir la plupart des nœuds de contrôle que Godot a à offrir et comment ils sont actuellement dessinés par le thème, y compris une barre de progression ici En cliquant sur le bouton Plus, nous pouvons ajouter une barre de progression à ce thème et modifier ses propriétés de la même manière que nous l'avons fait depuis l'inspecteur pour le nœud de la barre de progression Les mêmes propriétés de thème sont présentes pour les couleurs, les constantes, les polices, les tailles de police et les styles. Si nous cliquons sur les boutons plus à côté de l'arrière-plan et du remplissage, nous pouvons ajouter des boîtes de style à ce thème pour la barre de progression. Comme nous avons déjà créé ces boîtes de style, nous pouvons sélectionner le nœud de la barre de progression. Cliquez ensuite sur les ressources de la boîte de style et faites-les glisser de l'inspecteur vers l'éditeur de thème. La barre de progression dans l'aperçu du thème est mise à jour pour utiliser les boîtes de style. Désormais, chaque barre de progression héritant du nœud HUD héritera de ce thème et utilisera ces boîtes de style pour dessiner automatiquement la barre de progression Cela nous donne la possibilité de tous les nœuds de contrôle du même type de la même manière ou d'utiliser des remplacements de thème pour dessiner différemment les nœuds de contrôle individuels Nous pouvons supprimer les remplacements de thème nœud de la barre de progression puisque ces boîtes de style sont désormais héritées du thème HUDs. Si vous souhaitez utiliser ce thème pour l'ensemble de votre projet sans avoir à le copier dans chaque scène, vous pouvez l'enregistrer en tant que ressource du projet. Ensuite, dans les paramètres du projet, sous thème de l'interface graphique, nous pouvons définir un thème personnalisé en sélectionnant la ressource de thème enregistrée. Cela nécessitera le redémarrage de l'éditeur pour prendre effet. Désormais, toutes les barres de progression chaque scène de l' ensemble du projet seront dessinées de la même manière. Mais imaginons que vous souhaitiez avoir plusieurs jauges magiques utilisant ces boîtes de style et plusieurs autres barres de progression utilisant d'autres boîtes de style Plutôt que d'avoir plusieurs thèmes, nous pouvons utiliser des variations de types de thèmes. En cliquant sur le bouton Plus, nous pouvons taper un nom personnalisé à ajouter au thème, comme Magic Gauge. Cliquez ensuite sur le bouton Outils et donnez-lui un type de barre de progression de base en le tapant ou en le sélectionnant dans la liste. Les autres onglets contiennent maintenant les propriétés héritées de la barre de progression, et nous pouvons modifier les valeurs des cases de style de fond et de remplissage. Je vais copier les boîtes de style depuis mon nœud Magic Jauge, puis cliquer sur l'icône en forme de maillon les dissocier de l' endroit où elles ont été copiées En passant aux propriétés du thème de la barre de progression, je vais supprimer les boîtes de style , rétablissant ainsi le thème par défaut Sélectionnez ensuite le nœud Magic Jauge dans l'arbre de la scène, développez la section thématique dans l'inspecteur. Je peux sélectionner la jauge magique dans la variante de type pour leur dire d'utiliser les propriétés du thème pour la jauge magique. Maintenant, mon jeu peut avoir plusieurs jauges magiques si j'en ai besoin sans avoir à configurer les styles pour chacune d'elles individuellement. Il suffit de demander au thème d' utiliser les propriétés du thème de la jauge magique, et je peux toujours avoir d'autres barres de progression dans mon jeu qui ne sont pas des jauges magiques, qui peuvent également être dessinées en utilisant différents styles Nous disposons désormais d'une simple jauge magique, mais il nous reste encore à mettre en place le compteur sanitaire. Je vous verrai dans la prochaine vidéo. 38. Icône 5-3: Bonjour, mes amis. Dans cette vidéo, nous allons créer une icône de santé qui comporte des animations lorsque le personnage récupère ou perd de la santé Les icônes de santé sont actuellement affichées sous forme nœuds de texture détruits organisés horizontalement par le nœud contenant la boîte horizontale Si vous souhaitez les animer sous forme de sprites, vous pourriez penser à les transformer en nœuds Animated Sprite two D. Mais le mélange de nœuds de contrôle avec deux nœuds D pose des problèmes. Je vais rapidement configurer la ressource d'images Animation Sprite afin de pouvoir faire une démonstration Deux nœuds D ne se comporteront pas comme des nœuds de contrôle. Ils n'ancreront pas leurs positions par rapport à leurs parents, ne seront organisés par nœuds de conteneur ou redimensionnés automatiquement pour s'adapter à la résolution de la fenêtre Plutôt que de changer le type de nœud que nous utilisons, nous devrons animer ce nœud humide de texture tel quel Si nous développons la liste déroulante des propriétés de texture, nous pouvons voir qu'il existe une option de texture animée Cette ressource de texture animée ne peut contenir qu'une seule animation, déjà, elle ne correspond pas vraiment à nos besoins dans ce cas. Si nous voulions l'utiliser pour animer l'icône, nous devrions définir chaque image individuelle de l'animation sous la forme d' une texture d'atlas distincte d' une durée en secondes via cette interface maladroite Après tout cela, nous devrions utiliser un script personnalisé pour contrôler quelles images de l'animation sont utilisées de toute façon. Si nous voulions avoir la même texture, jouez plusieurs animations. Il serait donc préférable de laisser cette propriété de texture sous forme de texture d'atlas. Bien que nous puissions écrire un script personnalisé pour modifier la valeur de la propriété de région de cette texture d'atlas, le temps et les efforts nécessaires n'en vaudraient pas vraiment peine lorsque le nœud Animation Player existe déjà. Ajoutons donc simplement un nœud Animation Player en tant qu'enfant de cette icône de santé. Avant de faire des animations, il serait judicieux d'enregistrer d' abord cette icône en tant que scène. Cela encapsulera le nœud Animation Player, car il n'est pas vraiment pertinent par rapport au contexte du HUD du jeu Dans cette scène, je vais d'abord définir l'état par défaut de la région des icônes , qui sera vide. Créez ensuite une nouvelle animation lorsque cette icône se remplit, en réglant la fréquence d'images à 12 images par seconde, ajustant le zoom et en activant la capture d'images Je vais ensuite l'encadrer au début de l'animation et l'ajouter à la piste de réinitialisation. Même si je ne veux pas l'utiliser comme première image de l'animation, c'est maintenant l'état par défaut utilisé par l'animation de réinitialisation. Ensuite, je vais remplacer la première clé de mon animation de remplissage par la première image réelle Continuez ensuite avec le reste des cadres en remplissant l'icône. Je vais régler la durée de l' animation à huit images. N'oubliez pas de passer le mode de mise à jour en mode discret lorsque vous utilisez des animations d' images comme celle-ci. Ça a l'air bien, donc je vais le dupliquer et créer une autre animation lorsque le personnage subit des dégâts, ce qui videra l'icône. Comme je sais que les sprites de mes feuilles de sprites sont tous régulièrement espacés, je peux simplement modifier les valeurs des régions saisies par des multiples de 32 pixels pour obtenir les images Cette animation est plus courte , avec seulement six images. Il est important que ces animations se terminent par l'image qui sera persistante une fois qu'elles seront terminées. Une fois cette animation vide exécutée, l'icône restera vide jusqu'à ce que l' animation de remplissage soit lancée. De même, une fois l'animation de remplissage lancée, l'icône restera remplie jusqu'à ce que l'animation vide soit jouée. Joindre un script au nœud racine de l'icône de santé et l'enregistrer dans un nouveau dossier pour les scripts d'interface utilisateur. Nous supposerons que ce script peut être utilisé pour n'importe quelle icône animée au cas où nous voudrions l'utiliser pour autre chose que la santé. Ce script doit uniquement obtenir une référence au nœud Animation Player lorsqu'il est prêt. Proposez ensuite des fonctions publiques pour jouer chacune des animations en cas de besoin. De retour dans la scène du jeu, nous pouvons supprimer toutes les autres icônes de santé. Je vais renommer cette première icône en Health icon, puis la dupliquer huit fois pour recréer les autres avec le lecteur d' animation et le script joints Si nous voulons tester cela, nous pouvons utiliser le script du lecteur pour indiquer à l' icône de santé de se remplir ou de se vider en appuyant sur une touche Lorsque j'appuierai sur le bouton Exécuter, j'utiliserai le chemin du nœud annoté en signe de dollar pour indiquer à cette première icône de santé de se remplir Lorsque je relâcherai le bouton Exécuter, je ferai la même chose pour le vider. Comme ce n'est qu' à des fins de test, je n'ai pas besoin de me soucier de l'inefficacité de ce code Lancer le jeu, appuyer sur le bouton Exécuter, remplit toutes les icônes, même si je n'ai demandé qu'à la première de les remplir. En effet, Godot essaie naturellement d'utiliser le plus efficacement possible les ressources et n'a créé qu'une seule ressource de texture d'atlas à utiliser pour toutes les icônes Ainsi, lorsque nous animons une icône, toutes les icônes utilisent la même texture, elles sont donc toutes animées Dans la scène des icônes de santé, nous pouvons annuler ce comportement en développant la ressource de texture de l'atlas dans l'inspecteur Dans la section des ressources, activez l'option local vers la scène Cela indiquera à Godot que chaque instance de la scène aura besoin sa propre copie unique de cette ressource de texture d'atlas avec sa propre propriété de région Cette feuille de sprites sera toujours partagée par toutes les icônes, mais la région de la feuille de sprites qu'elles dessineront sera unique Lancer à nouveau le jeu. Cette fois, seule la première icône se remplit lorsque j'appuie sur le bouton d'exécution et se vide lorsque je relâche le bouton fois le test réussi, nous pouvons supprimer ou commenter les lignes de code supplémentaires. Nous avons maintenant des icônes de santé animées, mais le compteur de santé ne compte pas réellement la santé de notre personnage. Je vous verrai dans la prochaine vidéo. 39. Compteur 5-4: Bonjour, mes amis. Dans cette vidéo, nous allons écrire un script qui gère les icônes animées pour refléter une valeur et une valeur maximale. Nous avons nos icônes animées ici, mais nous devons joindre un script au nœud parent qui contrôlera comment et quand elles s'animeront afin refléter le décompte de la santé du personnage du joueur Je vais nommer ce compteur d'icônes et le placer dans le dossier des scripts de l' interface utilisateur. Rien dans ce script n' utilise spécifiquement les fonctionnalités du conteneur de boîtes horizontales Je vais donc étendre le type de contrôle plus générique pour permettre de modifier le type de ce nœud ultérieurement si je le souhaite. Le script aura besoin de deux nombres entiers, l'un pour la santé maximale du personnage et l'autre pour sa santé actuelle Comme je veux que ce script soit utile pour compter n'importe quoi, pas seulement la santé, j'utiliserai le terme générique valeur. Pour l'instant, nous pouvons définir la valeur par défaut de la santé maximale comme étant égale au nombre d'enfants de ce nœud à l'aide de la balise on ready. Ensuite, nous aurons besoin de deux fonctions publiques qui définiront ces deux valeurs, acceptant un paramètre entier et en remplaçant l'ancienne valeur par la nouvelle Lorsque le personnage de notre joueur subira des dégâts et retrouvera des points de vie, nous serons en mesure d'appeler ces fonctions publiques pour communiquer au joueur l' évolution de la valeur de ses points de vie. sera chargé de contrôler le Ce script sera chargé de contrôler le nombre d'icônes affichées et celles qui sont remplies ou vidées fonction des valeurs de ces entiers et de leur évolution Nous allons commencer par définir la valeur de leur état de santé actuel. La première chose à faire est de vérifier que le nombre nous est donné pour définir la valeur est un nombre valide. Nous ne pouvons pas afficher le personnage ayant une santé inférieure à zéro, ni aucune valeur supérieure au nombre d' icônes disponibles, c'est-à-dire à sa santé maximale. Nous allons donc d'abord définir la valeur sur le retour d'un entier de serrage compris entre zéro et la santé maximale. Si nous essayons d'appeler cette fonction avec un nombre négatif, elle mettra la santé à zéro. De même, tout ce qui dépasse le maximum sera plafonné au maximum Ensuite, si nous définissons la valeur sur le même nombre qu'elle est déjà, nous ne devrions rien avoir à faire, nous pouvons donc simplement revenir à cette fonction. Une fois que nous avons établi que nous changeons la valeur affichée par ce compteur d'icônes par un nouveau nombre valide, le processus sera différent si le nombre augmente ou diminue. Si la nouvelle valeur est supérieure à l'ancienne, nous indiquerons à certaines icônes de se remplir. Mais quelles icônes ? Les icônes sont facilement dessinées par le conteneur horizontal dans le même ordre que leur index enfant dans l'arbre de la scène. En utilisant une simple boucle à quatre boucles, en utilisant I comme indice, nous pouvons compter la plage de valeur jusqu'à la nouvelle valeur. Range renvoie un tableau contenant la séquence d'entiers allant du premier au second, mais exclut le second nombre Donc, si l'ancienne valeur était un et que la nouvelle valeur est quatre, cela nous donnera les chiffres un, deux et trois. Comme l'indice enfant du premier enfant est nul non un, cela correspond parfaitement aux index des icônes à remplir. Nous allons donc obtenir le nœud enfant à l'index I et lui dire de se remplir. Le processus de diminution de la valeur est très similaire. Ce n'est que puisque nous savons que la nouvelle valeur est inférieure à l'ancienne valeur que nous devons fournir un argument supplémentaire à la fonction de plage, négatif un, qui lui indiquera de faire le compte à rebours. Si l'ancienne valeur était quatre et la nouvelle valeur est un, range renverra 43 et deux. Ils ne sont pas identiques aux index enfants des icônes, mais ils sont supérieurs d'un. Nous pouvons donc résoudre ce problème en soustrayant un de I dans la fonction get child et en demandant à ces icônes n'est qu'une fois que tout cela est fait que nous définissons l'ancienne valeur sur la nouvelle valeur ? Nous pouvons tester cela sans ajouter scripts ou de mappages d'entrée supplémentaires Il suffit d'ajouter une fonction d'entrée au script. Nous allons d'abord vérifier si l'événement d'entrée était une touche d'événement d'entrée et si l'événement était une touche pressée. Utilisez ensuite une instruction match sur le code clé de l'événement. Si la touche qui a été pressée était l'une des touches numériques, nous pouvons définir la valeur du compteur d'icônes sur ce chiffre. déclarant une variable numérique sous forme d'entier, nous pouvons calculer le nombre sur lequel vous avez appuyé en soustrayant simplement la touche zéro du code clé des événements Cela fonctionne parce que les codes clés sont une énumération, une simple liste numérotée Quel que soit le code clé pour la touche zéro, le code clé pour la touche sept sera le code clé pour la touche zéro Nous pouvons imprimer une déclaration disant quelque chose comme set current health two plus le nombre converti en chaîne. Appelez ensuite la fonction de valeur définie en passant le numéro. Si nous lançons le jeu, appuyer sur n'importe quelle touche numérique mettra le compteur d'icônes à ce chiffre et animera les icônes selon qu'elles sont remplies ou vidées Et nous pouvons également faire la même chose pour définir la valeur maximale. Bien que nous puissions déjà avoir le maximum d'icônes dans la scène et simplement masquer celles que nous n'utilisons pas, il serait plus évolutif d' instancier de nouvelles icônes selon nos besoins Comme cela n' arrive pas très souvent, cela n'affectera pas les performances et permettra d'en ajouter autant que nécessaire si nous décidons de recruter le maximum plus tard. Nous allons donc exporter une variable pour conserver la scène d'icônes sous la forme d'une scène compressée. Copier le contenu de la fonction de valeur définie. Après avoir changé chaque instance de valeur en valeur maximale, il ne reste que quelques modifications à apporter. Tout d'abord, nous ne pouvons pas valider la valeur maximale en nous basant sur elle-même. Nous devrons donc fixer une limite à la valeur maximale possible. Vous souhaiterez peut-être exporter ce plafond plutôt que de coder une valeur en dur. Au lieu de remplir des icônes, nous instancierons de nouvelles icônes et les ajouterons en tant qu'enfants. Et au lieu de vider les icônes, nous les supprimerons de l'arborescence des scènes en appelant gratuitement Pour tester cela, je vais utiliser le même système de saisie numérique, mais je dois maintenir la flèche vers le haut enfoncée mais je dois maintenir la flèche vers pour définir la valeur maximale. Donc, si vous appuyez sur l'action du point de saisie, recherchez, puis j'imprimerai Max Health, je définirai cette valeur place et mettrai la partie santé actuelle dans le bloc else. cours de jeu, je peux modifier En cours de jeu, je peux modifier la valeur maximale de santé en maintenant la flèche vers le haut enfoncée, en appuyant sur l'une des touches numériques et en relâchant la flèche vers le haut . Je peux également modifier la valeur actuelle de santé. N'oubliez pas de commenter la fonction de saisie après le test. Nous avons maintenant un compteur d' icônes animé qui permet de suivre les valeurs de santé maximales et actuelles des personnages du joueur . Mais ni le compteur d' icônes de santé ni la jauge magique ne sont réellement liés au personnage du joueur. Je vous verrai dans la prochaine vidéo. 40. Boîte à 5-5 dommages: Bonjour, mes amis. Dans cette vidéo, nous allons donner au personnage un peu de santé pour qu'il puisse se connecter au compteur d'icônes de santé. Nous pourrions ajouter des variables de santé au script du personnage et le suivre de cette façon. Cela permettrait à chaque personnage de notre jeu d'avoir de la santé sans aucun travail supplémentaire. Mais si nous considérons que des objets qui ne sont pas des personnages peuvent également avoir besoin de santé, comme des murs cassables, par exemple, cela devient moins bénéfique, autant plus que notre personnage est un corps de personnage deux D et que le mur cassable serait un corps statique deux D. Et peut-être que nous avons un autre corps rigide en D qui a également besoin Nous aurions besoin des mêmes variables et fonctions dans plusieurs scripts pour chacun de ces cas. Nous pourrions réécrire le script de notre personnage pour hériter de Physics Body Two D. Tout ce qui a besoin de santé dans notre jeu peut également utiliser ce Mais il y a beaucoup de choses dans ce script qui ne seraient pas applicables à ces autres objets. Ce serait du gaspillage d'avoir toutes ces variables et fonctions attachées à un mur cassable qui n'aurait jamais besoin de les utiliser et, de même, d' avoir les variables et les fonctions destinées un mur cassable attachées à Dans de tels cas, vous pouvez utiliser le modèle composite plutôt que l' héritage orienté objet pour réutiliser vos scripts dans l'ensemble de votre projet de jeu. En créant un composant de santé, celui-ci peut exister indépendamment de ce à quoi il est attaché. Les personnages peuvent avoir une composante santé et les murs cassables peuvent également avoir une composante santé Dans la scène des personnages, nous allons ajouter un nouvel enfant, un nœud en zone 2 D, et le nommer Hurt Box. Ajoutez ensuite un nœud TD en forme de collision en tant qu'enfant de la Hurt Box pour définir sa forme. Ce sera la zone aérienne où le personnage subira des dégâts s'il est touché. Il se peut que vous ne souhaitiez pas toujours que cette forme soit identique à celle du corps de leur personnage en cas de collision. De plus, vous voudrez généralement que la collision entre les corps du personnage reste active, tandis que la zone de blessures sera souvent désactivée pour empêcher le personnage de subir des dégâts en esquivant ou pendant les cinématiques, par Il est donc utile de donner à votre Hurt Box une zone de collision distincte. Je vais également faire de la mienne une capsule, mais légèrement plus petite que le corps du personnage et définir sa couleur de débogage sur le vert pour pouvoir les distinguer plus facilement Cette zone n'a pas besoin d'être chargée de surveiller quoi que ce soit. Il suffit d'être surveillable pour hitboxes puissent le détecter élargissant la section collision sous l'objet de collision deux D, nous pouvons la définir pour qu'elle se trouve sur la couche dix et supprimer complètement son masque. Dans les paramètres du projet, je vais donner à deux couches de D Physics le nom du joueur Hurt Box. Désormais, tout ce qui surveille et masque la couche dix dans le jeu masque la couche dix dans le peut blesser le personnage du joueur En attachant un script à ce nœud, je le nommerai Hurt Box. Ce script aura besoin des mêmes valeurs de santé maximale et de santé actuelles que celles du compteur d'icônes. Comme je vais indiquer la valeur de santé à l'aide d'icônes, celles-ci devront être des entiers Si vous utilisez une jauge pour la santé de votre personnage, vous avez la possibilité d' utiliser des flottants à la place car une jauge peut indiquer des valeurs décimales Pour l'instant, je vais simplement définir la santé maximale à cinq et utiliser le tag On Ready pour définir la santé actuelle sur Max Health. Contrairement au script de compteur d'icônes, le principal moyen par lequel une boîte à blessures modifiera la valeur de ses points de vie actuels sera de subir des dégâts en cas de frappe ou de récupérer de la santé. Ce seront donc nos fonctions publiques, qui accepteront toutes deux un nombre entier de points de santé à perdre ou à gagner. Lorsque vous subissez des dégâts, nous en déduisons simplement le montant de la santé actuelle du personnage Nous pouvons ensuite utiliser la fonction max pour renvoyer cette valeur ou zéro, selon la valeur la plus élevée, et définir comme nouvelle valeur de l'état de santé actuel. Cela empêchera leur santé de descendre en dessous de zéro. Nous pouvons rendre la fonction de restauration multi-usage en donnant au paramètre une valeur par défaut. Si nous appelons cette fonction de restauration sans argument, nous supposerons que cela signifie qu' ils doivent récupérer toute leur santé jusqu'à leur maximum, en réglant leur santé actuelle à leur santé maximale. Si un argument a été attribué à la fonction de restauration, ajoutez ce montant à la santé actuelle du personnage et utilisez la fonction MIN pour renvoyer ce résultat ou la santé maximale, selon la valeur la plus faible. La santé actuelle ne dépassera donc jamais la santé maximale. les deux cas, la valeur de l'état de santé actuel est modifiée et nous avons besoin que ce changement soit reflété dans le compteur d'icônes sur le HUD Mais la Hurt Box se trouve dans la scène du personnage et le compteur d'icônes dans la scène du jeu. Dans la plupart des cas, chaque fois que vous devez communiquer des informations entre des nœuds et différentes scènes, le meilleur moyen consiste à utiliser des signaux et établir leur connexion via leur ancêtre commun le plus proche. Dans la scène de jeu, l'ancêtre commun le plus proche entre le personnage et le compteur de points de vie est le nœud racine de la scène de jeu , le gestionnaire de jeu. Donnons un nom unique au compteur de santé. Ensuite, saisissez-en une référence dans le script du gestionnaire de jeu. Nous pourrions essayer de demander au compteur de santé de surveiller la boîte à blessures du personnage. Nous pouvons utiliser la fonction Get node pour récupérer la boîte à blessures du personnage. Mais alors, notre script de compteur d'icônes s' appuiera sur certaines fonctions ou variables existant dans l'entité qu'il surveille. Il ne serait donc essentiellement utile que comme compteur de santé, qui n'est pas réutilisable en tant que script pour compter d'autres choses. Inversant cette logique, il serait préférable de demander à la Hurt Box d'être surveillée par ce compteur d'icônes Appelez ensuite une fonction que nous n'avons pas encore écrite, comme set counter, et passez-lui le compteur de santé en argument. N'oubliez pas que cette fonction get node échouera si vous modifiez le nom de votre nœud Hurt Box ou si vous réorganisez la structure de votre arborescence de scènes afin qu'il ne soit plus un enfant direct Je préfère cette dépendance à l' écriture d'une nouvelle fonction dans le script de personnage pour récupérer le nœud Hurt Box, car ce script est déjà assez long. De retour dans le script Hurt Box, nous allons écrire cette nouvelle fonction acceptant un compteur d'icônes comme paramètre de contrôle de type, puisque nous ne lui avons pas donné de nom de classe spécifique. Maintenant, nous avons la Hurt Box et le compteur de points de vie dans le même script, ce qui nous permet de communiquer facilement entre eux. Plus important encore, le script du compteur d' icônes peut toujours être utilisé pour tout ce que nous voulons, et toute Hurt Box de notre jeu qui n'a pas besoin d'être surveillée par un compteur peut simplement ignorer cette fonction. Nous pourrions appeler les compteurs d'icônes des fonctions directement, mais cela obligerait chaque Hurt Box du jeu à vérifier en permanence si un compteur d'icônes surveille avant d' appeler ces fonctions Il serait préférable d'utiliser des signaux pour communiquer ces changements, l'un pour le moment où l'état de santé maximal change et l'autre pour le moment où l'état de santé actuel change. Les deux auront besoin de paramètres entiers pour leurs nouvelles valeurs. Nous pouvons également en vouloir un autre lorsque la santé atteint zéro, ce qui ne nécessitera aucun paramètre. Désormais, lorsque leur état de santé actuel change la suite de dommages subis ou d' une restauration de leur santé, nous pouvons émettre ce signal en utilisant leur nouvelle santé actuelle comme argument. Si la santé actuelle est nulle après avoir subi des dégâts, nous devrions émettre le signal teint deux Maintenant, lorsque nous configurons un compteur pour surveiller cette Hurt Box, nous pouvons simplement connecter ces signaux aux fonctions de valeur définie du compteur d'icônes, car les paramètres transmis par les signaux correspondent aux paramètres des fonctions du compteur d'icônes en termes de quantité et Il serait également judicieux d'émettre ces signaux immédiatement afin que le compteur d'icônes puisse régler ses valeurs en fonction de celles de la Hurt Box. Pour tester cela, nous pouvons écrire une fonction de saisie simple dans ce script. Si j'appuie dessus, le personnage récupérera une santé. Si j'appuie dessus, le personnage subira un point de dégâts, et si je saute, il retrouvera toute sa santé. cours de jeu, appuyez sur le bouton enfoncé pour infliger un dommage au personnage à chaque fois que vous appuyez sur un bouton. Les dégâts infligés à zéro point de vie ne sont pas pris en compte. Appuyer vers le haut permet de récupérer un point de vie, et le rétablissement de santé chez Max est ignoré. En redescendant d'abord à une valeur inférieure, je vais ensuite sauter et récupérer complètement tous mes points de vie. N'oubliez pas de supprimer ou de commenter cette fonction de saisie après le test. Notre personnage est désormais capable de subir des dégâts et de récupérer de la santé, mais sa santé n'est pas sauvegardée. Je vous verrai dans la prochaine vidéo. 41. 5-6 Données: Bonjour, mes amis. Dans cette vidéo, nous allons créer une ressource personnalisée qui permet de suivre les statistiques du joueur et sa progression dans le jeu entre les sessions de jeu. Si nous voulons que le joueur puisse obtenir un maximum d'améliorations de santé, conservez ces améliorations la prochaine fois qu'il jouera. Le jeu aura besoin d'un moyen de savoir ce qu'ils ont trouvé et ce qu'ils n'ont pas trouvé dans le jeu. Pour ce faire, nous pouvons créer nos propres ressources. Nous avons déjà utilisé plusieurs ressources dans ce projet, comme la ressource Sprites Atlas Texture du personnage ou la ressource Animation Tree state machine Et le thème. Ces ressources sont toutes de types définis par le moteur de jeu Godot pour fournir des fonctions spécifiques aux nœuds qui les utilisent. Mais nous pouvons également créer le nôtre pour répondre à nos besoins spécifiques. Créons un nouveau dossier dans le dossier nommé resources. Nous pouvons ensuite créer un nouveau script dans ce dossier nommé data plutôt que d' hériter du nœud, ce script héritera de Les ressources ne sont pas représentées sous forme de nœuds dans l'arborescence des scènes. La première chose que nous voulons faire lors de la création d'une ressource personnalisée est de nous assurer de lui donner un nom de classe. Sinon, nous ne serons pas en mesure d'en créer des instances. Comme le but de cette ressource est de suivre les données du joueur, nous pouvons inclure autant de variables que nécessaire pour tout ce que nous voulons enregistrer entre les sessions de jeu. Pour l'instant, j'ai besoin de variables pour la santé maximale et la santé actuelle des personnages sous forme de nombres entiers J'ajouterai également leur magie maximale et leur magie actuelle sous forme de chars. Toutes ces variables seront accessibles publiquement aux autres scripts. Nous pouvons également inclure des chaînes pour des éléments tels que leur nom ou des booléens pour suivre l'activation ou la désactivation d'un élément Les tableaux peuvent être utilisés pour stocker des groupes d'informations connexes, comme un tableau de booléens permettant de savoir quelles améliorations ont été trouvées par le joueur et lesquelles ne quelles améliorations ont été trouvées par le joueur et lesquelles l' dictionnaires sont très utiles pour stocker des classes entières d'informations, car nous pouvons utiliser des noms d' attributs comme clés du dictionnaire avec leurs valeurs correspondantes Au-delà des types de variables de base, nous pouvons également inclure d'autres classes intégrées Godot, comme des vecteurs pour stocker deux coordonnées D, des couleurs ou même d'autres classes personnalisées que nous créons Toute variable que vous souhaitez enregistrer entre les sessions de jeu devra avoir la balise d'exportation. D'autres variables qui n'ont pas la balise d'exportation peuvent tout de même être utiles si, par exemple, vous ne souhaitez pas enregistrer la santé actuelle du personnage, mais uniquement sa santé maximale, et repartir avec une santé complète du joueur à chaque fois qu'il charge sa partie. Ces variables non exportées seront toutefois conservées si votre jeu change si votre jeu change de scène pendant la session de jeu. Si vous deviez quitter la scène de jeu pour une raison quelconque, pour jouer à une scène coupée, puis revenir à la scène de jeu une fois de plus, ces variables conserveront leur valeur. Bien que nous puissions également écrire des fonctions dans ce script, cela n'est généralement pas nécessaire. Si vous souhaitez effectuer une initialisation automatique de votre ressource, nous pouvons remplacer la fonction d'initialisation Cette fonction innit sera appelée automatiquement par Godot chaque fois que nous créerons une nouvelle instance de cette ressource via un script Nous pouvons donc donner aux variables des valeurs par défaut, définir la longueur des tableaux ou ajouter des clés à nos dictionnaires Assurez-vous d'enregistrer ce script avec le nom de classe défini avant d'essayer de l'utiliser de quelque manière que ce soit. Godot reconnaîtra donc ce nom de classe. Nous aurons besoin d'un autre script pour accéder à notre ressource personnalisée, que nous aborderons dans la prochaine vidéo. Pour l'instant, nous pouvons tester notre ressource personnalisée en en créant une dans l'onglet du système de fichiers. Nous cliquons, sélectionnons Créer une nouvelle ressource, puis tapons le nom de la classe ou sélectionnons-le dans la liste. Donnez-lui ensuite un nom. En créant cette ressource nous l'ouvrirons automatiquement dans l'inspecteur, où nous pourrons voir et modifier toutes nos variables exportées. La création d'une ressource de cette manière n'utilise pas la fonction nit, mais utilise les valeurs fournies pour les variables assignées dans leurs déclarations. Si vous sélectionnez autre chose et souhaitez recommencer à modifier cette ressource, vous pouvez double-cliquer dessus dans l'onglet du système de fichiers. Je vais rapidement tester la création d'une ressource de données dans le script du gestionnaire de jeu. Nous pouvons créer une instance de notre ressource en déclarant d'abord une variable dont le type est le nom de classe. Attribuez ensuite à cette variable le nom de classe suivi du point Nu. Nous pouvons ensuite accéder à toutes les variables déclarées dans cette classe, qu'elles soient exportées ou non, remplacer leurs valeurs et les utiliser selon les besoins pendant le jeu N'oubliez pas de supprimer ou de commenter ce code de test et de supprimer le fichier de ressources de données de test. Nous avons maintenant une ressource de données qui inclut la santé maximale et la santé actuelle de nos personnages, mais elle n'est pas encore enregistrée. Je vous verrai dans la prochaine vidéo. 42. Fichier 5-7: Bonjour, mes amis. Dans cette vidéo, nous allons enregistrer et charger les données du joueur à l'aide de notre nouvelle ressource personnalisée. Pour ce faire, nous avons besoin d' un autre script qui gère accès à la ressource que nous avons créée dans la vidéo précédente. Ce script devra être accessible de n'importe où dans le projet. Le personnage doit connaître ses statistiques. Les salles devront savoir si le joueur a ouvert une porte, trouvé une amélioration ou vaincu un boss. Même l'interface utilisateur et la carte devront accéder aux données sauvegardées. Nous pouvons rendre certains nœuds facilement accessibles de cette manière en les rendant globaux. Créons un nouveau dossier dans le dossier des scripts nommé Globals. Créez ensuite un nouveau script dans ce dossier nommé file. Le but de ce script sera fournir un accès rapide et facile aux données de sauvegarde des joueurs tous les autres scripts que nous écrivons tout au long du projet, ainsi que de les enregistrer sur le système du joueur et de les charger également. Nous aurons besoin d'une variable du type de notre ressource personnalisée. Je vais les nommer données en minuscules D. Nous aurons alors besoin trois fonctions publiques pour gérer ces données, démarrer une nouvelle partie, sauvegarder la partie et charger le jeu et charger le Démarrer une nouvelle partie est simple. Il suffit de définir la valeur des données comme étant le nom de notre classe suivi du point neu. Cela créera une nouvelle instance de la ressource et l'initialisera Lorsque nous serons prêts à enregistrer notre jeu, nous devrons également savoir où nous voulons le sauvegarder. Pour cela, je vais déclarer une constante de chaîne, puisque je ne changerai jamais cela, le chemin d'accès à l'emplacement où je souhaite enregistrer le fichier de données du joueur. Godot fournit un raccourci simple qui fonctionne sur Windows, Mac, Linux, le Web et les consoles peuvent tous l'utiliser. L'utilisateur Colon fait suivre la barre oblique. Do le remplacera automatiquement par le chemin approprié à la plateforme, en tant qu' emplacement spécifique à la fois à l'utilisateur du système et au jeu. déclarant également une variable pour le nom de fichier sous forme de chaîne, je nommerai la mienne save suivi d'un je nommerai la mienne save suivi point TRS, abréviation de ressource texte. Maintenant, pour sauvegarder le jeu, nous pouvons accéder à une classe Singleton du Godot, Resource Saver, appelée alors fonction de En transmettant la ressource que nous voulons enregistrer et l'emplacement dans lequel nous voulons l' enregistrer en ajoutant le chemin et le nom du fichier Si nous voulions avoir plusieurs emplacements de sauvegarde, il nous suffit de changer le nom de fichier pour chaque emplacement. Le chargement de notre jeu est similaire à la sauvegarde. Tout ce que nous avons à faire est d'utiliser le chargeur Godot Singleton. La fonction de chargement nécessite uniquement l'emplacement de la ressource que nous chargeons. Et il renvoie la ressource. Nous allons donc l'attribuer à notre variable de données. Comme notre jeu n'a pas de scène de titre, je suppose automatiquement que si un fichier de sauvegarde existe, je souhaiterai le charger ou s' il ne permet pas de démarrer un nouveau jeu. Donc, dans la fonction REDI, j'utiliserai le chargeur de ressources pour vérifier s'il existe un fichier de données à charger, et si c'est le cas, pour le charger. Sinon, lancez une nouvelle partie. Même avec une scène de titre, il est utile de pouvoir démarrer votre jeu directement depuis la scène de jeu sans avoir à passer par l'écran titre chaque fois que vous développez et testez. Nous avons notre ressource de données ici. Nous pouvons le créer, le sauvegarder et le charger. ne nous reste plus qu'à rendre ce script facilement accessible depuis n'importe où dans notre projet. Ouvrez les paramètres du projet, passez à l'onglet Globals. Cliquez sur le bouton du dossier pour ouvrir un navigateur et accéder au script de fichier que nous venons de créer. Cliquez ensuite sur Ouvrir. Nous pouvons donner un nom différent à ce nœud global si nous le voulons ou utiliser celui fourni. Cliquez ensuite sur Ajouter pour ajouter le script à la liste des nœuds globaux. Désormais, tout script que nous écrivons peut accéder à ce script de fichier uniquement avec son nom. la même manière, nous avons utilisé les singletons d'entrée, d' économiseur de ressources et de chargeur de ressources Pour tester cela, je vais régler la santé maximale du personnage pour qu'elle corresponde à celle qui se trouve dans le coffre-fort plutôt que le coffre-fort plutôt que de la définir en haut du script Je vais donc ajouter une fonction initialisée à ce script après avoir accepté un nouveau paramètre de valeur maximale, en réglant l'ancienne valeur maximale sur la nouvelle valeur maximale Ensuite, de la valeur actuelle à la valeur maximale, j'émettrai les deux signaux modifiés. Après avoir obtenu la boîte à blessures du personnage, le responsable du jeu peut désormais boîte à blessures du personnage, le responsable du l'initialiser avec la valeur de santé maximale indiquée dans le fichier de données du joueur J'ajouterai également une fonction de saisie qui, lorsque vous appuyez sur les touches fléchées haut ou bas augmentera ou diminuera la santé maximale du personnage dans le fichier de données et réinitialisera la Hurt Box en conséquence. Enregistrez ensuite le jeu en appelant file point save game. Je vais devoir inverser l'ordre de ces opérations pour afficher les bonnes valeurs. cours de jeu, le personnage commence avec cinq points de vie maximum, mais je peux modifier cette valeur en appuyant sur les flèches haut ou bas. Je fermerai ensuite le jeu et je le relancerai pour vérifier que leur santé maximale a été enregistrée et chargée. Pour trouver le fichier de données que nous avons enregistré dans le menu du projet, sélectionnez Ouvrir le dossier de données utilisateur. Cela ouvrira une fenêtre de navigateur de fichiers, et nous pourrons voir notre fichier de sauvegarde DotTRS Cliquez avec le bouton droit sur ce fichier et ouvrez-le à l'aide de n'importe quel éditeur de texte. Nous pouvons voir que seule la santé maximale a été sauvée. Godot garde une trace des variables utilisées par le jeu et ne sauvegardera que les variables que nous utilisons et modifions réellement Gardez donc cela à l'esprit. Nous pouvons réellement modifier ce fichier ici, et le jeu le chargera avec les valeurs modifiées tant que le formatage correspond. C'est formidable pour nous pendant que nous développons et testons notre jeu. Mais vous ne voulez peut-être pas permettre à vos joueurs modifier facilement leur fichier sécurisé lorsque vous serez prêt à le publier. Dans le script de fichier, remplacez simplement l'extension TRS dans le nom du fichier par point RES. Au lieu d'une ressource texte, celle-ci sera désormais enregistrée sous forme de ressource binaire, qui ne peut pas être ouverte ni modifiée dans un éditeur de texte. En relançant le jeu, je vais ouvrir le fichier de sauvegarde que je viens de créer. Il m'est désormais impossible de le modifier. Nous avons désormais la possibilité de sauvegarder et de charger des données relatives à la progression du joueur dans notre jeu. Dans la section suivante, nous ajouterons nos capacités à débloquer Je vous verrai dans la section suivante. 43. Double saut 6-1: Bonjour, mes amis. Dans cette vidéo, nous allons donner à notre personnage la possibilité de faire un double saut. Alors que de nombreux personnages de notre jeu peuvent avoir besoin la capacité de marcher, de courir, de sauter et de tomber, les capacités à débloquer sont généralement exclusives au personnage du joueur Dans le script du personnage, plutôt que d' ajouter des variables et des fonctions à ce script, qui est déjà assez long, nous pouvons créer un nouveau script qui ne sera utilisé que par le personnage du joueur. Assurez-vous que le script de votre personnage porte un nom de classe et qu'il est enregistré avant de continuer. la scène du personnage, cliquez avec le bouton droit sur le nœud racine du personnage et sélectionnez Joindre un script. Plutôt que d'hériter de CharacterBody two D, nous pouvons hériter du nom de classe de notre personnage nous pouvons hériter du nom de classe de script original Donnez ensuite un nom à ce nouveau script et enregistrez-le dans le dossier approprié. Comme ce nouveau script hérite du caractère, il a accès aux mêmes variables et fonctions que celles que nous avons créées pour cette classe, et toutes les valeurs des variables exportées et des connexions de signal sont également copiées dans ce nouveau script Mais nous pouvons désormais en ajouter d'autres qui ne sont utiles qu' au personnage du joueur. Selon ce modèle d'héritage, personnage est appelé la superclasse et le personnage de notre joueur est une sous-classe abord, nous aurons besoin d'une variable qui nous indique si ce personnage a débloqué la capacité de faire un double saut Et afin de limiter le double saut au personnage à une seule fois, nous aurons besoin d'une autre variable pour savoir si son double saut est prêt. Il peut également être utile d'avoir un signal à émettre lorsque nous effectuons un double saut avec succès pour créer un effet de particules si vous le souhaitez, comme nous l'avons fait pour l'autre saut. Comme le double saut utilise généralement le même bouton que le saut normal, nous n'avons pas besoin de travailler davantage sur la carte d'entrée dans les paramètres du projet ni de modifier le script du joueur pour appeler de nouvelles fonctions. Nous pouvons simplement annuler la déclaration de la fonction Jump. Lorsque vous remplacez une déclaration de fonction, la signature de la fonction doit rester la même Le nom de la fonction, ses paramètres, quantité, son ordre et ses types, ainsi que le type de retour. Étant donné que la fonction de saut originale du script de caractères n'acceptait aucun paramètre et renvoyait une valeur booléenne, cette dérogation de saut ne doit pas non plus comporter de paramètres et renvoyer Nous voulons toujours que toutes les fonctionnalités d'origine du saut soient maintenues. Ce personnage pourra donc sauter si les bonnes conditions sont réunies. Nous pouvons accéder aux fonctions de superclasse l'aide du mot-clé super, puis utiliser un point, le nom de la fonction et parenthèses comme nous appellerions une fonction de toute autre manière Comme la fonction de saut de superclasse renvoie un booléen, nous pouvons également renvoyer le résultat pour satisfaire à l' exigence de renvoyer Lorsque le joueur appuie sur le bouton de saut, le script du joueur appelle fonction de saut de personnage de ce joueur, qui appelle ensuite la fonction de saut de personnage plus générique. Cette structure nous permet d'intercepter le processus en ajoutant du code supplémentaire au-dessus de la ligne de retour, ce qui nous permet de vérifier si le personnage du joueur peut d'abord faire un double saut en réponse à la demande de saut, puis ne poursuivre qu'avec le comportement de saut par défaut par la suite Donc, si le personnage de ce joueur peut double saut, que le double saut est prêt et que le personnage n'est pas au sol, nous devrions l' autoriser à effectuer un double saut et revenir à la réalité. Si l'une de ces conditions est fausse, nous devons vérifier si ce personnage peut sauter dans conditions normales à l'aide la fonction de saut de superclasse de personnage Nous pouvons à peu près simplement copier les lignes de code qui implémentent un saut lors d'un double saut, mais qui émettent un signal différent. Et nous devrons définir la variable « double saut est prêt chutes » pour empêcher le personnage du joueur d'effectuer plus d'un double saut. Dans la plupart des jeux avec un double saut, la capacité d'effectuer le double saut est rétablie après l' atterrissage au sol. Comme la classe de personnage possède déjà une fonction qui sera appelée lorsque le personnage apparaîtra, nous pouvons également la remplacer Chaque fois que ce personnage atterrit, si son double saut n'est pas prêt, nous pouvons remettre la variable sur true pour qu'elle soit prête. Appelez ensuite la fonction de superclasse. Dans ce cas, l'ordre dans lequel nous voulons exécuter la fonction de superclasse avant ou après n'aura pas d'importance Pour tester cela, j'ajouterai une instruction d'impression lorsque le personnage saute deux fois avec succès Et une autre lorsque le double saut est rétabli. Définissez ensuite la valeur par défaut de C double jump sur true. En cours de jeu, nous pouvons appuyer deux fois sur le bouton de saut pour faire un double saut. Appuyez dessus trois fois ou plus pour ne pas produire plus de sauts et la capacité de double saut est rétablie lors de l'atterrissage ne nous reste plus qu'à verrouiller et déverrouiller cette capacité de double saut. Je vais donc remettre la valeur par défaut du double saut en C sur false. Dans les données de sauvegarde du joueur, je vais supprimer toutes ces variables inutiles. Nous aurons besoin de variables pour savoir quelles capacités le joueur a débloquées, que nous pouvons stocker dans un tableau de booléens Les tableaux sont indexés à l'aide d'entiers, nous aurons besoin que chacune de nos capacités se voie attribuer un numéro en séquence, en commençant par zéro en comptant jusqu' attribuer un numéro en séquence, en commençant par zéro en comptant jusqu' à ce qu'il serve d' indice pour ce Si vous ne voulez pas mémoriser un ensemble d'entiers, nous pouvons créer une énumération pour donner à chaque entier un nom plus facile à utiliser J'aime mettre ces énumérations dans un script distinct nommé Bien que Godot nous oblige à hériter d'une classe existante lors de la création du script, nous pouvons supprimer cette ligne de notre script une fois celui-ci Donnez ensuite un nom de classe à ce script afin que nous puissions le référencer dans d'autres scripts. J'utilise généralement le même script pour contenir toutes les énumérations de l'ensemble du projet Nous pouvons déclarer une énumération en utilisant le mot clé num, suivi d'accolades À l'intérieur des accolades, nous pouvons écrire le nom de chacune de nos capacités dans une liste séparée par des virgules J'ai déjà créé un double saut comme première capacité à débloquer, et je vais créer un saut mural, un tableau de bord, un chapeau et tirer un énumérations sont classiquement nommées en cas de Pascal, tandis que les entrées d' énumération sont en L'énumération attribuera la valeur de la première entrée à zéro, puis à un, deux, etc., ce qui signifie que nous pouvons les utiliser assez facilement comme indices pour notre tableau Ils n'ont pas besoin d'être dans l'ordre dans lequel ils seront débloqués par le joueur L'ordre est arbitraire et sert uniquement à attribuer un numéro unique à chaque capacité. Lors de l'initialisation des données de sauvegarde du joueur, nous pouvons redimensionner le tableau pour qu'il corresponde à la taille de l'énumération, nous donnant automatiquement le nombre correct de booléens et en les attribuant par défaut à tous la booléens et en les attribuant par défaut N'oubliez pas que les variables doivent avoir la balise d'exportation pour être enregistrées. De retour dans le script du joueur, nous pouvons référencer le tableau des capacités débloquées et le stocker dans une variable du même nom en utilisant le tag on ready Notez que cela ne fait pas simplement une copie du tableau dans son état actuel. Cela crée une référence au tableau, sorte que toute modification affectera les deux. Cela signifie que pour débloquer une capacité que le personnage peut utiliser, il suffit de définir sa valeur dans la ressource de données de sauvegarde. Nous pouvons désormais remplacer la variable C double jump en indexant le tableau des capacités débloquées par le Enums, les capacités et le point Ce tableau de capacités débloquées peut désormais être utilisé dans l'ensemble de ce script pour chaque capacité Dans le script du gestionnaire de jeu, j'utiliserai la fonction de saisie pour tester le déverrouillage de la capacité de double saut en appuyant sur la flèche vers le haut Configuration des points de données du fichier : points, points, capacités, points, points, capacités, points , points, capacités, points, capacités, points, capacités, points, double saut sur true Nous pouvons ensuite sauvegarder le jeu pour le rendre permanent. En cours de jeu, mon personnage ne peut pas faire de double saut. De retour dans l'éditeur Godot, je vais passer à l'onglet Remote pour voir l'arborescence des scènes du jeu en cours d'exécution Ici, je peux voir le nœud global du fichier, qui possède une ressource de données. Dans cette ressource de données, le tableau des capacités débloquées contient cinq booléens, qui sont Le nœud du personnage du joueur contient également une référence au même tableau. Pour revenir à la simulation, appuyer sur le bouton enfoncé permet de débloquer la capacité de double saut Dans l'arborescence de la scène distante, je peux voir que le booléen du tableau a été défini sur true à la fois dans la ressource de données et dans le Fermez le jeu et relancez-le. Le double saut est déjà débloqué puisqu'il a été enregistré. Nous pouvons supprimer les instructions d'impression maintenant que le fonctionnement du double saut est confirmé. Nous avons maintenant une capacité de double saut à débloquer, mais nous avons plusieurs autres capacités à débloquer Je vous verrai dans la prochaine vidéo. 44. 6-2 Diapositive murale: Bonjour, mes amis. Dans cette vidéo, nous allons permettre au personnage de glisser le long d'un mur, ajoute de la friction pour ralentir sa descente. Tout d'abord, nous devons décider cette capacité et du moment où nous voulons qu'elle se produise. Lorsque vous implémentez une nouvelle fonctionnalité comme celle-ci, il est conseillé de configurer abord les tests que vous souhaitez réussir. Je vais commencer par la scène du contenu de la pièce et cacher les arbres pour mieux voir. Pour créer un mécanisme de coulissement mural, je vais créer deux murs dans ma chambre. Je considère que mon mécanisme Wall Slide complet lorsque le personnage peut sauter, puis glisser le long de l'un ou l'autre des murs à une vitesse de chute réduite. J'aimerais également jouer une animation différente pendant que cela se produit. La diapositive murale doit se terminer lorsque le personnage n'est plus en contact avec le mur, s'il touche le sol ou si nous appuyons sur le sens du mouvement pour éloigner le personnage du mur. Sa mise en œuvre modifiera donc la physique aérienne du personnage. Dans le script du personnage du joueur, nous allons modifier le processus de physique de l'air du personnage Appelez ensuite le processus de physique de l' air de la superclasse à partir du script du personnage Ici, nous pouvons séparer notre code en trois blocs distincts. Lorsque le personnage exécute une diapositive murale, vérifie quand il peut commencer à exécuter une diapositive murale, et à tout autre moment, nous appelons le processus de superclasse Airphysics Nous avons besoin de savoir quand le personnage exécute une diapositive murale Nous devons donc la déclarer en tant que variable booléenne Il serait également utile d'exporter un float à utiliser comme multiplicateur de la gravité du personnage lors d'une glissade murale. Je vais utiliser 10 %. Pour en revenir au processus de physique de l'air, nous pouvons maintenant bifurquer selon que la variable « is wall sliding » est vraie ou fausse. Si le personnage glisse déjà sur le mur, nous pouvons soit continuer le glissement mural, soit y mettre fin selon que d'autres conditions sont remplies. Si le personnage ne glisse pas sur le mur, nous devons vérifier s'il peut glisser sur le mur, et si les conditions sont réunies pour commencer à glisser sur le mur, faites-le. Enfin, si tout cela est faux, nous devrions utiliser par défaut la physique de l'air des superclasses écrivant votre algorithme dans des commentaires de pseudocode comme celui-ci il est beaucoup plus facile de le remplir par la suite et de le réorganiser Cela rend également le résultat final déjà commenté. Commençons par démarrer un Wall Slide en vérifiant si la capacité Wall Jump a été déverrouillée Ajoutez ensuite également la condition que ce personnage doit être sur un mur. La classe character body fournit cette fonction qui agit de la même manière que sur le sol. J'aimerais également ajouter d' autres conditions selon lesquelles leur vitesse Y doit être supérieure ou égale à zéro. Je ne veux pas que le personnage commence à glisser sur le mur s'il se déplace vers le haut, et le joueur doit appuyer sur le sens de déplacement saisi vers le mur. Le corps de caractère à deux chiffres nous donne également une autre fonction. Reprenez Wall à la normale. Cela renvoie un vecteur pointant à l'opposé du mur. Donc, si nous utilisons la partie X de ce vecteur, celle-ci sera toujours négative si le mur est droite du personnage ou positive si le mur est à gauche du personnage. En comparant cela à la direction de déplacement du personnage, je vais multiplier chaque côté par moins un et exiger que les résultats soient égaux. Cela ne permettra pas à la direction du déplacement d'être nulle. Il y a plusieurs conditions dans cette instruction I, et elles ne rentrent pas dans ma fenêtre de script. Si vous souhaitez écrire les conditions de votre instruction if sur plusieurs lignes, vous pouvez le faire en les mettant entre crochets. Cela peut faciliter la lecture et le débogage de votre code si vous préférez ce format Bien que mes murs soient parfaitement verticaux, vous devrez peut-être utiliser le sinus du X normal si vos murs sont inclinés Si tout cela est vrai, j'autoriserai le personnage à lancer un toboggan mural en réglant le glissement mural true et en plafonnant sa vitesse Y à zéro à l'aide de la fonction min Cela créera une brève réinitialisation de la vitesse de chute pour ralentir le glissement du mur. J'imprimerai également une déclaration à des fins de test. Nous allons maintenant supposer que le personnage est déjà en train de faire glisser un mur et que nous voulons annuler sa gravité pour ralentir sa descente En ajoutant simplement à la vélocité Y du personnage, la gravité multipliée par Delta est multipliée par le multiplicateur de gravité Wall Slide, que j'ai réglé à 10 % de la gravité normale. En y réfléchissant d' un point de vue physique, cela revient dire qu'il existe un coefficient de friction de 0,9 entre le personnage et le mur. Enfin, nous pouvons nous demander quand terminer le Wall Slide. Si le personnage n'est plus sur le mur ou si le joueur appuie dans le sens opposé pour s' éloigner du mur. Donc, si ce n'est pas sur le mur ou si le signe de la direction du déplacement est le même que les normales du mur X, alors je mettrai la valeur False au mur et j'imprimerai une déclaration indiquant que la diapositive murale est valeur False au mur et j'imprimerai terminée Il serait plus simple de continuer la diapositive murale alors que les autres bloquent cette déclaration I. Je vais donc la couper et la coller ici. Il existe une autre condition qui doit mettre fin à un toboggan mural lorsque le personnage touche le sol. Comme nous avons déjà une fonction qui est automatiquement appelée lorsque le personnage débarque, je vais simplement ajouter une autre instruction I qui met fin à la diapositive murale. Si le caractère glisse sur le mur, réglez I wall sliding sur false, puis imprimez une autre déclaration. Il est utile que ces deux instructions soient différentes afin que nous puissions voir quand chacune d'elles se produit réellement pendant nos tests. Cela fonctionnera pour le clavier, mais pas pour un contrôleur puisque le sens du déplacement peut être une valeur décimale Je vais donc devoir appliquer la fonction de signe à ces deux vérifications pour fonctionner avec l'entrée du contrôleur. La dernière chose à faire est d'ajouter une animation Wall Slide au lecteur d'animation du personnage. Je vais donc dupliquer leur animation de marche. Modifiez la position Y de la région de la feuille de calcul utilisée et supprimez la trace des traces de pas Ajout de cette animation à la ressource State Machine. J'autoriserai le personnage à passer à cet état entre saut et la chute si I Wall sliding est défini sur true. Ensuite, passez d'un toboggan mural chute si le glissement mural est réglé sur des chutes. Ou à la locomotion s' ils touchent le sol. Dans le script du gestionnaire de jeu, je vais remplacer le déverrouillage du double saut déverrouillage du Wall Cela devrait être suffisant pour réussir mon test, je vais donc lancer le jeu. Le personnage peut toujours sauter normalement, et sauter contre le mur ne fait pas glisser le mur puisque cette capacité est toujours verrouillée. Mais en appuyant vers le haut pour déverrouiller le Wall Jump, si je saute en me dirigeant vers le mur, ils glissent vers le bas et s'arrêtent lorsqu'ils touchent le sol. essayez de le faire sur l'autre mur, le toboggan mural se termine lorsqu' ils atteignent le bas du mur. Et encore un essai contre le premier mur, le toboggan mural ne commence que lorsque le personnage commence à tomber, et je peux terminer le toboggan plus tôt en m' éloignant du mur. Le comportement normal du personnage en matière de saut n'est pas affecté par l'exécution de ces actions. Une fois tous les tests réussis, n'oubliez pas de commenter les instructions d'impression. Notre personnage est maintenant capable d'exécuter un Wall Slide, mais nous devons encore implémenter le Wall Jump. Je vous verrai dans la prochaine vidéo. 45. 6-3 Sauts de mur: Bonjour, mes amis. Dans cette vidéo, nous allons permettre au personnage de sauter loin du mur tout en effectuant un toboggan mural. Dans le script du personnage, nous avons déjà remplacé la fonction de saut pour effectuer un double Lorsque nous voulons que le personnage saute sur le mur, toutes ces conditions lors du double saut peuvent également être vraies. Nous devons donc d'abord considérer le Wall Jump comme une possibilité et l'exclure avant de vérifier s'il y a un double saut, car les conditions du Wall Jump sont plus spécifiques. Nous n'aurons qu'à vérifier si la capacité Wall Jump a été déverrouillée et si le personnage exécute actuellement un wall slide Si ces conditions ne sont pas remplies, nous pouvons vérifier si le personnage peut faire un double saut à la place. Cependant, cela ne permettra pas au personnage d' effectuer un saut mural tant que le Wall Slide n'aura pas commencé, qui attend que le personnage ait atteint le sommet de son saut. Si vous souhaitez autoriser le saut de mur avant de lancer le Wall Slide lorsque la vélocité Y du personnage est négative, nous pouvons également ajouter d'autres conditions. Soit les personnages exécutent un toboggan mural, soit ils ne sont pas au sol et sont accrochés à un mur, et la direction du déplacement est dirigée vers le mur. ce qui concerne l'ordre des opérations pour la logique, nous devons mettre le ou entre crochets afin qu'il soit vérifié avant le premier et. Nous pouvons utiliser plusieurs niveaux de crochets et d'indentations pour présenter visuellement l'ordre des opérations d'une logique complexe comme celle-ci afin de faciliter la compréhension si nécessaire Maintenant que nous sommes prêts à effectuer un saut mural, nous pouvons faire les mêmes choses que pour n'importe quel autre saut. Retournez ensuite true, afin que le gestionnaire de saisie sache que cette pression sur le bouton de saut a été réussie En ce qui concerne le réglage de la vélocité du corps du personnage, nous voulons qu'il soit non seulement ascendant , mais aussi qu'il s'éloigne du mur. Ainsi, plutôt que de simplement définir la vélocité Y du personnage, nous allons définir l'ensemble du vecteur de vélocité, créant également un nouveau vecteur. Pour le X, nous pouvons utiliser le point vectoriel normal X de la paroi, et pour Y, nous pouvons en utiliser un. Cela nous donne un vecteur pointant vers haut et à l'opposé du mur, afin que nous ayons la bonne direction. multipliant cela par la force de saut, nous obtiendrons un vecteur d' une amplitude supérieure notre saut normal puisque le vecteur d'origine avait déjà une longueur supérieure à un Nous pouvons normaliser ce vecteur de direction si nous le voulons, mais la façon dont il fonctionne actuellement produira en fait un meilleur résultat, à mon avis, avec la hauteur totale du saut, plus la force supplémentaire appliquée loin du mur. Mais comme la force de saut est un nombre négatif, cela inversera le mur à la normale pour il pointe vers le mur plutôt que vers l'extérieur. Je vais donc ajouter un négatif au recto de wallnormalt X pour en faire un double négatif, qui devient positif Pour animer le Wall Jump, la machine à états du personnage aura besoin d'une transition depuis Wall Slide pour sauter condition que le personnage saute Cela va à l'encontre de la transition vers la chute puisque le personnage ne glisse plus sur le mur en même temps. La transition vers le saut nécessitera donc une valeur de priorité inférieure pour être prise en compte en premier. Au lieu que le double saut soit prêt, nous devrons régler Is wall sliding to falls lors de l' exécution du Wall Jump. Si nous lançons le jeu, nous pouvons déjà effectuer le saut mural puisqu'il a été débloqué dans la vidéo précédente En sautant contre le mur, on peut sauter du haut. La vitesse latérale par rapport au mur est égale à la force verticale appliquée. Mais comme la gravité tire constamment le personnage vers le bas, cela est beaucoup moins perceptible que la force qui l' éloigne du mur, qui n'est réduite que par le contrôle pneumatique ou les freins à air du personnage. Je préférerais que mon personnage soit soumis beaucoup moins de force latérale et puisse revenir sur le même mur après avoir effectué un saut de mur et continuer à grimper vers le haut. Cela nécessitera de nombreuses modifications physiques pour fonctionner correctement, à la fois en réduisant la force latérale appliquée au Wall Sump pour s'éloigner du mur en donnant au personnage une meilleure maîtrise de l'air afin de revenir sur le mur à une altitude plus élevée. Parlons d'abord de la force latérale. Plutôt que de coder une valeur en dur, il est toujours préférable d'utiliser variables exportées afin de pouvoir les déformer et les modifier. Je vais exporter un vecteur deux nommé Wall Jump force multiplicator et lui donner une valeur par défaut de moins un positif un. Nous pouvons ensuite multiplier le vecteur de vitesse obtenu par ce nouveau multiplicateur de force Wall Jump. Ce négatif éliminera le besoin d'appliquer le négatif au vecteur normal du mur, ce que je trouve plus intuitif puisque je pense que le négatif est éloigné du mur. Lorsque vous multipliez deux vecteurs, le résultat sera le produit des deux X par le produit des deux Ys Avec ces valeurs, cela fonctionnera de la même manière qu'à l'heure actuelle. Mais comme la valeur est exportée, je peux la changer dans la scène de mon personnage en moins 0,5, réduisant ainsi la vélocité X de moitié. Si vous souhaitez vous rappeler fonctionnement de vos variables, ajoutez un signe numérique supplémentaire devant un commentaire au-dessus de la déclaration de variable pour créer une infobulle qui s' affiche lorsque vous passez la souris sur la variable dans l'inspecteur En recommençant le jeu, mon personnage utilise toute la force ascendante du saut, mais seule la moitié de la force de saut est appliquée dans la direction X. Mais je n'arrive toujours pas à retourner au mur à un point plus élevé pour grimper plus haut. Pour cela, je dois donner à mon personnage beaucoup plus de contrôle aérien, mais je ne veux pas qu' il ait plus de contrôle aérien à un autre moment. Je dois donc modifier la valeur du contrôle aérien spécifiquement uniquement lors d' un saut mural, puis la remettre à sa valeur normale Dans les variables exportées pour le saut mural, je vais exporter un nouveau flotteur pour contrôle aérien de Wall Jump et le régler sur une valeur très élevée, par exemple quatre. Cela permettra au personnage accélérer quatre fois plus vite qu'il ne le ferait au sol et huit fois plus vite que lors d'un saut normal mon contrôle aérien étant réglé par défaut sur 0,5 Je vais également le stocker dans une autre variable en utilisant la balise ready. Donc, quand je veux le remettre à sa valeur normale, je saurai ce que c'est. Comme je ne sais pas si le joueur va sauter loin du mur ou revenir vers celui-ci ou s'il veut faire quoi que ce soit d'autre, le seul moyen fiable de rétablir le réglage par défaut du contrôle aérien serait d'utiliser un chronomètre. En ajoutant un nœud de temporisation à la scène, je le nommerai Wall Jump, je lui donnerai un nom unique, puis je lui donnerai une référence avec le tag on ready two. Je vais nommer cette dérogation au contrôle aérien de Wall Jump pour être un peu plus clair dans ce contexte Maintenant, lorsque nous effectuons le Wall Jump, nous pouvons changer la valeur du contrôle aérien en contrôle aérien Wall Jump et démarrer le chronomètre de dérogation du contrôle aérien Wall Jump En sélectionnant le nœud Timer, nous pouvons définir sa propriété one shot true et lui donner un court temps d'attente. Je vais utiliser une demi-seconde. Connectez ensuite le signal de temporisation du temporisateur au script. Lorsque le chronomètre expire, nous pouvons remettre le contrôle aérien du personnage à sa valeur par défaut. testant, c'est plus proche, mais je n' arrive toujours pas à gravir le mur. Je vais donc devoir ajuster les valeurs de mon multiplicateur de force Wall Jump et de mon contrôle aérien Wall Jump jusqu'à ce que cela fonctionne. Je recommence le jeu. Maintenant, lorsque j'effectue un saut sur le mur, mon personnage a suffisamment d'accélération pour revenir sur le même mur à un point plus haut, ce qui me permet de grimper sur le mur. Notre personnage est maintenant capable de sauter un mur pour escalader des surfaces verticales. Ensuite, nous allons ajouter une capacité impressionnante avec des cadres d' invincibilité Je vous verrai dans la prochaine vidéo. 46. 6-4 Poinçon: Bonjour, mes amis. Dans cette vidéo, nous allons donner au personnage une capacité de tiret à débloquer À partir des paramètres du projet, l'onglet Carte en entrée aura besoin d'un bouton qui peut être utilisé pour le tiret. J'utiliserai la touche D ou le bouton droit de ma manette. Ensuite, dans le script du joueur, dans la fonction de saisie, si le bouton du tableau de bord a été enfoncé, essayez de tirer, et en cas d'échec, mettez mémoire tampon la saisie du tableau de bord pour qu'elle sèche à nouveau à l'image suivante, comme nous l'avons fait pour le saut. Le tableau de bord aura besoin d'une direction, que nous pouvons obtenir en utilisant l'entrée Singleton, get axis, move left, move right Pour fournir des arguments à un objet appelable, nous utilisons la fonction bind, puis nous passons les arguments à cette fonction à la place Il serait donc préférable de n' appeler qu'une seule fois la fonction input get axis et de stocker le résultat. Comme cela ne se produit que pendant les images lorsque vous appuyez sur le bouton du tableau de bord, ce n'est pas si mal de déclarer une variable ici. Lorsque l' entrée mise en mémoire tampon est appelée, elle transmet les arguments liés Si vous avez initialement appuyé sur le tableau de bord alors que le joystick gauche était incliné, il sera mis en mémoire tampon avec la même entrée directionnelle Nous pouvons maintenant écrire cette fonction de tiret dans le script du personnage de notre joueur, acceptant la direction du tiret comme paramètre et en renvoyant un booléen, renvoyant false par défaut Avant d'écrire cette fonction, nous avons besoin de quelques variables. la distance que le personnage doit parcourir, je mettrai la mienne à 128 pixels. La force requise pour atteindre cette distance est calculée à l'aide de l'étiquette « on ready Nous pouvons utiliser la même formule que pour le calcul de la hauteur de saut, la racine carrée de la distance multipliée par la force négative, qui dans ce cas est la décélération multipliée J'aimerais également suspendre la gravité pendant que le tableau de bord se produit. Je vais donc également stocker la gravité par défaut du personnage dans une variable à l'aide de la balise on ready. Maintenant, pour ce qui est de la fonction tiret, si la capacité du tiret a été déverrouillée, nous voulons que le personnage fasse face à la direction du tiret, ce que nous pouvons faire en réglant le sens du déplacement sur cette valeur Réglez ensuite la vélocité du personnage un nouveau vecteur deux la direction du tiret multipliée par comme un nouveau vecteur deux, la direction du tiret multipliée par la force du tiret étant le X et zéro pour le Y. Comme le joystick analogique gauche peut être incliné, le joueur peut ainsi se précipiter plus lentement ou plus vite en fonction l' inclinaison du joystick analogique sur la Je ne veux pas que cela se produise Je vais donc utiliser la fonction sinus pour supprimer l'inclinaison de l'équation. Nous pouvons suspendre la gravité pendant le tiret, réglant la valeur de la gravité à zéro, puis revenir à la valeur true car le tiret a réussi et n'a pas besoin d'être mis en mémoire tampon En ce qui concerne la direction à prendre en compte, plusieurs cas doivent être pris en compte, non seulement si le joueur donne la direction à suivre, mais aussi si ce n'est pas le cas et aussi si le personnage est en train de faire glisser un mur. Comme c'est le cas le plus spécifique, je vais d'abord vérifier celui-ci. Si le caractère glisse sur le mur, je remplacerai la valeur de direction signe de WallNRMaltx S'ils ne glissent pas sur le mur et que le joueur donne une indication directionnelle lorsqu'il appuie sur le bouton du tableau de bord, j'utiliserai le sinus de direction comme direction, supprimant toute inclinaison analogique de l'entrée afin de pouvoir la supprimer de la ligne ci-dessous. Si le joueur ne donne aucune indication de direction lorsqu'il appuie sur le bouton du tableau de bord, je suppose qu'il veut se précipiter vers l'avant. J'utiliserai un ternaire pour la direction soit négative si le personnage fait face à la gauche ou positive s'il ne rétablit pas la gravité normale, nous aurons besoin d'une autre fonction à appeler à la fin du tiret Cela ne nécessite aucun paramètre ni ne renvoie de valeur. Nous allons simplement rétablir la gravité par défaut du personnage . Dans la scène du personnage, le tableau de bord aura besoin d'une animation dans le nœud Animation Player. réglant les images par seconde et en zoomant, j'ajouterai mes images clés pour animer le Nous devrons ajouter une piste de méthode d'appel et une image-clé sur cette piste pour appeler la fonction end dash à la fin de l'animation Ou n'importe quel cadre dans lequel vous souhaitez restaurer la gravité du personnage. En utilisant cette procédure, s'il est possible d'interrompre cette animation pour quelque raison que ce soit, nous devrons tout de même appeler la fonction end dash pour rétablir la gravité du personnage, contrairement au chronomètre que nous avons utilisé pour rétablir le contrôle des erreurs du personnage. Gardez donc cela à l'esprit et faites un commentaire pour vous en souvenir plus tard. En ajoutant cette animation à la machine à états, il devrait être possible d'effectuer un tiret à partir de n'importe lequel de nos états de mouvement existants. Il serait donc préférable de placer cette animation sur une nouvelle couche. enregistrant la machine à états actuelle en tant que ressource du projet, je vais la nommer mouvement et placer dans le dossier des scènes de personnages. Créez ensuite une nouvelle ressource de machine à états pour l'arbre d'animation. ajoutant la machine à états de mouvement tant que nœud dans cette nouvelle machine à états, je vais la renommer en mouvement et créer une transition entre le début mouvement. C' est donc la valeur par défaut En ajoutant une nouvelle animation de tableau de bord à cette machine à états, nous pouvons ajouter une transition entre le mouvement et le tiret et revenir au mouvement. Pour lancer une animation une seule fois, la transition qui y mène doit être définie sur Activée, et le mode de commutation de la transition menant à l'animation doit être réglé à la fin » et le mode avancé doit rester automatique. Nous pouvons tester cette animation en cliquant sur le bouton play dans l'état. À chaque clic, il joue une fois dans son intégralité et revient à l' état de mouvement une fois terminé. La transition menant à l'animation n'étant pas automatique, il nous appartiendra de déclencher cette animation manuellement via notre script. déclarant une nouvelle variable, sera utilisée pour plusieurs capacités différentes En déclarant une nouvelle variable, elle sera utilisée pour plusieurs capacités différentes. Je vais donc la mettre en haut et la nommer animation en abrégé. Le type de cette variable sera une lecture automatique de l'état d'un nœud d'animation. C'est ce que Godot utilise pour naviguer dans la machine à états et jouer des animations En sélectionnant le nœud dans l'arborescence des scènes, nous pouvons voir cette ressource de lecture sous les paramètres de lecture. Nous pouvons récupérer cette ressource en cliquant et en faisant glisser le nœud Animation Tree pour obtenir le chemin du nœud Utilisez ensuite des crochets pour obtenir une ressource à partir de ce nœud. Cliquez sur cette ressource et faites-la glisser depuis l'inspecteur entre crochets pour obtenir le chemin d'accès à la ressource Si nous étendons le mouvement et la locomotion, vous pouvez constater que chaque couche de la machine à états possède sa propre ressource de lecture Bien que nous n'en ayons actuellement besoin que pour déclencher manuellement le tableau de bord, nous ajouterons bientôt d'autres capacités. Ce chemin changera également au fur et à mesure que nous ajouterons de nouvelles couches à la machine d'état Il devra donc être mis à jour. Pour déclencher l'animation du tiret, lorsque vous exécutez un tiret avec succès, nous pouvons indiquer à cette lecture de passer à l'état de tiret en spécifiant son nom de chaîne comme argument. Cette ligne de code équivaut à appuyer sur le bouton de lecture dans l'arbre d'animation lorsque nous avons prévisualisé l'animation Je souhaite également supprimer la capacité du joueur à contrôler le personnage pendant le tiret. Ainsi, en remplaçant le processus physique, nous pouvons l'interrompre rapidement et vérifier dans quel état se trouve actuellement la machine à états d'animation en utilisant la fonction G current node Cela renvoie le nom de chaîne que nous avons écrit sur le nœud de l'arbre d'animation, que nous pouvons comparer pour voir s'il s'agit d'un mouvement ou non. S'il s'agit d'autre chose que du mouvement, je mettrai la direction du déplacement à zéro avant poursuivre le processus physique normal des superclasses Cela empêchera le personnage de se déplacer ou de faire face à une autre direction lorsqu'il utilisera l'une des capacités de la couche supérieure de la machine à états. Dans le script du gestionnaire de jeu, je vais modifier la flèche vers le haut pour débloquer la dashability Lancer le jeu en appuyant sur le bouton du tableau de bord ne fait rien. Après avoir appuyé sur la flèche vers le haut pour déverrouiller la dashability, nous pouvons nous précipiter, faisant avancer le personnage vous appuyez sur une direction , le personnage se précipitera dans cette direction. Et si nous nous précipitons en glissant sur le mur, le personnage s'éloignera du mur. Le personnage de notre joueur est désormais capable de se déplacer dans l'environnement, mais nous devrons ajouter un temps recharge pour empêcher le joueur de l'utiliser trop souvent. Je vous verrai dans la prochaine vidéo. 47. Temps de récupération 6-5: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter des images d'invincibilité et un temps de recharge à notre capacité de Dash Avant de commencer à ajouter des cadres d' invincibilité au tableau de bord, il serait utile d' avoir une case de réponse dans notre scène afin de pouvoir essayer de la parcourir rapidement Dans la scène du contenu de la pièce de départ, j'ajouterai une zone à déchiffrer et je la renommerai en appuyant sur Box Ajoutez ensuite une forme de collision en tant qu'enfant. Donnez-lui une forme de rectangle en tant que ressource et définissez sa couleur de débogage sur le rouge Vous pouvez imaginer que cela représentera un ennemi qui inflige des dégâts au personnage du joueur au contact. Je vais faire une tuile d'une épaisseur 32 pixels et deux de haut de 64 pixels. Puis déplacez-le vers la gauche. Je considérerai que mon test est réussi si le personnage du joueur peut se faufiler dans cette zone sans être blessé Pour que cette zone de collision inflige des dégâts au joueur, elle devra être surveillée. Il n'est pas nécessaire qu'il soit contrôlable, mais laisser cette case cochée ne fera aucune différence Il n'est pas nécessaire qu'il existe sur une couche, mais doit masquer la couche Hurt Box du joueur Si cela vous aide à mieux comprendre les collisions, considérer que cette zone de frappe existe sur une couche de zone de frappe ennemie ou sur une couche de danger environnemental. Les seules exigences sont qu'il doit surveiller et masquer le joueur Hurt Box. En attachant un script à ce nœud, nous allons connecter le signal saisi dans la zone au script. Après avoir vérifié si la zone dispose d'une méthode de prise de dégâts, nous appellerons cette méthode et en donnerons une pour le montant des dégâts. Cela permettra de s'assurer que la zone qui entre dans celle-ci contient le script Hurt Box que nous avons créé précédemment, qui utilise la méthode take damage, acceptant le montant des dégâts comme paramètre. Si une autre zone déclenche le signal sans script Hurt Box, cela provoquera une erreur car il n'y aura pas de méthode de prise de dégâts à appeler. Pour pouvoir voir nos formes de collision pendant le test du jeu, nous pouvons ouvrir le menu de débogage et sélectionner les formes de collision visibles Si nous lançons le jeu, nous pouvons voir la zone de frappe, et le personnage du joueur subit un dommage à chaque fois qu'il entre dans cette zone. Un message d'erreur s'affiche car le contenu de la pièce est chargé en réponse à entrée de notre personnage dans une zone de collision, et Godot n'aime pas ajouter une autre zone de collision lors d'une collision Nous allons ignorer cela pour le moment car nous ne faisons qu'un test, et cela ne fera pas partie de notre jeu final. Dans la scène du personnage, sélectionnez le nœud Animation Player et l'animation du tiret. Pour ajouter des images d'invincibilité à notre animation de tableau de bord, il suffit de saisir la propriété surveillable de la Hurt Box Nous pouvons définir le cadre exact lorsque la Hurt Box s'éteint et lorsqu'elle se rallume. Si vous le souhaitez, vous pouvez également définir la visibilité de votre Hurt Box pour qu'elle corresponde à ses propriétés surveillables afin de la voir s'éteindre puis se rallumer pendant que vous jouez au jeu Cela permet de savoir plus facilement quand votre personnage est réellement invincible. Il peut également être utile de désactiver la visibilité de la forme de collision du corps du personnage afin de mieux voir la boîte à blessures. cours de jeu, nous pouvons désormais nous faufiler dans la zone de frappe sans subir de dégâts. Marcher dans la zone inflige toujours des dégâts, tout comme terminer la course à l'intérieur de la Ajoutons maintenant un temps de recharge au tableau de bord. Nous allons commencer par ajouter un nœud chronomètre à la scène du personnage. Je vais donner à ce Timer Dash Cooldown le nom de Timer Dash Cooldown et définir sa propriété One Shot sur true Je vais laisser sa durée de pesée à 1 seconde. Ce sera le temps de refroidissement de la capacité. Étant donné qu'il s'agit de la deuxième capacité associée à un nœud de temporisation, et que nous souhaiterons peut-être en ajouter d' autres à l'avenir, vous pouvez envisager d'utiliser un nœud normal comme dossier pliable pour les contenir. Mais cela aidera à lui donner un nom unique au cas où nous voudrions restructurer l'arbre des scènes Nous n'avons pas besoin de connecter le signal au script pour utiliser ce nœud de temporisation comme temps de refroidissement. Dans les déclarations de variables pour Dashability, j'utiliserai la balise on ready pour obtenir une référence à ce nouveau nœud de temporisation Tout ce que nous avons à faire est de démarrer le chronomètre soit au début, soit à la fin, soit au point de départ. C'est à vous de choisir, mais si vous souhaitez commencer le temps de recharge à la fin du dash, une autre condition sera requise pour empêcher le joueur de se précipiter deux fois de suite Je démarrerai le temps de recharge une fois le tableau de bord terminé. Revenez ensuite à l' instruction I où nous vérifierons si ce personnage peut commencer à vibrer. Nous pouvons vérifier si le nœud actuel de la machine à états d'animation est en mouvement. Cela aura également des avantages supplémentaires plus tard, puisque nous n'autoriserons pas le personnage à se précipiter lorsqu'il exécute d'autres capacités d'action similaires. Pour appliquer le temps de recharge, il suffit de vérifier si ce chronomètre est arrêté pour savoir si nous devrions être en mesure de recommencer à courir Si l'animation du tableau de bord est déjà active ou si le temps de recharge n'est pas arrêté, cela signifie que le tableau de bord échouera Maintenant que vous lancez le jeu, appuyez sur le bouton du tableau de bord pour permettre au personnage de se lancer une seule fois, puis force le joueur à refroidir pendant une seconde avant de pouvoir à nouveau se lancer. Cela fonctionne, mais cela n'est en aucun cas communiqué au joueur. Habituellement, les jeux comme celui-ci ont un indicateur diagétique, quelque chose qui existe dans le jeu, non sur le HUD, pour indiquer au joueur quand le temps de recharge est terminé. Ajoutons donc un nœud 2D Animated Sprite à la scène du personnage et appelons-le Dash Cooldown effect. En créant une ressource Sprite frames pour ce nœud, nous pouvons importer une feuille Sprite Je vais simplement le mettre dans le dossier poussière pour le moment plutôt que de créer un nouveau dossier de ressources pour une feuille Sprite Et ajoutez les cadres Sprite de la feuille Sprite. Je vais désactiver le bouclage, régler le nombre d'images par seconde à 12 et ajouter une image vide à la fin de l'animation Ce n'est pas centré sur le personnage, je vais donc le déplacer de 12 pixels vers le haut. Cette animation dure plus d'une seconde, mais au bout d'une seconde, je veux que le temps de recharge soit considéré comme terminé. Je vais donner un nom unique à ce nœud. De retour dans le script, il suffit de récupérer une référence à ce nœud. Et dites-lui de jouer à la fin du tableau de bord. Mais comme mon animation est plus longue que le temps de recharge de Dash, je dois arrêter l'animation avant de la lancer au cas où elle serait toujours en cours de lecture Cela réinitialisera l' animation au début. R Maintenant, lorsque nous lançons le jeu et que nous utilisons la capacité Dash, l'animation se joue, mais elle ne suit pas le personnage. Cela est dû au fait qu'un nœud normal n'a pas de transformation. Il n'a donc pas de position. Cela rompt la ligne d'héritage depuis le nœud racine du personnage. Le nœud Animated Sprite two D commence donc sa propre ascendance pour deux transformations en D, à partir de la position 00 Nous pouvons remplacer le type du dossier de capacités deux D afin qu'il fournisse par deux D afin qu'il fournisse une ligne de succession dans l'arbre des scènes et que le sprite animé suive le nœud racine Il est désormais clair pour le joueur que sa capacité de dash est en temps de recharge et qu' il sait exactement quand il peut recommencer sans avoir à ajouter d' informations supplémentaires sur le HUD Nous avons maintenant notre capacité de tableau bord capable de parcourir les cases frappe sans nous faire toucher et rafraîchir avant de pouvoir être réutilisées. Ensuite, nous allons ajouter une capacité passive qui modifie l'apparence du personnage. Je vous verrai dans la prochaine vidéo. 48. 6-6 Hat: Bonjour, mes amis. Dans cette vidéo, nous allons implémenter une capacité passive qui modifie l'apparence du personnage En commençant par la scène du contenu de la pièce, je vais dupliquer la zone de collision précédente pour ce test. Cette fois, la zone de collision représentera spécifiquement la chaleur intense provenant de l'intérieur d'un volcan. Je vais changer la couleur en orange pour savoir laquelle est laquelle. Je veux que le joueur ne puisse pas traverser cette zone tant qu'il n'a pas débloqué un chapeau magique qui lui permettra de continuer indemne Mais le fait de porter le chapeau leur permettra tout de subir les dégâts causés par les boîtes de frappe normales. Donc, plutôt que de masquer la couche Hurt Box normale du joueur, j'utiliserai une autre couche J'utiliserai la couche 14 comme couche dédiée à cet effet thermique environnemental. Ce sera facile pour moi de m'en souvenir puisqu'il est directement inférieur à dix. Dans les paramètres du projet, je nommerai cette couche heat. Ensuite, dans la scène des personnages, je vais faire en sorte que la Hurt Box existe également sur cette couche. Désormais, cela fonctionnera de la même manière que dans la zone de collision précédente, infligeant un dommage au joueur à chaque fois qu'il entre dans cette zone. Il est le seul à vérifier les collisions sur la couche 14 plutôt que sur la couche 10. Tout ce que nous avons à faire pour que personnage du joueur soit immunisé contre les dégâts causés par la chaleur lorsqu'il porte le chapeau, c'est de retirer la couche 14 de sa propriété de couche de collision Hurt Box. Pour modifier l'apparence du personnage, je vais superposer des sprites supplémentaires sur le personnage Je vais importer de nouvelles feuilles de sprites pour trois améliorations différentes une gemme, une cape et un chapeau Ensuite, dans la scène des personnages, j'ajouterai un nœud Sprite Tu Di supplémentaire pour chacun d'eux. Le tout avec des textures d'atlas, tout comme le sprite corporel. Attribuez ensuite les feuilles de sprites comme propriété d'atlas pour chaque nœud la façon dont ces actifs ont été dessinés, je dois les superposer spécifiquement dans l' ordre du chat, puis de la cape, du chapeau et de la confiture par-dessus Je vais commencer par le premier sprite à la position 00 d'une taille de 32 x 36 pixels et leur donner le même décalage pour les déplacer de 18 pixels vers le haut Ces actifs sont dessinés pour s'animer de manière synchrone avec le sprite normal du personnage Ainsi, toutes les valeurs de région seront les mêmes pour chaque couche en même temps. Il me suffit d'ajouter région de texture de l'atlas de chaque sprite à l'animation Copiez et collez ensuite les touches du corps de la piste Sprite vers les autres pistes Et changez leur mode de mise à jour en mode discret. Désormais, l'animation inclut également toutes les couches de sprites parfaitement synchronisées Je devrai le faire pour toutes mes animations, mais cela ne demandera pas beaucoup d'efforts. Afin de retourner chacun de ces sprites, nous pourrions définir toutes leurs propriétés de retournement H chaque fois qu'ils changent de direction Mais il existe un moyen plus simple d' utiliser l'héritage de l'arbre des scènes. Si nous faisons de tous les autres sprites un enfant du sprite corporel, ils en hériteront leur transformation Et nous pouvons inverser un sprite en utilisant sa transformation en réglant son échelle X sur moins un Notez que cette astuce ne doit pas être utilisée pour tout ce qui concerne la physique ou les collisions. Cela fonctionne bien ici car nous ne dessinons que des sprites. Dans la fonction face gauche de notre script de personnage, plutôt que de régler le flip H, nous pouvons régler le point d'échelle X sur moins un, s'il est laissé, sinon sur un point positif. Cela synchronisera désormais le retournement de tous les sprites fois la configuration des sprites terminée, je désactiverai la visibilité des autres sprites par défaut, puis je les activerai au fur et à mesure que les capacités seront débloquées puis je les activerai au fur et à mesure que les capacités seront débloquées Dans le script du personnage du joueur, nous aurons besoin d'une fonction pour gérer les couches de sprites visibles en fonction des capacités débloquées par le joueur Je vais l'appeler Update Sprite visibility. Donnez ensuite un nom unique à chacun des sprites et définissez leur visibilité en fonction de la valeur débloquée pour la capacité correspondante Le double saut ajoutera la cape. Le chapeau est évident. Et la capacité de tirer des projectiles ajoutera la gemme. Dans le script du gestionnaire de jeu, lorsque nous commençons à jouer au jeu, nous pouvons appeler cette fonction pour mettre immédiatement à jour la visibilité des sprites du personnage au cas où nous aurions chargé une bière contenant des capacités déjà débloquées Pendant le jeu, nous souhaiterons également appeler cette fonction chaque fois que le joueur déverrouille une nouvelle capacité Nous allons donc ajouter un signal à ce script lorsqu'une capacité a été déverrouillée, avec le nombre entier de capacités comme paramètre Écrivez ensuite une fonction publique pour débloquer une nouvelle capacité, acceptant le même numéro de capacité et en omettant le signal Nous pouvons ensuite connecter ce signal au personnage du joueur. Cependant, nous n'avons pas écrit la fonction de visibilité de Sprite de mise à jour pour accepter des paramètres Ainsi, lorsque nous connectons le signal, nous devons dissocier un argument pour éviter de provoquer des erreurs Cela changera l'apparence du personnage, mais il subira tout de même des dégâts causés par la chaleur lorsqu'il portera le chapeau. Lorsque je mettrai à jour la visibilité des sprites du personnage , dans le cas précis où il porte le chapeau, je supprimerai également la couche de collision pour les dégâts causés par la chaleur afin de le protéger Pour supprimer une seule couche spécifique d'un masque de bits, passez d' abord le curseur de votre souris sur la couche et notez sa valeur La couche 14 a une valeur de 8 192 , soit deux pour la puissance 13 ou deux pour la puissance 14 moins un La couche de collision est en fait un entier qui, en binaire, est une séquence de zéros et de uns. Actuellement, ce sont tous des zéros, sauf que les dixième et 14e bits sont un Il suffit de changer le 14e bit à zéro pour le supprimer de cette couche. Nous allons commencer par saisir une référence à la case. Comme cette fonction n'est pas appelée très souvent, vous pouvez utiliser un chemin de nœud. Pour supprimer la couche de collision, nous pourrions soustraire sa valeur 8 192 Toutefois, cela dépend de la couche de collision qui existe actuellement sur la couche 14. Si nous devions appeler cette fonction pour une raison quelconque alors que la couche 14 est déjà désactivée, simple soustraction ne fonctionnerait pas En utilisant l'opérateur bit et sur la couche de collision de notre boîte Hurt, si nous pouvons fournir une séquence de tous les bits avec seulement le 14e bit pour zéro, le résultat sera de définir le 14e bit 20 quelle que soit sa valeur actuelle. Pour obtenir ce nombre, nous pouvons inverser les bits de 8 192, la valeur de la couche Cela se fait avec l'opérateur bitwise naught, qui dans GDScript est un Il s'agit d'un moyen mathématiquement très efficace de supprimer les couches de collision Si vous souhaitez ajouter une couche de collision en définissant son bit sur un, vous suffit d'utiliser l' opérateur ou au lieu de et de retirer le nœud Mais cela ne nous intéresse pas ici. Dans le script du gestionnaire de jeu, je vais mettre à jour ma fonction de saisie pour déverrouiller chaque nouvelle capacité en séquence lorsque j'appuie sur la flèche vers le haut pour mon test. Déclarer une nouvelle variable ici, afin qu'elle soit intégrée à mon code de test Je n'oublierai pas de le supprimer ainsi que la fonction de saisie lorsque je n'en aurai plus besoin pour les tests. Je vais lui donner le nom de capacité suivante sous la forme d'un entier dont la valeur par défaut est naturellement zéro Chaque fois que j'appuie sur la flèche vers le haut, je déverrouille la capacité suivante et j'imprime le nom de cette capacité. Nous pouvons utiliser la fonction keys sur une énumération pour obtenir un tableau de chaînes identiques à celles que nous avons écrites comme entrées d' énumération Ainsi, l'indexation du tableau de clés avec le numéro de capacité permet d'obtenir le nom de cette capacité Je vais ensuite incrémenter la capacité suivante, mais je vais la maintenir entre zéro et la taille de l'énumération des capacités moins une pour éviter toute erreur Je vais supprimer le fichier sécurisé actuel afin que mes capacités soient verrouillées et que les formes de collision visibles soient activées. En lançant le jeu, nous commençons sans aucune capacité débloquée et avec le personnage par défaut Sprite Je vais ouvrir l' arbre des scènes distantes et sélectionner les personnages Hurt Box pour vérifier qu'ils se trouvent sur les couches 10 et 14. En appuyant une fois sur la flèche vers le haut, la capacité de double saut est désormais déverrouillée, le personnage porte donc une cape En appuyant à nouveau sur la flèche vers le haut, le saut mural est débloqué, mais l'apparence du personnage reste inchangée puisque cette capacité n'a pas été associée à un changement esthétique Toucher l'une des zones de collision infligera des dégâts au personnage. En appuyant une fois de plus , le tableau de bord est également débloqué, et le personnage a toujours la même apparence Une fois de plus, pour débloquer le chapeau magique, nous pouvons voir que la boîte à blessures du personnage ne se trouve plus sur la couche 14, mais toujours sur la couche 10. Toucher la zone de frappe normale inflige des dégâts, mais pas le fait d'entrer dans la nouvelle zone de frappe due à la chaleur volcanique, ce qui signifie que le personnage est immunisé lorsqu'il porte le chapeau. En appuyant une dernière fois, nous débloquons la capacité de tir et ajoutons la gemme, mais nous ne l'avons pas encore implémentée. Notre personnage change maintenant de tenue en fonction de sa progression dans le jeu. La dernière capacité que nous ajouterons est de tirer un projectile. Je vous verrai dans la prochaine vidéo. 49. Projectile 6-7: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un sort de projectile que le joueur peut lancer en dépensant ses points de magie Tout d'abord, nous devons donner à ce personnage des points magiques à dépenser. Dans le script du personnage du joueur, je vais ajouter une nouvelle catégorie d'exportation pour lancer des sorts Ensuite, deux variables pour leur magie maximale et leur magie actuelle, toutes deux sous forme de flotteurs. Nous aurons également besoin de signaux à émettre chaque fois que ces valeurs changent afin de pouvoir mettre à jour le HUD En remplaçant la fonction Ready, nous pouvons définir la valeur magique maximale à partir des données de sauvegarde du joueur Ensuite, je vais simplement démarrer le joueur en toute magie, en réglant la valeur actuelle sur la valeur maximale et émettant les signaux modifiés pour mettre à jour le HUD Depuis la scène de jeu, nous pouvons facilement connecter les signaux du personnage du joueur à la jauge magique puisqu'ils existent dans la même scène. La jauge magique n'est pas associée à un script, mais elle n'en a pas besoin. Comme la barre de progression fournit déjà les fonctions dont nous avons besoin, il suffit de désactiver les méthodes de script uniquement La classe range nous donne la fonction set max qui accepte un paramètre float. Ainsi que la fonction de valeur définie, accepte également un paramètre à virgule flottante. Désormais, la jauge magique sera automatiquement mise à jour avec les variables magiques du personnage du joueur. Dans les paramètres du projet, l'onglet Carte d'entrée aura besoin d'un bouton sur lequel le joueur pourra appuyer pour lancer un sort. J'utiliserai la touche C ou le bouton Face supérieur de ma manette. Ensuite, dans le script du joueur, nous pouvons copier le même format que le saut pour essayer de lancer un sort et, en cas d'échec, l'entrée en mémoire tampon pour réessayer l'image suivante. De retour dans le script du personnage du joueur, nous pouvons écrire la fonction cast, n' acceptant aucun paramètre et en renvoyant un booléen Tout ce que nous avons à faire ici est de vérifier si la capacité a été déverrouillée et si le personnage n'est pas occupé à effectuer d'autres actions, si le nœud actuel de l'animation est le mouvement Dites ensuite à l'animation de passer à l'animation du casting et renvoyez true si la saisie est réussie ou false si elle ne l'est pas. Si nous ne voulons pas que le lancement de notre sort soit instantané, tout le reste devra se faire dans une fonction séparée Nous l'appellerons « projectile à tir unique ». Elle n'a pas besoin d'arguments ni de renvoi de valeur, et nous ne disposons pas encore des informations nécessaires pour écrire cette fonction, mais nous aurons besoin que cette fonction soit déclarée et enregistrée avant de pouvoir l'inclure dans l'animation de casting. Pour passer à la scène du personnage, nous allons commencer par ajouter un sprite animé à dender pour l'utiliser comme effet de casting Cela nécessitera une ressource Sprite frames. Avant d'importer mes feuilles de sprites pour lancer des sorts, je vais créer un nouveau dossier pour les sprites magiques et déplacer l' effet Dash Cooldown dans Importez ensuite les sprites à lancer, le projectile et ses sprites d'impact Ajout des sprites d'animation de casting à la ressource Sprite frames Oui, je vais le régler à 12 images par seconde, pas en boucle Et j'ajouterai un cadre vide à la fin de l'animation, puis je le déplacerai de 18 pixels vers le haut avec le décalage Y. Cela semble bien, mais si nous l'associons au personnage Sprite, il se retournera également dans la même direction que le personnage En sélectionnant le nœud Animation Player, nous pouvons dupliquer n'importe des animations existantes pour créer une animation de casting. Après avoir supprimé les pistes inutiles et mis à jour toutes les images-clés de la région Sprite, nous ajouterons des pistes de méthode d'appel à la fois au nœud racine du personnage et l'effet de casting Animated Sprite no two D. Pour l'effet de casting, il suffit de lui dire Pour le personnage, nous allons ajouter une image-clé pour tirer le projectile Ces images-clés peuvent facilement être ajustées pour apparaître à tout moment pendant l'animation du casting Je vais lancer l'effet Cast sur la deuxième image et lancer le projectile sur la troisième image. Le reste de l'animation servira de restauration. Dans l'arbre d'animation, il suffit de répéter le même processus que celui utilisé avec le tiret. La transition vers le casting est activée, et nous reviendrons au mouvement à la fin de l'animation Ensuite, assemblons le projectile lui-même. Commencez par ajouter une note en D de zone 2 à la scène du personnage. Donnez-lui ensuite une forme de collision et une ressource de forme. J'utiliserai un cercle mais je réduirai son rayon à huit pixels, et je changerai sa couleur de débogage pour une couleur que je n'ai pas encore utilisée, comme le violet Ajoutez ensuite un sprite animé à déchiffrer et donnez-lui une ressource Sprite frames Tout d'abord, nous allons ajouter les images de sprite pour le projectile tel que nous voulons qu'il démarre et les utiliser comme animation Sprite par défaut Cela sera mis en boucle et je réglerai ma fréquence d'images à 12 images par seconde. Ensuite, nous cliquons sur le bouton Ajouter une animation pour créer une deuxième animation Sprite et la nommer quelque chose comme Impact Nous pouvons maintenant ajouter d'autres images Sprite pour une animation d'impact qui sera jouée par le même projectile lorsqu' il entre en collision avec Vous pouvez également ajouter une image vide à la fin de cette animation pour permettre à la dernière image de s'afficher pendant toute sa durée. N'oubliez pas de configurer l' animation par défaut pour qu'elle se lance automatiquement Nous jouerons donc cette animation lorsque le projectile sera généré Toujours dans la scène du personnage, repositionnez le projectile à l'endroit où vous souhaitez qu'il commence par rapport au Vous pouvez faciliter cette opération en sélectionnant le projectile et l'arbre de scène et en maintenant la touche Alt enfoncée pendant que vous le déplacez Le mien est à 12 pixels vers la droite et vers le haut par rapport à l'origine du personnage. Ensuite, ajoutez un marqueur à deux nœuds en D en tant qu'enfant du projectile Cela permettra de s'assurer que sa position correspond exactement à celle du projectile Le marqueur vers un nœud D est exactement le même qu'un nœud deux D, sauf qu'il dessine un petit gadget dans l'éditeur afin que nous puissions voir exactement où il se trouve Cela nous donne la position où nous voulons faire apparaître le projectile dans notre scène lorsque nous lançons le sort Nous pouvons donc nommer le nœud Marker Tutti en conséquence. Rétablissez ensuite le lien entre le nœud Marker Tutti et le personnage Sprite Comme il s'agit d'un enfant du personnage Sprite, il inversera son exposition lorsque le personnage changera automatiquement de direction Enregistrez la branche du projectile en tant que scène à part entière et enregistrez-la dans un nouveau dossier de scènes pour les projectiles Supprimez-le ensuite de la scène du personnage. Nous avons maintenant un projectile et nous savons où nous voulons le faire apparaître Nous allons donc revenir au script du personnage du joueur Nous pouvons exporter le projectile sous forme de scène pleine et le remplir dans l'inspecteur Nous pouvons également récupérer une référence au marqueur d'apparition. Il vaudrait mieux qu'il ait un nom unique. Et nous devrons spécifier le coût magique du tir de ce projectile Je vais fixer le mien à 16 points magiques. Avant de permettre au joueur de commencer à lancer le sort, nous devons également vérifier s'il possède suffisamment de points magiques en vérifiant si sa magie actuelle est supérieure ou égale au coût magique. Ensuite, lorsque l'animation du casting appelle la fonction de tir au projectile, étant donné qu'il s'écoule un très court laps de temps entre le moment où ces deux fonctions sont appelées, il n'est pas mal de vérifier qu' suffisamment de magie au personnage reste suffisamment de magie au personnage pour lancer à nouveau le sort ici Donc, si vous vérifiez si la magie actuelle est inférieure au coût, fait de revenir à cette fonction ne déclenchera pas le projectile Sachant que ce n' est pas le cas, nous pouvons soustraire le coût de notre magie actuelle et émettre le signal de changement magique actuel pour mettre à jour le HUD Ensuite, nous allons créer un nouveau projectile en instanciant la Nous ne voulons pas qu' il suive le personnage lorsqu' enfant, mais plutôt comme un frère ou une sœur dans le monde, afin qu'il puisse se déplacer tout seul Nous allons donc d'abord consulter le parent avant d'ajouter ce projectile étant enfant Définissez ensuite sa position dans le monde comme étant la globale du marqueur d'apparition des projectiles Nous devons utiliser la position globale ici car la position locale du marqueur est liée à la position du personnage, mais le projectile est ajouté au nœud mondial, pas au personnage Nous voulons donc connaître la position du marqueur par rapport au monde. Enfin, nous indiquerons ce projectile dans quelle direction il tire Nous pouvons passer un argument sous forme de vecteur à deux points vers la gauche si le personnage est orienté vers la gauche ou vers la droite, sinon. Nous devons maintenant écrire cette fonction pour notre projectile, en ouvrant la scène du projectile, ouvrant la scène du projectile, puis en ajoutant un script à son nœud racine, nous le nommerons Projectile et l'enregistrerons dans le dossier Il sera utile de donner un nom de classe à ce script afin que nous puissions y faire référence ultérieurement. Ce projectile aura besoin de certaines variables exportées, comme la vitesse à laquelle il se déplace et l'ampleur des dégâts qu'il inflige lorsqu' il touche un objet. Je vais nommer ce dommage par défaut afin qu'il puisse être annulé et je lui donnerai la valeur un Nous aurons également besoin d'une référence au nœud Animated Sprite Tu Di pour lui indiquer l' animation à jouer Il doit savoir dans quelle direction il est tiré et combien de dégâts il infligera réellement, si ce n'est pas le cas par défaut, et s'il se déplace actuellement ou non. Lorsqu'on nous demande de tirer, nous pouvons accepter la direction sous forme de vecteur deux et le montant des dégâts sous forme d'entier avec une valeur par défaut de zéro, ce qui en fait un paramètre facultatif. Nous allons définir la direction en fonction du paramètre de direction et retourner le sprite si le point de direction X est inférieur à zéro, c'est-à-dire à gauche Définissez ensuite dommage par dommage si une valeur de dommage a été fournie, sinon, utilisez les dégâts par défaut pour les dommages, et enfin, le réglage passe à vrai. Annulation de la fonction du processus. Si ce projectile est en mouvement, nous pouvons définir sa position comme étant plus égale à la direction multipliée par la vitesse multipliée par Delta Ce projectile devra entrer en collision à la fois avec des corps et des zones Nous devrons donc connecter au script à la fois les signaux relatifs à la zone saisie et aux signaux saisis dans le corps. Les corps avec lesquels ce projectile entrera en collision seront situés sur le terrain, tandis que les zones seront des boîtes à blessures Les deux auront à peu près les mêmes effets. Nous appellerons donc une fonction privée distincte deux et la nommerons en fonction de son impact. Lorsque le projectile touche un objet, il arrête de bouger, puis nous désactivons toute autre collision en mettant son masque de collision à zéro Cela désactive toutes les couches du masque de collision. Ensuite, lancez l' animation d'impact et connectez le signal de fin d'animation à la fonction quart supprimer automatiquement le nœud de la scène. Si le projectile touche une boîte à blessures, nous pouvons indiquer à cette boîte de blessures de subir le montant des dégâts avant de déclencher l'impact Nous n'utilisons pas le paramètre body, nous pouvons donc le marquer comme non utilisé avec un trait de soulignement Si le projectile ne touche rien, nous devons tout de même le nettoyer. Une méthode simple consiste à faire en sorte que la pièce la détruise automatiquement lorsqu' elle quitte la pièce dans laquelle elle a été créée À partir du script de la pièce, plutôt que de connecter ce signal à l'inspecteur à chaque fois pour chaque pièce, il serait plus facile de le faire par le biais d'un script Nous allons donc écrire une fonction sortant d'une zone, acceptant une zone comme un numéro deux D et en ne renvoyant aucune valeur Si la zone qui est sortie de cette pièce était un projectile, nous la mettrons en file d'attente pour être libérée de l'arbre des scènes Connectez ensuite le signal de sortie de la zone dans la fonction Prêt. Nous pouvons également le faire pour connecter automatiquement les signaux saisis par le corps. N'oubliez pas que si ces signaux sont déjà connectés à l'une des scènes de votre pièce, vous devez les déconnecter pour éviter les erreurs. Mais au fur et à mesure que nous créons des centaines de pièces, fait de créer ces connexions de signaux automatiquement par script nous permettra d'économiser beaucoup plus de temps et d'efforts Pour que le collisionneur de la pièce détecter un projectile qui en sort, il doit masquer la couche de collision sur laquelle se trouve le projectile lui-même En lançant le jeu, je commence déjà avec toutes les capacités débloquées dans la vidéo précédente et ma jauge magique est pleine Je vais ouvrir l'arborescence des scènes distantes pour voir apparaître mon projectile et me faire nettoyer De retour au jeu, appuyez sur le bouton de tir pour lancer un sort qui lance le projectile Le projectile entre en collision avec le mur et explose Ma jauge magique est réduite par le coût du sort. En visant dans l'autre sens, le projectile n'a rien à toucher et quittera donc la pièce actuelle Mais au lieu de continuer à s'envoler vers l'infini, il sera détruit une fois qu'il quitté les limites de cette pièce. Nous avons maintenant toutes nos capacités à débloquer dans le jeu, et nous sommes prêts à commencer à ajouter Je vous verrai dans la section suivante. 50. Rythme 7-1: Bonjour, mes amis. Dans cette section, nous allons ajouter des ennemis à notre jeu. Je vais commencer par créer un nouveau dossier pour contenir mes sprites ennemis et importer une feuille de sprites de mon premier ennemi, la souris aveugle Nous aurons également besoin d'un nouveau dossier de scènes pour les ennemis. Nous pouvons faciliter les choses en dupliquant notre personnage de joueur existant pour l'utiliser comme modèle pour créer notre ennemi. Déplacez-le ensuite dans le dossier de l'ennemi. En ouvrant la nouvelle scène, je vais renommer le nœud racine pour qu'il corresponde au nom de la scène Parcourez ensuite la hiérarchie des scènes et déterminez quels nœuds sont nécessaires à l'ennemi et lesquels ne le sont pas. Nous aurons toujours besoin d' une forme de collision pour entrer en collision avec le terrain, d'une boîte à blessures pour encaisser des dégâts et d'un sprite pour dessiner le personnage Mais les enfants du Sprite ne sont pas nécessaires, car cet ennemi n'a pas d'autres sprites ni la capacité de tirer des projectiles Nous conserverons le lecteur d'animation, l'arborescence et les nœuds d'effets sonores, mais vous souhaiterez peut-être modifier les sons. Le chronomètre Coyote ne sera pas nécessaire. à vous de décider si vous voulez ou non que vos ennemis C'est à vous de décider si vous voulez ou non que vos ennemis soient dessinés sur la carte, mais vous devrez évidemment modifier la texture si vous décidez de conserver l'icône de la carte. Et nous pouvons également supprimer tous les nœuds de capacité. Le script du personnage du joueur est attaché au nœud racine. Nous devrons le remplacer par le script de personnage normal, car il le script de personnage normal, ne s'agit pas du personnage du joueur et il ne possède aucune des capacités du personnage du joueur. En sélectionnant le nœud Sprite Toti, nous pouvons remplacer la propriété atlas des textures de l'atlas par une feuille Sprite pour Comme la feuille de sprites est différente de celle du personnage de mon joueur, je dois parcourir chacune de mes animations dans mon nœud Animation Player et vérifier que le nombre d' images et les valeurs de région saisies sont corrects Cet ennemi possède moins d' animations que le personnage du joueur, donc je peux tout supprimer sauf le fait de rester inactif et de marcher. L'animation inactive fonctionne correctement, car les valeurs des régions saisies correspondent exactement, mais pas celles de l'animation de marche Je vais donc devoir la corriger pour qu'elle corresponde aux valeurs des régions de la feuille de sprites Je vais rapidement mettre à jour les valeurs de la région Y saisies pour que cette animation fonctionne Nous allons ignorer les animations « hit and dead » pour le moment, car nous ne pouvons pas encore les tester. L'arbre d'animation aura besoin d'une machine à états beaucoup plus simple pour cet ennemi, non la même que celle utilisée par le personnage du joueur. Nous allons donc créer une nouvelle ressource de machine à états. Ajoutez ensuite les animations de ralenti et de marche passant du mode démarrage au mode veille par défaut pour marcher si la vélocité X n'est pas nulle, puis revenez au mode veille si la vélocité X est nulle C'est tout ce que cet ennemi doit faire pour le moment. Si je regarde le script du personnage pendant un moment, il contient déjà tout ce dont nous avons besoin pour faire avancer un personnage dans les deux sens. Comme je ne veux pas mes ennemis passent du temps à jouer au coyote, je dois soit déplacer le code pour qu'il ne figure que dans le script du personnage du joueur, soit simplement m' assurer qu'aucun code lié au temps du coyote ne s'exécute s'il n'y a pas de temps ou de nœud Coyote Comme j'ai déjà utilisé la fonction get node ou null pour vérifier la présence du nœud Coyote Timer, cette variable sera nulle si aucun nœud de ce type n'existe La seule fois où nous utilisons le nœud Coyote Timer, c'est dans le processus physique, et nous pouvons simplement vérifier s'il existe un nœud Coyote Timer avant d'essayer appeler fonction de démarrage pour Ce même processus peut également être utilisé si vous ne souhaitez pas inclure exactement les mêmes nœuds dans les différentes scènes de votre personnage et de vos ennemis pour des éléments tels que les sons ou les effets de particules. Passons à l'une de nos scènes de contenu de salle existantes et ajoutons ce nouvel ennemi à la pièce. Mon plan pour cet ennemi est de le faire avancer et revenir. Quand ils heurtent un mur, je veux qu'ils fassent demi-tour, qu'ils attendent une seconde, puis qu'ils marchent dans la direction opposée. Je vais donc modifier mon terrain pour créer une plate-forme simple avec des murs de chaque côté. Cet ennemi va donc faire des allers-retours ici. J'ajouterai également une autre plateforme sans murs, et l'ennemi devrait quitter le rebord dans ce cas Vous souhaiterez peut-être écrire un autre script, comme le script du personnage du joueur héritant du personnage, qui inclut également ce comportement Mais il vaut mieux considérer ce comportement comme une alternative au nœud joueur dans la scène de jeu, grâce auquel le joueur peut contrôler le personnage du joueur. Au lieu de cela, nous écrivons un script qui contrôle le comportement de cet ennemi. Nous allons donc créer un nouveau nœud en tant qu'enfant de l'ennemi. Je vais appeler ce nœud pace. De cette façon, le même script de comportement peut être utilisé pour plusieurs ennemis différents, et le même type d'ennemi peut également avoir plusieurs scripts de comportement différents. inclusion de ce nœud dans la scène de l'ennemi le ferait automatiquement appliquer à tous les ennemis du même type. Cependant, le placer dans la scène du contenu de la pièce permettra aux mêmes ennemis d' avoir des comportements potentiellement différents. Nous allons joindre un script à ce nœud et placer dans un nouveau dossier de scripts pour les ennemis. Pour indiquer à un ennemi ce qu'il doit faire, nous avons besoin d'une référence à l'ennemi lui-même stockée dans une variable. Nous pouvons appeler la fonction G parent pour obtenir le parent direct de ce nœud et l'attribuer à la variable à l'aide de la balise ready. Notez que cela ne fonctionnera que si le nœud de comportement est un enfant direct de l'ennemi. Nous devrions également exporter une variable pour indiquer dans quelle direction cet ennemi ira en premier. Je vais donc le nommer direction et lui donner une valeur par défaut de un, c'est-à-dire vers la droite. annulant la fonction du processus, il suffit de définir la direction de déplacement de l'ennemi cette direction pour qu'il commence à marcher Lorsque l'ennemi est sur un mur, nous pouvons dire au personnage de faire face à la gauche et de régler sa direction de déplacement à zéro pour qu'il s'arrête. Pour attendre un court instant, nous avons besoin d'une minuterie. Comme ce nœud n'a pas de type, nous pouvons utiliser ce nœud comme temporisateur lui-même en modifiant son type. Le type étendu par ce script devra également être remplacé par timer afin d'accéder à l'un des nœuds, propriétés ou fonctions du temporisateur. Nous n'avons pas besoin de connecter le signal de temporisation, car tout ce que nous avons vraiment besoin de savoir c'est si le chronomètre est arrêté ou non Si le chronomètre est arrêté, nous réglerons la direction de déplacement de l'ennemi par direction. Sinon, nous pouvons le mettre à zéro car cet ennemi attend actuellement. Lorsque le personnage heurte un mur, nous définissons la valeur de direction comme étant le sinus du mur X normal et nous démarrons le chronomètre. Pour que le personnage fasse face droite lorsqu'il heurte un mur à sa gauche, nous devons également faire en sorte que cela dépende du sinus X normal des murs. Nous voulons également arrêter le personnage et le faire demi-tour uniquement si sa direction de marche actuelle n'est pas la même que celle normale des murs Nous appelons cette fonction normale get Wall à plusieurs reprises, il serait donc plus efficace de la stocker dans une variable locale. Faisons quelques refactorisations légères ici. Dans la scène du contenu de la pièce, nous pouvons ajuster le temps d' attente et définir la propriété one shot sur true. Je vais dupliquer le nœud de rythme et l'attacher à l'autre ennemi. Donnez ensuite à mes deux ennemis des valeurs différentes pour leur direction initiale. Maintenant, lorsque nous lançons le jeu, à l'aide de notre script comportemental, les ennemis suivent le rythme, l'un vers la gauche et l' autre vers la droite. Le deuxième ennemi sort du rebord, mais le premier heurte le mur, fait demi-tour et attend une seconde avant de faire demi-tour et de marcher dans l'autre sens Et ils répètent tous les deux ce comportement. Mais vous avez peut-être remarqué que leurs animations ne correspondent pas toujours à leur vélocité. Les deux personnages s' animent en fait de manière synchronisée En effet, tout comme les icônes de santé, elles partagent une ressource. Dans la scène des ennemis, nous devrons sélectionner le nœud Sprite two D et faire ressource de texture de l'atlas soit locale à cette scène Désormais, chaque instance de cet ennemi aura sa propre texture d'atlas et nous pourrons l'animer indépendamment les unes des autres Toutefois, si l'une de vos animations modifie la propriété de texture du nœud Sprite two D, cela risque de casser les animations qui y font référence Je vais supprimer cette piste de mon animation de réinitialisation. Nous n'avons pas non plus besoin de la connexion par signal, qui a été copiée depuis la scène du personnage du joueur, qui est utilisée pour jouer à Jump Efforts. relançant le jeu, nous pouvons maintenant voir qu'ils sont capables de jouer correctement à leurs animations inactives et de marche. Nous avons maintenant un ennemi capable de faire des allers-retours, se retourner contre les murs, mais nous devons également nous assurer qu'il ne puisse pas quitter la pièce. Je vous verrai dans la prochaine vidéo. 51. 7-2 Murs invisibles: Bonjour, mes amis. Dans cette vidéo, nous allons empêcher nos ennemis de quitter la pièce dans laquelle ils sont apparus Pour ce faire, nous aurons besoin que nos ennemis entrent en collision avec des murs invisibles qui n'affectent pas le personnage du joueur. Nous avons le corps du personnage du joueur sur la couche de collision 9, masquant le terrain sur la première couche Dans notre scène d'ennemis, nous allons régler la couche de collision corporelle sur une autre couche , comme la couche 17. Ils doivent toujours masquer la couche de terrain, mais nous leur demanderons également de masquer une deuxième couche que nous utiliserons pour les murs invisibles. Je vais utiliser la couche 5. En ouvrant les paramètres du projet, couche s'appelle Physics two D. Je nommerai la couche 17 comme ennemie et la couche 5 comme murs invisibles. Dans la scène de ma pièce, je vais copier le nœud de la couche Tile Map, qui dessine la carte, puisqu' il contient déjà les limites de la pièce. Collez-le ensuite dans la scène de contenu et renommez-le en Invisible walls fois la note de couche Tile Map sélectionnée, en cliquant sur la ressource Tile set, nous devrons ajouter une couche physique à cette série de tuiles, existant sur la couche 5 pour les murs invisibles. À partir du panneau Tile set, nous pouvons peindre cette couche physique sur le carreau. passant au panneau Tile Map avec l'outil de peinture et la tuile sélectionnés, nous pouvons fermer les portes de cette pièce, scellant ainsi complètement la pièce de tous les côtés avec une couche physique masquée uniquement ennemis et non par le personnage du joueur Nous ne voulons pas que ces murs invisibles soient dessinés sur la carte Ils ne devraient donc pas figurer sur la deuxième couche de visibilité, et nous voulons pouvoir les voir pendant les tests. Mettons-les sur la première couche de visibilité. Je vais modifier le terrain et déplacer mes ennemis afin qu'ils puissent se déplacer librement dans toute la pièce. Maintenant, lorsque nous lançons le jeu, les ennemis marchent vers le bord de la pièce mais sont renversés par les murs. Alors que le personnage de notre joueur peut les traverser. Je préférerais que ces murs soient situés en dehors de la zone visible de la pièce, alors je vais les déplacer d' un carreau de plus. Pour rendre les murs complètement invisibles pour le joueur, il suffit de désactiver leur propriété visible, que joueur, il suffit de désactiver leur propriété visible, soit dans l'arbre de la scène ou dans l'inspecteur Nous devons maintenant faire en sorte que cet ennemi réellement une menace pour le joueur, ce que nous avons déjà fait auparavant. Tout ce que nous avons à faire est d'ajouter une zone au nœud D, de la nommer et de cliquer sur Box. Donnez-lui une forme de collision au nœud D étant enfant et donnez la forme de collision le nœud Tut une ressource de forme Réglez la zone de frappe pour masquer la zone de blessure du joueur. Et il doit s'agir d'une surveillance. Joignez ensuite le script Hit box et connectez le signal saisi sur la zone. À heure actuelle, lorsque nous lançons le jeu, le contact physique avec un ennemi cause des dégâts au personnage du joueur. Nous verrons comment rendre le combat plus engageant dans la section suivante. Pour l'instant, traitons ces messages d'erreur. Ces messages d'erreur apparaissent lorsque nous chargeons le contenu d'une pièce. Cela est dû au fait que nous chargeons le contenu de la pièce en réponse à une collision lorsque le corps du personnage du joueur entre dans une pièce. Et Godot n'aime pas que nous ajoutions nouvelles zones de collision ou d'objets alors qu'il est déjà occupé résoudre les collisions pour cette image en cours Donc, si nous suivons les conseils donnés par les messages d'erreur et que nous utilisons le terme « différé », cela indiquera au moteur de jeu de charger le contenu de la pièce fois la résolution de collision terminée pour l' image en cours. cycle de Godot commence traitement des entrées, puis par la physique, qui inclut les collisions, puis traite et se termine par des appels différés Nous pouvons donc l'utiliser pour effectuer n'importe quelle action que nous voulons comme dernière chose avant la fin d'une image. En relançant le jeu, il n' y a plus de message d'erreur. Notre ennemi va maintenant rester dans cette pièce et peut blesser le personnage du joueur. Mais nous devons ajouter une plus grande variété d' ennemis à notre jeu. Je vous verrai dans la prochaine vidéo. 52. 7-3 Détection de ranges: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un autre ennemi capable de détecter les coins et de faire demi-tour au lieu de s'en éloigner. Nous allons commencer par dupliquer notre ennemi actuel. En ouvrant la scène ennemie, nous allons modifier le nom du nœud racine pour qu'il corresponde à celui de l'ennemi. Importez leur feuille de sprites et définissez-la comme atlas dans l'inspecteur Tous les sprites de la feuille Sprite sont les mêmes que ceux du premier ennemi, y a donc rien à corriger en termes d'animations Dans la scène du contenu de ma chambre, je vais supprimer les deux ennemis et ajouter ce nouvel ennemi, puis modifier le terrain pour qu'ils se trouvent une terrasse surélevée avec un rebord de chaque côté à des hauteurs différentes Je veux que cet ennemi s'arrête sur le rebord supérieur, attende un moment, puis fasse demi-tour et marche dans l'autre sens Mais ensuite, ils devraient quitter le rebord le plus court. En ce qui concerne les murs, ils devraient agir de la même manière que l'ennemi précédent. Comme ce comportement est très similaire, il serait bon d' utiliser le même script. Je vais donc ajouter une note de chronomètre en tant qu'enfant de l'ennemi. Renommez-le, associez-y le script de rythme et définissez sa propriété one shot sur true Cet ennemi doit donc se comporter exactement comme une souris aveugle. Il ne nous reste plus qu' à déterminer quand l'ennemi marche vers une corniche, ce que nous pouvons faire en utilisant un nouveau type de nœud, un nœud en deux D coulé Nous appellerons ce détecteur de bord de nœud. Déplacez-le ensuite d'une courte distance vers la droite du personnage et vers le haut. Le rayon possède un masque de collision qui est déjà configuré en couche 1 pour le terrain. En élargissant la section de collision, notre terrain est un corps physique, sorte que le rayon va entrer en collision avec lui Si vous utilisez un nœud de diffusion de rayons pour détecter des zones, vous devrez vérifier les zones ici avant que cela ne fonctionne. Le rayon est représenté dans l'éditeur sous forme de flèche, mais il sera invisible pendant le jeu, tout comme nos nœuds de zone de collision. Il émet un rayon en partant de sa position dans la direction de la flèche et indique s'il touche ou non quelque chose. Dans ce cas, qu'il touche le terrain ou non. Donc, s'il touche le terrain, l'ennemi continuera à avancer, et si ce n'est pas le cas, le personnage doit s'arrêter. La distance à droite du personnage déterminera jusqu'où il cherchera le rebord La distance par rapport au sol n'aura pas beaucoup d'effet tant qu'elle est au-dessus du sol et en dessous de la hauteur du personnage. La position de la cible doit être dirigée vers le bas afin de détecter le sol, mais la distance à laquelle le rayon est projeté aura une incidence sur ce qu'elle considère comme une corniche et sur ce qu'elle ne l'est pas Je vais régler le mien à 64 pixels ou à deux tuiles. Cela signifie que si l'ennemi rencontre une corniche haute d'une seule tuile, il partira quand même. Mais si la hauteur est de deux tuiles ou plus, le rayon n'atteindra pas le terrain et, par conséquent, l' ennemi s'arrêtera. Contrairement aux zones de collision, le nœud de diffusion des rayons n' émet aucun signal auquel nous pouvons réagir. Nous devrons donc joindre notre propre script à ce nœud. Je vais le mettre dans le dossier des scripts ennemis. Nous pouvons commencer par déclarer notre propre signal, que nous voudrons admettre lorsqu'un rebord est détecté et le transmettre dans la direction du rebord par rapport à l' ennemi sous la forme d'un entier ce n'est pas aussi simple que de savoir si Mais ce n'est pas aussi simple que de savoir si le rayon frappe quelque chose ou non. même manière que nous avons fait en sorte que le chronomètre Coyote ne démarre que sur l'image exacte lorsque le personnage sort d'un rebord, nous ne voulons détecter un rebord qu' une seule fois pendant l'image exacte lorsque le rayon cesse d'entrer en collision avec le terrain Nous aurons donc besoin d'une variable booléenne indiquant si le rayon a touché le terrain dans la dernière image et quatre autres s'il a touché le terrain dans cette Au cours du processus physique, nous allons définir si la collision est entrée en collision la valeur précédente de est en collision, puis I entre en collision avec valeur actuelle renvoyée par le Si le rayon est entré en collision dans la dernière image mais qu'il n' entre pas en collision avec cette image, c'est à ce moment précis que nous avons détecté un rebord et que nous émettrons notre signal La direction du rebord peut simplement être le signe de la position du nœud Connectons le signal détecté par le rebord au script Pace et appelons une fonction nommée wait and turnaround Nous pouvons copier ces trois lignes vues d'en haut, qui indiquent à l'ennemi de s'arrêter, modifient le sens du rythme et démarrent le chronomètre Remplacez-les ensuite par un appel à notre fonction. Mais nous devrons transmettre l'opposé de la normale X de la paroi comme argument de direction pour correspondre à ce qui est transmis par le détecteur de bord. Le détecteur de rebord envoie la direction vers le rebord. Ici, nous devons donner la direction vers le mur. La nouvelle direction de stimulation est donc l'inverse du paramètre de direction Cela fonctionnera tant que l'ennemi se déplace vers la droite, mais nous devrons repositionner le nœud de distribution vers la gauche de l'ennemi lorsqu'il fera demi-tour Heureusement, nous avons déjà émis un signal chaque fois qu'un personnage change de direction. Il suffit donc de connecter ce signal au détecteur de bord pour y réagir. Renommons-le si l'ennemi change de direction. Puisque cela nous donne leur nouvelle direction, nous allons simplement définir la position du nœud comme étant la valeur absolue de sa position multipliée par moins un si direction est inférieure à zéro ou positive un dans le cas contraire. Retracez l'omission de ce signal de changement de direction jusqu'au script du personnage. À l'origine, je l'ai écrit en passant la variable de direction du déplacement comme paramètre de signal. Cependant, cela ne fonctionne pas dans le contexte dans lequel nous utilisons ce personnage ennemi, car la valeur de la direction de déplacement ne correspond pas nécessairement à la direction dans laquelle nous lui disons de faire face. Ainsi, plutôt que de transmettre la direction du mouvement, il est plus précis de passer un point négatif si vous demandez au personnage de faire face à gauche ou de passer un point positif pour la droite. Désormais, le ray cast dende sera toujours devant le personnage, qu' il soit orienté vers la gauche ou vers la droite Activons les formes de collision visibles pour voir le rayon projeté pendant le jeu, puis appuyons sur Play. Le rayon projeté est dessiné en rouge lorsqu'il entre en collision avec quelque chose Notre ennemi s'approche de la première corniche. Le rayon projeté devient bleu pour indiquer qu'il ne touche rien, et l'ennemi s'arrête pendant une courte période, puis fait demi-tour et part dans l'autre sens. À l'approche du rebord le plus court, le rayon projeté est suffisamment long pour atteindre le terrain, de sorte que l'ennemi s'éloigne et continue dans la même direction Ils finissent par heurter le mur invisible situé aux extrémités de la pièce et font demi-tour comme le faisait l'ennemi précédent. Nous avons maintenant un deuxième type d'ennemi qui se comporte différemment du premier, mais nous avons besoin de beaucoup plus de variété pour rendre notre jeu amusant Je vous verrai dans la prochaine vidéo. 53. 7-4 Voler: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un ennemi volant qui rebondit dans une pièce Commençons par importer une nouvelle feuille de sprites pour l'ennemi volant Ensuite, dupliquez l'une des scènes ennemies existantes. Après avoir ouvert la nouvelle scène ennemie, nous renommerons le nœud racine pour qu'il corresponde à l'atlas et remplacerons corresponde à l'atlas et remplacerons la feuille de sprites appropriée Ces sprites mesurent 32 pixels carrés, contrairement aux autres ennemis rencontrés jusqu'à présent Je vais donc ajuster la position Y du Sprite maintenant pour l' abaisser légèrement Cet ennemi ne possède pas distinctes pour les animaux inactifs et les animations de marche Je vais donc supprimer l'animation de marche et modifier l'animation inactive pour obtenir le bon nombre d'images. Modifiez ensuite les valeurs saisies pour que l'animation inactive ait la bonne hauteur en pixels L'animation inactive semble maintenant correcte. Pour ce qui est de la visibilité de la forme de collision du corps du personnage, je vais la faire pivoter de 90 degrés pour que la capsule soit horizontale, ce qui correspond le mieux à la forme de cet ennemi, et j'ajusterai son rayon et sa hauteur selon les besoins. Faites ensuite la même chose avec la Hurt Box. Et les dégâts de contact frappent la case, en veillant à ce qu'ils correspondent à la taille et à la forme de l'ennemi, sorte que les dégâts infligés au joueur soient justifiés. En ce qui concerne la machine à états Animation Tree, puisqu'il n'existe qu'une seule animation à l'heure actuelle, elle n'a besoin que d'un état inactif passant du mode démarrage au mode veille En ce qui concerne le script attaché au nœud racine de cet ennemi, nous n'avons pas besoin que cet ennemi marche ou saute, mais nous avons tout de même besoin que cet ennemi soit capable de faire face à gauche ou à droite, accélérer et de décélérer, être affecté par la gravité et la vitesse terminale, etc. Il y a donc suffisamment d'avantages à utiliser le même script de personnage ici plutôt que de repartir de zéro. Mais il y a suffisamment de différence dans le comportement d' un ennemi capable voler pour que nous devions écrire une nouvelle sous-classe héritant du caractère Créons donc un nouveau script nommé Flying Enemy, héritant du personnage, et enregistrons-le dans le dossier des scripts ennemis Notre ennemi volant aura besoin d'une direction pour voler. Contrairement à la marche ou à la course, qui sont représentées sous forme de flotteur, puisqu'il suffit de se soucier de l'axe X, une direction de vol peut être n'importe quelle direction dans l'espace D Nous allons donc la stocker dans un vecteur deux. Nous aurons également besoin d'une variable booléenne pour savoir si cet ennemi vole actuellement ou non Nous pouvons ensuite annuler le processus physique pour inclure une nouvelle vérification pour voir si l'ennemi vole, et si c'est le cas, appeler une fonction physique volante Si l'ennemi ne vole pas, nous pouvons considérer comme normale la définition du processus physique par une super classe . Vous pouvez également exporter une vitesse de vol sous forme de flotteur si vous souhaitez avoir un ennemi qui a vitesses de marche et de vol différentes. Je vais lui donner une valeur par défaut de 100 pixels par seconde. Je vais maintenir la touche Ctrl ou Commande enfoncée et cliquer sur cet appel de fonction au processus physique de la superclasse pour accéder directement à sa déclaration afin que nous puissions examiner ce qu'elle contient Notez que l'appel de la fonction move and slide fait partie de la définition de superclasse de notre processus physique Cette fonction doit être appelée pour appliquer le corps du personnage à la vélocité des nœuds D et vérifier l'absence de collisions Nous voulons également que notre ennemi volant fasse face à la direction dans laquelle il vole. Nous devrons donc le faire dans la fonction de physique du vol. Je vais copier ce bloc de code, revenir au script Flying Enemy et coller dans ma physique du vol. Plutôt que de vérifier la valeur de la direction du déplacement, nous devons vérifier la valeur du point X. Nous devrons également continuer à utiliser la fonction de déplacement et de glissement si l'ennemi vole. Nous pouvons ensuite appliquer la même logique que celle que nous avons utilisée pour le contrôle aérien à nos personnages non volants afin de faire voler notre ennemi volant. Si la direction de vol a une valeur, nous allons déplacer la vitesse de l' ennemi vers la direction de vol multipliée par vitesse de vol à un taux d' accélération multiplié par le contrôle aérien multiplié par le delta. Ou si aucune direction de vol n'est donnée, nous pouvons déplacer leur vitesse vers le vecteur deux point zéro à un taux de décélération multiplié par le nombre d' aérofreins multiplié par O. Lorsque nous ne modifiions que le point de vélocité X, qui est un float, un type de données primitif, nous avons dû appeler la fonction Godot move towards pour le modifier Mais comme un vecteur deux est une classe, il peut avoir ses propres fonctions. Maintenir la touche Ctrl ou Commande et cliquer sur le nom de la classe nous amène à la documentation de cette classe où nous pouvons voir toutes ses propriétés et fonctions si nécessaire. Nous avons donc ici la possibilité d' appeler velocity dot move towards, ce qui diffère de la fonction Godot move towards en ce que le premier paramètre est déjà connu sous le nom de vecteur lui-même Vous pouvez également exporter différentes valeurs pour l'accélération, la décélération, contrôle aérien et les freins à air pour vos ennemis volants si vous souhaitez qu'ils utilisent des valeurs différentes lorsqu'ils ne volent pas Nous aurons également besoin d'une fonction publique qui indique à cet ennemi de voler, acceptant un paramètre vectoriel à deux pour la direction à suivre. Et une autre pour savoir quand arrêter de voler. Cela permettra de contrôler la variable de vol et de définir la direction du vol en même temps. N'oubliez pas d'attacher ce script d'ennemi volant au nœud racine de l' ennemi dans sa propre scène. Dans la scène du contenu de la pièce, tout comme nos ennemis existants ont un nœud séparé leur indiquant comment se comporter, nous ferons de même avec notre nouvel ennemi volant. Je vais supprimer cet ennemi de la scène et ajouter deux de ces nouveaux ennemis volants. Ensuite, je modifierai le terrain pour placer l'un d'entre eux dans une zone de terrain afin que nous puissions voir comment il se comporte un peu plus facilement Je veux que ces chauves-souris volent en diagonale et rebondissent sur tout mur, plafond ou sol avec lequel elles entrent en contact Donc, en attachant un nœud de base aux deux, je le nommerai ricochet Attachez ensuite un script à ce nœud et enregistrez-le dans le dossier des scripts ennemis. Ce script aura besoin d' une variable exportée pour la direction de vol initiale. Je vais utiliser le vecteur 21, qui est en bas à droite. Nous aurons également besoin d'une référence à l'ennemi dont nous contrôlons le comportement défini sur ce nœud, parent utilisant le tag on ready. En remplaçant la fonction Ready, il serait judicieux de normaliser la direction du vol. La normalisation d'un vecteur garantit que sa longueur est exactement égale à un Comme un vecteur d'une valeur de 11 est plus long qu'un, la chauve-souris volerait plus vite que sa vitesse de vol. Mais si nous normalisons le vecteur, nous n'utilisons que la direction du vecteur, pas sa longueur. annulant la fonction du processus, nous pouvons dire à l'ennemi de voler dans la direction de vol souhaitée. Mais avant cela, nous devons vérifier si cet ennemi est actuellement en contact avec un mur, un plafond ou un sol. Nous pouvons ensuite régler le point de direction de vol X ou point et Y sur la valeur appropriée dans tous ces cas. Pour le plafond, la valeur sera valeur absolue du point de direction de vol Y, ce qui le rendra toujours positif, c'est-à-dire vers le bas. Et le plancher est le contraire, multipliant la valeur absolue par moins un, ce qui correspond à la hausse. Pour les murs, nous pouvons simplement multiplier la valeur absolue du point X de direction de vol par le signe du point normal du mur X, qui pointe à l'opposé du mur. Je vais également associer le script de ricochet à l'autre ennemi, puis appuyer sur Play Lorsque nous lançons le jeu, nous pouvons voir la batte rebondir ricocher sur chaque mur, plafond et sol qu'elle touche, créant ainsi un obstacle intéressant à éviter pour le joueur Nous avons maintenant un ennemi volant à combattre, mais nous devrions au moins avoir un autre type d'ennemi à affronter pour nos joueurs. Je vous verrai dans la prochaine vidéo. 54. Crawl 7-5: Bonjour, mes amis. Dans cette vidéo, nous allons créer un ennemi capable de ramper sur n'importe quelle surface, y compris les murs et les plafonds Commençons par importer une feuille de sprites pour cet ennemi. Puis dupliquez l'ennemi volant. Après avoir ouvert la nouvelle scène ennemie, je renommerai le nœud racine Remplacez ensuite l'atlas de la texture d'atlas à deux nœuds en D du Sprite la feuille Sprite appropriée Dans le lecteur d'animation de l'ennemi, je vais mettre à jour l' animation inactive pour qu' elle contienne le nombre correct d'images fournies par la feuille Sprite Mise à jour des valeurs de région saisies selon les besoins. Comme nous voulons que cet ennemi rampe non seulement sur le sol, mais aussi sur les murs et le plafond, il serait utile de pouvoir le faire pivoter Avec l' origine de l'ennemi à ses pieds, comme nous avons créé tous les autres ennemis, les faisant pivoter, tout tournera autour de ce point. Pour faciliter un peu les choses, il serait préférable de placer le point d'origine des ennemis rampants en leur centre pour que ces rotations soient plus Je vais donc centrer le sprite et toutes les formes de collision sur le point d'origine Maintenant, lorsque nous faisons pivoter cet ennemi, il restera dans la même position relative. Je vais rapidement ajuster la zone de blessure et la zone frappe pour qu'elles correspondent mieux à la forme de cet ennemi. , pour la forme de collision du corps du personnage Cependant, pour la forme de collision du corps du personnage, j'utiliserai un cercle plutôt qu'une capsule. Comme cet ennemi peut pivoter, la forme de la collision étant un cercle, cela signifie que les rotations n'entraîneront aucune modification lequel cet ennemi entre en collision Si vous utilisez des rotations strictes à 90 degrés, une forme de collision carrée fonctionnerait également, mais nécessiterait quelques étapes supplémentaires lorsqu'il s'agit de coins convexes Je vais donc m'en tenir à un cercle. Dans la scène du contenu de la pièce, je vais retirer les chauves-souris et les remplacer par deux escargots Le but est de faire ramper ces escargots à la fois sur la surface intérieure et extérieure de cette boîte Tout comme nous avons créé un nouveau script inspiré du personnage pour les ennemis volants, nous allons en écrire un autre pour explorer les ennemis et l'enregistrer dans le dossier des scripts ennemis Remplacez ensuite le script attaché à l'ennemi par ce nouveau script. Je vais ralentir mon escargot en réglant sa vitesse de marche à seulement 32 pixels par seconde. abord, nous devons connaître la direction vers la surface dans laquelle cet ennemi rampe actuellement sous forme de vecteur deux Ensuite, la direction de rampage vers l'avant sous la forme d'un autre vecteur deux Nous devrons également gérer nos propres collisions ici plutôt que de nous fier la fonction de déplacement et de glissement du corps du personnage pour faire toute la physique à notre place. Nous pouvons donc stocker les données de collision dans une autre variable de type collision cinématique deux D. En passant outre au processus physique, nous allons vérifier si cet ennemi est actuellement collé à une surface, et si c'est le cas, appeler le processus physique pour S'ils ne sont pas collés à une surface, on peut parler de processus physique des superclasses Cela fonctionne car un vecteur deux avec ses valeurs par défaut de zéro, zéro sera traité par l'instruction if comme faux et toute autre valeur comme vraie. S'ils ne sont pas collés à une surface, nous voudrons également vérifier si cet ennemi peut s' en tenir à une surface. En appelant une fonction légèrement différente de celle de move and slide, nous appellerons move and collide Cette fonction accepte le mouvement du personnage comme premier paramètre, sa vélocité multipliée par Delta. La fonction renvoie une collision cinématique deux D, que nous pouvons attribuer à notre variable De la même manière que notre vecteur deux peut être utilisé dans une instruction if, pour ces données de collision. Si aucune collision n'est survenue, elle sera considérée comme fausse. Et si une collision se produit, elle sera considérée comme vraie. Si cet ennemi est entré en collision avec un objet, nous supposerons qu' il veut s'y tenir et nous définirons la valeur de coincé à la surface Nous pouvons accéder aux collisions normales en appelant la fonction get normal. Il s'agit d'un vecteur pointant à l'opposé de la surface avec laquelle le personnage est entré en collision au point de collision Puisque nous voulons que la valeur de cette variable soit dirigée vers la surface, non loin de celle-ci, nous pouvons simplement la faire pivoter 180 degrés en appelant la fonction de rotation Mais les rotations dans Godot n'utilisent pas de degrés. Ils utilisent des radians, et 180 degrés sont identiques à des radians Pi Oh, si l'ennemi n'est entré en collision avec aucune surface, nous appellerons le processus de physique des superclasses Mais le processus physique des superclasses consiste également appliquer la vélocité du personnage lorsqu'il appelle Move and Slide Selon ce code, la vélocité du personnage est appliquée deux fois par image tant qu'il ne touche aucune surface. Nous pouvons résoudre ce problème en passant un deuxième paramètre facultatif à la fonction move and collide, qui est un test nommé booléen Si elle est vraie, cette fonction vérifiera uniquement les collisions, mais ne déplacera pas réellement le personnage. Maintenant que notre ennemi s'accroche automatiquement à n'importe quelle surface, automatiquement à n'importe quelle surface, nous pouvons nous familiariser avec la physique consiste à ramper sur cette surface abord, nous appliquerons la gravité à la surface sur laquelle l'ennemi est coincé, comme nous ne l'avons pas fait pour le test de collision plus tôt, et cela aidera également à maintenir l'ennemi sur la surface sur laquelle il pour le test de collision plus tôt, et cela aidera également à maintenir rampe. appelant move and collide, passant la direction vers la surface, en multipliant par la gravité, en multipliant par Delta, nos données de collision enregistreront désormais la collision avec la surface Nous pouvons ensuite bifurquer en fonction du fait qu'une collision s'est produite ou non. Si l'angle de la surface change, nous pouvons mettre à jour la direction vers la surface de rampage, puis calculer la direction vers l' avant, qui est simplement la direction vers la surface pivotée de 90 Si Pi est de 180 degrés, alors Pi divisé par deux est de 90 degrés. Cependant, le sens de rotation dépend du fait que l'ennemi est orienté vers la gauche ou vers la droite. S'ils sont orientés vers la gauche, nous devons les tourner dans le sens des aiguilles d'une montre S'ils sont orientés vers la droite, nous les tournons dans le sens antihoraire pour obtenir leur direction orientée vers l'avant sous la forme d'un vecteur deux Et si ces valeurs ont changé depuis l'image précédente, nous devrons également mettre à jour la rotation de l'ennemi pour le dessiner correctement. Comme l'ennemi est orienté vers la droite dans sa scène avec une rotation de zéro, il suffit d'utiliser la direction avant d' appeler la fonction angle. La fonction angle renvoie l'angle entre n'importe quel vecteur deux et l'axe X positif. Mais comme nous utilisons une échelle X négative pour retourner le personnage lorsqu'il fait face à la gauche, nous devrons également corriger cela lors de la rotation, en effectuant une rotation supplémentaire de 180 degrés ou en Pi radians si l' ennemi est orienté vers la gauche Maintenant que l'ennemi est remonté à la surface et que nous savons dans quelle direction il veut ramper, et que nous savons dans quelle direction il veut ramper, si on lui demande de bouger, nous pouvons enfin utiliser à nouveau la fonction de déplacement et de collision pour le déplacer vers l'avant, multipliée par la vitesse de déplacement, multipliée par le delta S'il y a une collision à la suite de ce mouvement, signifie qu'ils sont entrés en collision avec un coin concave Tout ce que nous avons à faire ici est recalculer la direction vers la nouvelle surface Le prochain cadre physique s'occupera du reste. S'il n'y a pas eu de collision, l'ennemi rampe doucement sur une surface plane ou convexe Si aucune direction de déplacement n'a été donnée, ils resteront immobiles. en revenir à la première affirmation, si la gravité dirigée vers la surface n'a pas entraîné de collision, cela signifie que l'ennemi a perdu le contact avec la surface sur laquelle il rampait d'une manière ou perdu le contact avec la surface sur laquelle il rampait Nous devrions donc appeler une fonction qui les remettra à une orientation normale. Je vais le nommer unstick et le rendre public afin que d'autres scripts puissent l'appeler Cette fonction remettra la direction de la surface au vecteur 20 et la rotation à zéro, les ramenant à un état de comportement semblable à celui de n'importe quel autre ennemi. Il y a cependant encore une chose qui manque à notre physique rampante, c'est de dire à l'ennemi de faire face à la direction dans laquelle il se déplace, puisque cela se faisait dans le cadre du processus de physique des superclasses Plutôt que de copier-coller le même code ici, déplaçons-le dans une fonction privée de la classe de caractères Ensuite, nous pouvons appeler cette fonction à la fois dans ce script de personnage et dans le script d'exploration de l'ennemi Plutôt que de créer un nœud et un script séparés pour simplement dire à cet ennemi de ramper, j'exporterai une variable entière pour la direction de Krall Ensuite, remplacez la fonction du processus et faites-le ici. À des fins de test, je vais également annuler la fonction de saisie pour que flèche vers le bas les force à décoller de la surface sur laquelle ils rampent Lorsque nous lançons le jeu, l' escargot rampe autour de cette boîte, tournant à la fois dans les coins concaves et convexes pour grimper sur les murs et de nouveau pour ramper au plafond En appuyant sur la flèche vers le bas, ils se détachent de la surface et tombent sous l'effet de la gravité comme le ferait n'importe quel autre ennemi Nous avons maintenant notre dernier type d'ennemi, un ennemi capable de ramper sur les murs et les plafonds Mais nos ennemis devraient être plus agressifs envers le personnage du joueur. Je vous verrai dans la prochaine vidéo. 55. 7-6 La vue: Bonjour, mes amis. Dans cette vidéo, nous allons donner à certains de nos ennemis la capacité de percevoir et de réagir à la présence du personnage du joueur. Dans la scène du contenu de la pièce, je vais retirer les escargots et la boîte de terrain Remplacez-le par un bloc sur les deux côtés, puis insérez une note de souris à l'intérieur qui fera des allers-retours entre les deux. Je vais ajouter le nœud Timer, joindre le script Pace et définir sa propriété one shot sur true. Pour que cet ennemi agisse de manière agressive envers le personnage du joueur, il doit trouver un moyen de le détecter. Nous devrons utiliser plusieurs outils pour y parvenir. Tout d'abord, nous allons ajouter un nœud D de zone 2 à notre ennemi. Et un nœud en forme de collision pour la zone. Cette zone représentera l'ensemble du champ de vision de l' ennemi. Vous pouvez utiliser un carré pivoté 45 degrés, une capsule ou un cercle Si vous utilisez un polygone de collision deux nœuds en D au lieu d'un nœud en forme de collision en deux D, vous pouvez créer un polygone personnalisé plutôt que d'utiliser des formes prédéfinies Cliquez simplement dans l'éditeur pour dessiner chaque sommet de la forme souhaitée Cela nous permet de créer un triangle ou un ventilateur, ce qui est une meilleure représentation d'un champ de vision. développant la propriété du polygone dans l'inspecteur, nous pouvons voir les positions de chaque sommet, modifier et les réorganiser si nécessaire. Quelle que soit la forme que vous choisissez d'utiliser, assurez-vous qu' elle ne comporte que des angles convexes Si votre polygone est concave, Godot le divisera en plusieurs formes convexes plus petites et doublera ainsi le coût des calculs de collision si vous décidez d'utiliser , si vous décidez d'utiliser une forme de collision symétrique normale, Cependant, si vous décidez d'utiliser une forme de collision symétrique normale, il est beaucoup plus facile de retourner l'ennemi vers la gauche ou la droite, car vous pouvez simplement utiliser la même méthode que celle utilisée pour le lancer du détecteur de bord, réglant sa propriété de position l'ennemi change de direction , avec le polygone de collision à deux nœuds D Cependant, avec le polygone de collision à deux nœuds D, le processus est un peu plus compliqué Nous ne pouvons pas simplement déplacer sa position, et nous ne devons pas non plus modifier sa propriété d'échelle. Si nous ouvrons la documentation de ce nœud, elle met spécifiquement en garde contre cela en indiquant qu'il ne se comportera probablement pas comme prévu. Si nous décidons d'utiliser ces polygones de collision pour des formes non symétriques que nous devons retourner, nous devrons modifier manuellement les positions de chacun des sommets dans Le champ de vision ne sera cependant pas suffisant à lui seul, car rien ne l'empêche de traverser les murs. Si nous voulons que l'ennemi détecte le joueur avec une ligne de visée dégagée, nous aurons besoin d'un autre nœud pour vérifier qu'un rayon projette deux nœuds D. Vous devez le placer près des yeux de l'ennemi, d'où il pourrait réellement observer, tout en le centrant horizontalement. Je vais le renommer en ligne de visée. La ligne de visée entrera en collision à la fois avec le terrain et avec le corps du personnage du joueur, qui sont tous deux des corps Cela permettra au terrain de bloquer leur champ de vision, même si le personnage du joueur se trouve dans son champ de vision. Une fois le champ de vision sélectionné, nous n'en aurons besoin que pour surveiller et masquer le corps du joueur Je vais supprimer le nœud de forme et utiliser le polygone comme zone de collision. Donnez-lui ensuite, ainsi qu' au casting, des noms uniques. En joignant un script au champ de vision pour déchiffrer, nous l'enregistrerons dans le dossier des scripts ennemis Récupérons les références à la forme ou nœud polygonal et au nœud de ligne de visée à l'aide de la balise ready Ce que j'aimerais dans cette configuration, c'est que l'ennemi réagisse au personnage du joueur une fois qu'ils sont tous deux entrés dans le champ de vision et que l'ennemi a une ligne de visée directe sur le joueur. Si le personnage du joueur sort à la fois du champ de vision et que la ligne de visée est rompue, j'aimerais que l'ennemi retrouve son comportement normal Réfléchissez à la manière dont nous voulons que ce nœud communique avec les autres nœuds par le biais de signaux. Nous aurons besoin de ce nœud pour signaler deux choses lorsque l'ennemi a acquis une cible et lorsqu'il a perdu sa cible. Ce seront les moments exacts où nous voudrons modifier leur comportement par rapport à leur rythme d' avant en arrière par défaut et leur dire plutôt de commencer à agir de manière plus agressive ou vice versa Nous pouvons relier les signaux du corps entré et du corps sortant du champ de vision au script Et cela nous indique assez facilement quand le personnage du joueur entre et sort du champ de vision Nous devrons le stocker dans une variable nommée target. Comme le paramètre est un numéro deux D, nous allons également définir le type de variable comme un numéro deux D pour simplifier les choses. Nous avons également besoin d'une variable booléenne pour savoir si l'ennemi cible actuellement, si la cible se trouve actuellement dans le champ de vision et si l'ennemi a actuellement une ligne de visée vers la Lorsqu'un corps entre dans le champ de vision, définissez son champ de vision sur vrai et définissez la cible sur le corps. Lorsque le corps quitte le champ de vision, nous pouvons le remettre sur faux. N'oubliez pas que nous ne faisons que masquer le personnage du joueur, nous savons donc déjà que ce corps est le personnage du joueur En passant outre le processus physique, s'il n'y a pas encore de cible, nous pouvons simplement revenir car il n'y a rien à faire Nous pouvons maintenant supposer que le personnage du joueur est entré dans le champ de vision au moins une fois. Ensuite, nous allons pointer la ligne de visée vers la cible. Nous pouvons créer un vecteur pointant de A vers B en soustrayant A de B. Ainsi, la position cible du raycast sera la globale de la cible moins notre position globale La valeur de is in line of sight sera alors vraie si ce que le collisionneur touche est identique à la cible Si le rayon projeté touche le terrain ou ne touche rien du tout, cela sera faux. Notez que lorsque le processus physique se produit, les collisions ont déjà été calculées par Godot Ainsi, lorsque nous pointons le personnage du joueur dans la ligne ci-dessus, les données de collision qui en résultent ne seront pas disponibles avant la prochaine image. Ce que nous vérifions ici, ce sont les résultats des collisions de l'image précédente. Si, pour une raison ou une autre, vous avez absolument besoin d'un cast à mettre à jour immédiatement, vous pouvez appeler sa fonction force RycaStudate Mais comme le jeu tourne à 60 images par seconde, le retard ne sera pas perceptible et cela fonctionnera parfaitement tel quel. ne nous reste plus qu'à émettre nos signaux au bon moment. Si l'ennemi ne cible pas actuellement, mais que la cible se trouve dans son champ de vision et qu'il a une ligne de visée, cela signifie que la cible a été acquise. Nous allons donc définir son ciblage sur true et émettre le signal acquis par la cible, en passant la cible comme argument. Et dans le scénario inverse, s'ils ciblent actuellement, mais que la cible ne se trouve pas dans leur champ de vision et qu'ils n' ont pas de ligne de visée, alors nous avons perdu la cible. Dans ce cas, il serait également judicieux remettre la valeur de la cible à Null, ce qui empêchera le processus physique de vérifier quoi que ce soit jusqu'à ce qu'elle revienne dans le champ de vision. Imprimons également le moment où ces événements se produisent afin de pouvoir les tester. La dernière chose à faire est de retourner notre polygone de collision lorsque l'ennemi change de direction, ce que nous pouvons faire en connectant le signal de direction modifiée à notre script Si vous utilisez une forme symétrique, vous suffit de la repositionner il vous suffit de la repositionner de l'autre côté du personnage Mais j'utilise un polygone, ce qui signifie que je dois modifier les sommets individuels Je vais commencer par récupérer le tableau existant à partir du polygone et le stocker dans une variable Le type est un tableau vectoriel compressé à deux. Je peux ensuite parcourir chacun des sommets et utiliser la même stratégie pour inverser leur exposition autre côté du personnage s'ils sont orientés vers la Le tableau de sommets fourni par le polygone ici n'est qu'une copie, pas le tableau lui-même Ainsi, lorsque nous modifions ses valeurs, cela n'affecte pas réellement le polygone de collision Pour que les modifications fonctionnent réellement, nous devons remplacer le tableau existant par la copie modifiée Activons les formes de collision visibles dans le menu de débogage et essayons-le. Nous pouvons voir notre ennemi faire des allers-retours entre les deux murs et le polygone de collision bascule lorsqu'il En entrant dans le champ de vision, le nœud Ray Cast commence à suivre notre position, mais l'ennemi ne l'a pas encore vue car sa ligne de visée est bloquée par le terrain. Si nous sautons, la ligne de visée n'est plus obstruée et nous obtenons le message acquis par la cible en sortie En quittant le champ de vision et la ligne de visée de l'ennemi , le message indiquant que la cible a été perdue apparaît et les acteurs ne suivent plus notre position Notre ennemi est désormais capable de détecter la présence du personnage du joueur, mais il doit encore réagir. Je vous verrai dans la prochaine vidéo. 56. 7-7 Agression: Bonjour, mes amis. Dans cette vidéo, l'ennemi va poursuivre et attaquer le joueur. En commençant par la scène ennemie, nous devrons ajouter une attaque pour cet ennemi. En dupliquant l'animation inactive, je vais rapidement créer les sprites appropriés pour l' animation d'attaque de l'ennemi Cette animation d'attaque n' indique pas vraiment l'étendue de la zone que l' attaque va toucher. Il ne montre que le mouvement de l' ennemi lui-même. Nous aurons besoin d'un sprite distinct pour cela. Je vais créer un nouveau dossier de sprites pour les sprites à effets et importer une feuille de sprites pour l'effet d'attaque de cet ennemi Nous allons ajouter un sprite animé pour se faire passer pour un enfant du Sprite de l'ennemi, afin qu'il bascule automatiquement horizontale lorsque l' ennemi Créez ensuite une nouvelle ressource Sprite frames et ajoutez les sprites de la feuille Sprite Comme toujours, je vais ajouter un sprite vide à la fin de l'animation, régler sa fréquence d'images à 12 images par seconde, sans faire de boucle Je vais mettre cette animation sur son premier sprite, qui montre avec précision la taille et la forme de l'attaque Positionnez-le ensuite devant l'ennemi. Il est ainsi beaucoup plus facile d' ajouter une boîte de frappe à cette attaque. Dupliquons donc la boîte de frappe existante. Je vais renommer la boîte de frappe d'origine en dommages par contact et laisser cette nouvelle boîte en tant que boîte de frappe. Nous pouvons maintenant faire en sorte que la forme de la collision corresponde à l'effet de l'attaque. Contrairement au sprite animé, nous ne devrions pas utiliser l'astuce de mise à l'échelle négative pour inverser notre case de frappe. Nous devrons donc connecter le signal de changement de direction de l'ennemi au script hit boox et le repositionner manuellement Comme nous l'avons déjà fait, nous allons simplement saisir une référence à la forme de collision. Et réglez sa position sur sa valeur absolue multipliée par un si la direction est inférieure à zéro ou positive un dans le cas contraire. Dans l'état par défaut de cet ennemi, celui-ci n'attaquera pas, donc cette zone de frappe ne sera pas active. Désactivons donc sa propriété de surveillance et sa visibilité. Revenez ensuite à l'animation d'attaque où nous pouvons saisir ces propriétés pour les activer pendant l'animation d'attaque et les désactiver à nouveau. Cela les ajoutera également à la piste de réinitialisation avec leurs valeurs par défaut. Et nous pouvons également indiquer l'effet d'attaque à jouer en même temps. Dans la scène du contenu de la pièce, nous avons actuellement le comportement normal de cet ennemi, qui se déplace d'avant en arrière, et un moyen pour l'ennemi de voir le personnage du joueur Lorsque ce nœud émet le signal obtenu par la cible, nous devons modifier le comportement de l'ennemi pour qu'il passe du rythme à un comportement plus agressif Et lorsqu'ils perdent la trace de leur cible, ils doivent reprendre leur rythme initial. Mais nous ne voulons pas nécessairement que cela s'applique à tous les ennemis ou autres personnages qui utilisent le script de rythme. Nous devons donc créer un nœud distinct pour les comportements agressifs. Je vais utiliser un autre nœud de temporisation et le nommer agressivité. Attachez ensuite un script à ce nœud et enregistrez-le dans le dossier des scripts ennemis. Tout comme pour le script de rythme, nous aurons besoin d'une référence à l'ennemi que ce script contrôle à l'aide du tag ready. Nous devrons également enregistrer une référence à la cible dans une variable à l'égard de laquelle cet ennemi agit de manière agressive. Et nous devrons également connaître la direction vers la cible sous forme de vecteur deux, ainsi que la distance par rapport à la cible sous forme de flotteur. Connaître ces valeurs permettra à l'ennemi de s' approcher de sa cible pour atteindre le champ d'attaque avant d'attaquer. Mais nous devrons également spécifier la portée d'attaque de cet ennemi sous forme de variable exportée, qui serait un flotteur. Si vous le souhaitez, vous pouvez également spécifier une portée d'attaque minimale. Si nous changeons le type de plage d'attaque en un vecteur deux, nous pouvons utiliser la valeur X comme plage minimale et Y comme valeur maximale. Je vais définir sa valeur par défaut à au moins 32 pixels du lecteur et à un maximum de 64 pixels. Donc, si l'ennemi se trouve à plus de 64 pixels du personnage du joueur, je veux qu'il court vers lui. Ou si l'ennemi se trouve à moins de 32 pixels du personnage du joueur, je veux qu'il le fuie. Mais dans cette zone, l'ennemi attaquera. annulant la fonction du processus, nous pouvons ignorer Delta, et s'il n'y a pas de cible pour cet ennemi, nous pouvons revenir Cela ne devrait pas se produire, mais ce n'est jamais une mauvaise idée d' avoir un système de sécurité intégré Nous pouvons calculer la direction vers la cible en soustrayant la position de notre ennemi de la position de la cible, puis obtenir la distance en prenant le même vecteur et en calculant sa longueur Si la distance jusqu'à la cible est supérieure à notre portée d'attaque maximale, cet ennemi doit se déplacer vers la cible en orientant son mouvement vers le point X. Si la distance jusqu'à la cible est inférieure à notre portée d' attaque minimale, cet ennemi doit s' éloigner de la cible faisant exactement le contraire. Si ces deux conditions étaient fausses, alors la cible est à portée d'attaque. L'ennemi doit donc se préparer à attaquer. Je vais m'assurer que l'ennemi arrête bouger en réglant sa direction de déplacement sur zéro et en faisant face à zéro et en faisant face la cible, au cas où ce ne serait pas déjà le cas. Je ne veux pas que l'ennemi attaque tout de suite, étant donné que mon animation d'attaque est très courte, elle n'est pas télégraphiée Je vais donc démarrer le chronomètre ici et attendre la fin du compte à rebours avant d'attaquer. La propriété one shot de ce chronomètre doit être définie sur true pour ne compter qu'une seule fois. La propriété du temps d'attente sera le temps pendant lequel l'ennemi reste dans le champ d'attaque avant d'attaquer. En connectant le signal de temporisation au script, c'est ici que je vais dire à mon ennemi d'attaquer C'est également une bonne idée de faire à nouveau face à la cible au cas où quelque chose aurait changé depuis le début du chronomètre. Je ne veux démarrer le chronomètre que s'il est actuellement arrêté. J'arrête également le chronomètre chaque fois que la cible est hors de portée d'attaque. Cela devrait suffire à notre comportement. Il ne nous reste plus qu' à alterner entre nos deux scripts de comportement au moment opportun. Nous ne voulons pas que notre script d'agression soit actif lorsque l' ennemi apparaît pour la première fois Nous allons donc désactiver son mode de traitement En sélectionnant le champ de vision dans l'arbre des scènes, nous allons connecter le signal cible acquis au script d' agression, et nous pouvons renommer cette fonction si nous le voulons Pour que les choses restent cohérentes entre mes différents scripts de comportement, je vais le nommer zoom. Cette fonction définira la valeur de la cible, modifiera le mode de processus pour hériter et indiquera également à l'ennemi de courir, ce qui le fera commencer à agir manière agressive envers la Mais nous devons également suspendre le script de rythme. Nous allons donc également connecter le même signal au nœud Pace. Et cette fois, appelez une fonction nommée pause, mais ce signal fournit un argument, et nous n'en avons pas besoin pour suspendre ce comportement. Nous pouvons également imaginer un scénario dans lequel nous voudrions suspendre ce comportement dans d'autres circonstances sans fournir un argument arbitraire et inutile pour appeler la fonction pause. Nous allons donc dissocier l'argument fourni par le signal, afin que la fonction connectée n' ait aucun argument Ici, il suffit de désactiver le mode de traitement. Lorsque l'ennemi voit une cible, il interrompt son rythme et reprend son comportement agressif Ainsi, lorsqu'ils perdent leur cible, nous pouvons faire le contraire, en connectant le signal aux scripts et en appelant les fonctions opposées. Paramétrer leur mode de traitement pour qu'il hérite pour les activer ou qu'il soit désactivé pour les désactiver Lors de l'activation du comportement de stimulation, nous voudrons également dire à l'ennemi de marcher Maintenant, dans le script du personnage, nous devons déclencher l'animation d'attaque lorsque nous demandons à l' ennemi d'attaquer. Pour ce faire, nous avons besoin d'une référence à la lecture automatique de l'arbre d'animation. Mais cela provoquera une erreur dans le script du personnage du joueur si nous avons une autre variable du même nom, puisque le personnage du joueur hérite du personnage Il y aurait donc une variable d'animation héritée du personnage, mais aussi une autre déclarée dans le personnage du joueur, ce qui n'est pas autorisé, mais nous l'utilisons dans le même but. Nous pouvons donc simplement supprimer celle-ci Nous pouvons donc simplement supprimer du script du personnage du joueur. De retour dans le script du personnage, lorsqu'on nous demande d'attaquer, il suffit de dire à cette lecture de passer à l'animation de l' attaque. Dans l'arbre d'animation, nous allons ajouter l'animation d'attaque et passer du mode Idle with Advance Enabled à ce mode Idle with Advance Enabled mode pour revenir au mode inactif à la fin de l'animation. Si vous ne voulez pas que l'ennemi puisse se déplacer ou changer de direction pendant qu'il attaque, nous pouvons ajouter des contrôles rapides pour vérifier si le nœud actuel de la diffusion de l'animation est une attaque. Et soit réglez le sens du déplacement zéro, soit quittez complètement la fonction. Maintenant, lorsque nous lançons le jeu, une fois que l'ennemi nous a placés à la fois dans son champ de vision et dans sa ligne de visée, son comportement passe du rythme à un comportement plus agressif Ils nous poursuivront et attaqueront après une brève pause. doit désormais affronter un ennemi beaucoup plus agressif Notre personnage doit désormais affronter un ennemi beaucoup plus agressif, mais celui-ci ne peut pas vraiment riposter Je vous verrai dans la section suivante. 57. Combo 8-1: Bonjour, mes amis. Dans cette vidéo, nous allons donner au personnage du joueur ses propres attaques afin qu'il puisse se défendre contre ses ennemis. Nous avons déjà attaqué la souris Knight, et le processus sera très similaire. Cependant, le personnage de notre joueur possède deux attaques différentes. Nous pouvons copier certains nœuds de la scène nocturne de la souris pour gagner du temps, la boîte de dialogue et du nœud Animated Sprite Two D. passant à la scène du personnage, nous pouvons coller ces nœuds dans la scène, puis les réorganiser selon les besoins Le nœud 2D du Sprite animé peut être trié sous le Sprite du personnage, sorte qu'il bascule automatiquement en fonction de la direction dans laquelle se trouve le personnage Je vais le renommer en effet d'attaque. Je sais de quel sprite animé il s'agit. , je vais généralement garder tant que frère ou sœur, je vais généralement garder le tri à côté de la Hurt Box Pour que les personnages touchés infligent des dégâts à la boîte de blessures de l'ennemi, nous devons nous assurer que les couches et les masques de collision sont définis en conséquence. Comme le personnage de mon joueur se trouve dans la couche de collision 9 et que sa boîte de blessures se trouve dans la couche de collision 10, mes ennemis seront placés dans la couche de collision 17 et leurs boîtes de blessures dans la couche de collision 18. ouvrant les paramètres du projet, j'ajouterai la Hurt Box ennemie aux noms de mes deux couches physiques en D en tant que couche 18. N'oubliez pas de modifier toutes mes scènes ennemies existantes pour placer également leurs cases de blessures sur cette couche. La case de frappe du personnage du joueur peut ensuite être configurée pour masquer la couche 18 afin de leur infliger des dégâts. Pour inverser la case de saisie, nous devons reconnecter le signal dans cette scène, car cette connexion n'aura pas été copiée depuis l'autre scène Mais la fonction que nous avons écrite précédemment dans le script Hit box à laquelle nous voulons connecter ce signal est nommée lorsque l'ennemi a changé de direction. Cela n'a pas d'importance, mais si vous voulez être cohérent dans la façon dont vous nommez les choses dans votre jeu, vous pouvez remplacer le nom de cette fonction chaque personnage change de direction ». Cela ajoutera une autre fonction au script, et nous pouvons facilement déplacer le code vers cette nouvelle fonction et supprimer l'ancienne, car elle fera exactement la même chose. Cependant, nous devons maintenant accéder à la scène des ennemis et modifier leur connexion au signal pour nous connecter à la nouvelle fonction. à un stade précoce de votre projet vous pourrez identifier ces problèmes à un stade précoce de votre projet, moins vous aurez besoin de temps et d' efforts pour le refactoriser ultérieurement. De retour dans la scène du personnage du joueur, nous allons sélectionner le nœud Animation Player dans la hiérarchie des scènes et ajouter une nouvelle animation. Nous appellerons cette attaque une attaque car il existe deux animations d'attaque différentes et nous devrons les différencier. Après avoir ajouté les cadres Sprite du personnage. Je vais copier les images-clés sur les autres pistes pour les vêtements du personnage Nous pouvons également activer la propriété de surveillance de la hitbox. Et la visibilité aussi, si vous aimez le voir s'activer et se désactiver en mode débogage Si l'on regarde l'effet d'attaque, cela ne correspond pas à l'animation de l'attaque. Je vais donc importer les sprites à effets appropriés pour cette attaque. Ajoutez ensuite une nouvelle animation à la ressource Sprite frames. Je vais l'appeler Attack One, désactiver le bouclage, régler la fréquence d'images et ajouter une image vide à la fin Maintenant, l'animation de l'attaque peut indiquer l'effet de l'attaque Animated Sprite utilise deux nœuds en D pour exécuter l'effet Attack One L' appel à la fonction keyframe est just play, qui fonctionne bien tant que notre nœud Animated Sprite two D n'a qu'une seule animation à Mais maintenant, nous avons deux animations différentes, et nous devons spécifier laquelle nous voulons jouer. En cliquant sur l'image-clé, nous pouvons la modifier dans l'inspecteur développant la section des arguments, nous pouvons voir que la fonction play comporte en fait trois arguments, tous facultatifs. Nous ne nous intéressons qu' au premier argument, le nom de l'animation, que nous pouvons taper dans le champ de texte. Si vous êtes curieux, les autres arguments concernent le réglage de vitesse de l'animation ou la lecture de l'animation à l'envers L'orthographe doit correspondre exactement au nom de l' animation. Je vais renommer l'animation par défaut en attaque deux, conformément à ce que j'ai mis dans l'animation dupliquant l'animation de l' attaque 1, nous pouvons également créer une animation de l'attaque 2 Après avoir modifié les images des sprites du personnage, je copierai les images-clés sur les autres pistes Remplacez ensuite l'argument transmis par l'effet d' attaque pour jouer à l'attaque 2 au lieu de l'attaque 1. En sélectionnant le nœud Animation Tree, nous pouvons ajouter une animation d'attaque et attaquer deux animations. Ajoutez ensuite une transition entre le mouvement et l'attaque un, puis entre l'attaque un et l'attaque deux. des deux sera mode avancé des deux sera activé, ce qui signifie que nous déclencherons ces transitions à partir de notre script. En ajoutant des transitions, laissant l'une ou l'autre des animations d'attaque revenir en mouvement , leur mode de changement de mode sera réglé sur la fin. Le passage de l' attaque 1 à l'attaque 2 aura également son mode de commutation réglé sur « à la fin ». Cela nous permettra de passer à l' attaque 1 si le bouton d'attaque est enfoncé, puis de l'attaque 1 à l'attaque 2 si le bouton d'attaque a été enfoncé une deuxième fois lors de la première animation d' attaque. Pour ajouter un bouton d'attaque à notre jeu, nous devons accéder aux paramètres du projet, dans l' onglet de saisie de la carte et ajouter un nouvel événement d'entrée pour attaquer. J'utiliserai la touche X du clavier et le bouton gauche de ma manette, qui est également X. Ensuite, dans le script du joueur, nous pouvons ajouter un autre bloc I pour les attaques, la saisie en mémoire tampon de la même manière que pour toutes les autres actions Comme le bouton permettant de déclencher la première attaque et la deuxième attaque est le même, le script du joueur doit uniquement se concentrer fait de dire au personnage d'attaquer, non sur l' attaque spécifique à exécuter. Dans le script du personnage du joueur, nous pouvons ajouter cette fonction d'attaque, renvoyant un booléen comme n' importe quelle autre entrée mise en mémoire tampon Cela ne sera pas verrouillé et n'a aucun coût, contrairement à la fonction cast. Si l' animation du personnage est actuellement en mode mouvement, je l'autoriserai à attaquer. En cas de succès, nous pouvons indiquer à l' animation de se déplacer jusqu'à l' animation Attack One et de renvoyer vrai ou faux si le personnage était occupé à autre chose. Une erreur s'est produite car la fonction d'attaque remplace la fonction d'attaque de la classe de personnage, mais la signature ne correspond pas Cela signifie que les paramètres ou le type de retour sont différents, ce qui n'est pas autorisé. Maintenir le contrôle ou la commande et cliquer sur la fonction nous amène à la définition de superclasse de cette fonction où nous pouvons voir qu'elle renvoie un void, et non un booléen Pour utiliser cette structure d' héritage avec nos ennemis et notre personnage de joueur, tout en autorisant les entrées mises en mémoire tampon, nous devons faire en sorte que la fonction d'attaque des superclasses renvoie également un Nous allons simplement renvoyer vrai pour satisfaire à cette exigence, et en revenant au script du personnage du joueur, l'erreur sera résolue. Mais qu'en est-il de la deuxième attaque ? Nous pouvons ajouter un bloc else if et vérifier si la lecture de l'animation se trouve actuellement dans l'animation Attack One. Dites-lui ensuite de passer à l' animation Attack 2 à la place. Activons les formes de collision visibles dans le menu Debug, puis appuyons sur Play et essayons. En appuyant sur le bouton d'attaque, notre personnage joue à Attack One Animation. La case de frappe est activée et l' animation de l'effet s'exécute. Appuyez à nouveau sur le bouton d'attaque lors de la première attaque pour lancer également la deuxième attaque. En revenant à l'éditeur, nous pouvons ouvrir l'arborescence distante pour voir notre jeu en cours d'exécution. En explorant l'arbre des scènes jusqu'à ce que nous trouvions la souris la nuit, nous pouvons sélectionner sa boîte à blessures et consulter ses propriétés dans l'inspecteur, y compris son état de santé actuel. De retour dans le jeu, nous pouvons attaquer notre ennemi et regarder chaque attaque le toucher pour obtenir une santé à chaque fois jusqu'à ce qu'il atteigne zéro. Allez. Notre personnage est désormais capable d'attaquer les ennemis, mais nos personnages et ennemis ne réagissent pas lorsqu'ils sont touchés. Je vous verrai dans la prochaine vidéo. 58. Coup 8-2: Bonjour, mes amis. Dans cette vidéo, nous allons faire réagir nos personnages lorsqu'ils sont touchés par des attaques. En commençant par la scène du personnage du joueur, en sélectionnant le nœud Animation Player, nous devrons ajouter une nouvelle animation pour être touché. Pour faciliter les choses, je vais dupliquer l'animation du tiret pour créer l'animation du hit. Après avoir mis à jour les images-clés du Sprite, je les copierai et les collerai dans les autres pistes pour animer également les vêtements du personnage Comme j'ai dupliqué l'animation du tableau de bord, cette animation à succès inclut désormais également des images d' invincibilité Cela est très utile pour empêcher les personnages de subir des dégâts sur plusieurs cases à la suite, ce qui est souvent injuste pour le joueur et amène le personnage à subir des dégâts répétés à cause de boîtes de frappe persistantes, comme les risques environnementaux, par exemple, car une nouvelle collision sera déclenchée lorsque la boîte à blessures sera réactivée à la fin du animation, si la Hurt Box se chevauche toujours avec la case de frappe. Nous avons également la méthode track qui appelle la fonction end dash, qui, si vous vous souvenez, d'après la façon dont elle a été implémentée dans la section précédente, doit être appelée si le tiret a été interrompu. Il serait judicieux de déplacer cet appel de fonction au début de l'animation du hit. Examinons cette fonction dans le script du personnage du joueur. Selon les images sur lesquelles vous activez ou désactivez la Hurt Box, il est possible que le personnage soit touché pendant que l' animation du tiret est en cours de lecture et interrompe donc l'animation du tiret. Cela signifie que la fonction de fin de tableau de bord ne sera jamais appelée, la gravité du personnage ne sera jamais réinitialisée et que le temps de recharge du tableau de bord n'a jamais commencé C'est évidemment problématique, mais nous pouvons facilement y remédier. Tout ce que nous avons vraiment besoin de faire, c'est de savoir quand le personnage est en train de tirer avec une variable booléenne Lorsque le tableau de bord démarrera, nous le réglerons sur true. Ensuite, lorsque la fonction end tiret est appelée, nous vérifierons si le personnage est en train de tirer en premier et, dans l' affirmative, nous ferons les mêmes choses Ensuite, réglez sa valeur sur false par la suite. Nous pouvons maintenant appeler cette fonction à tout moment , que le personnage soit brillant ou non. Si le personnage n'est pas brillant, la fonction ne fera tout simplement rien En sélectionnant le nœud Animation Tree et en jetant un coup d'œil à la machine à états, j'aimerais que l' animation du hit puisse interrompre n'importe laquelle de ces animations d'action existantes, ainsi que toutes les animations de saut ou de mouvement. Par conséquent, il serait judicieux d' utiliser une autre machine à états. Je vais donc enregistrer cette machine d'état comme je l'ai fait avec les précédentes. Je vais le nommer actions et l'enregistrer dans le dossier de mon personnage avec les autres. Remplacez ensuite cette machine d' état par une nouvelle et chargez la machine d'état d'actions en tant que nœud. OK. Vous pouvez ensuite ajouter l'animation du hit à cette machine à états. L'ajout d'une transition entre le début les actions en fait l'état par défaut. Ensuite, une transition entre les actions à frapper avec son mode avancé réglé sur activé, et une autre entre actions avec le mode de commutation réglé sur « à la fin ». Cela nous permet de déclencher l'animation à partir de n'importe quel état existant, jouer en même temps, puis de revenir à nos autres états. Dans le script des personnages, comme je veux que cela s'applique à tous les personnages, pas seulement au personnage de mon joueur, nous devrons créer une nouvelle variable pour maintenir la lecture de cette nouvelle machine à états. Nous pouvons dupliquer la variable existante et la renommer en quelque chose comme Hurt Animations Le chemin d'accès à cette propriété de lecture est le paramètre Playback, puisqu'il s'agit de la racine de l'arbre d'animation. Si nous sélectionnons l'arbre d'animation dans l'arborescence des scènes et que nous développons sa section de paramètres, nous pouvons voir les playbacks de chacune de nos machines d'état Le chemin de la propriété de lecture de la machine Action State a donc changé et nous devons le mettre à jour. Pour mieux clarifier l'utilisation de cette lecture par rapport aux animations Hurt, je vais appeler cette lecture des animations d'action. Utilisez ensuite la fonction de remplacement pour remplacer toutes les instances de cette variable par son nouveau nom. Comme le script du personnage du joueur hérite de cette variable, je dois également remplacer toutes les instances de l'ancien nom par le nouveau dans ce script Cela fonctionnera pour le personnage du joueur, mais pour que cela fonctionne pour les ennemis, nous devrons également mettre à jour leurs machines d'état Animation Tree correspondent à ce nouveau format. Je ne mettrai ma souris à jour que le soir puisque cet ennemi se trouve dans ma salle de départ, et le processus sera le même pour tous les ennemis. Je vais créer l'animation du hit dans le nœud Animation Player. Enregistrez ensuite la machine d'état Animation Tree en tant que ressource de projet. Remplacez-le par une nouvelle machine à états. Ajoutez l'ancienne machine à états en tant que nœud, ajoutez l'animation du hit, ajoutez les transitions avec la même avance et changez de mode. Renommez les actions pour qu' elles correspondent à ce que le script recherchera Cet ennemi possède désormais la même structure d'animation que le personnage du joueur Les scripts fonctionneront donc de la même manière, avec deux versions distinctes pour jouer l'animation à succès et une autre pour les actions Une fois la machine d'état configurée, la machine d'état enregistrée peut être supprimée. Cela permettra de localiser la machine d'état sur la scène plutôt que d'être une ressource partagée entre plusieurs scènes. Maintenant que nous avons accès à la lecture de notre machine à états, nous devons déclencher l'animation. Nous allons commencer par le script Hurt Box. Nous avons un signal qui est émis lorsque l'état de santé du personnage change, que nous utilisons pour mettre à jour l'élément HUD Mais ce signal est également émis lorsque nous initialisons la santé du personnage au début, ainsi que chaque fois que le personnage retrouve de la santé Ce n'est donc pas le meilleur signal à utiliser pour recevoir des dégâts. Nous allons déclarer un nouveau signal pour cela. Si vous souhaitez que le personnage réagisse à différents niveaux ou types de dégâts, vous pouvez donner des paramètres à ce signal. Je vais ajouter un paramètre pour la direction d' où proviennent les dégâts, sous forme de facteur deux. Mais nous ne pouvons pas obtenir cette information d'ici. Nous n'avons accès qu' à la Hurt Box et non à la Hit Box qui a causé les dégâts. Donc, en passant au script Hit box, nous avons ici accès à la fois à la hit box et à la Hurt Box. Nous allons donc l'ajouter comme un autre argument transmis par la fonction take damage. Nous pouvons calculer la direction de A à B en soustrayant A de B, puis en normalisant le résultat En normalisant, nous ignorerons la distance entre A et B en réglant la longueur du vecteur à un De retour dans le script Hurt Box, nous ajouterons le paramètre de direction. Lorsque notre boîte Herd est endommagée, nous émettons le signal et le suivons dans la direction. Notre script de personnage peut désormais réagir à ce signal. je vais renommer la fonction connectée Pour des raisons de simplicité, je vais renommer la fonction connectée en « on damage received OK. Nous allons d'abord demander à l'animation Hurt de passer à l'état hit. Ajoutez ensuite une force au corps du personnage dans le sens des dégâts. La direction étant normalisée, elle aura une longueur d'un pixel Nous pouvons multiplier ce chiffre par le nombre que nous voulons pour modifier l'impact de la force de renversement. Vous pouvez même l' exporter en tant que nouvelle variable afin qu'elle puisse être modifiée pour chaque personnage individuel Nous devrons également établir cette connexion de signal dans toutes les scènes de nos personnages. Essayons-le. Mon personnage peut désormais attaquer l'ennemi et celui-ci réagit lorsqu'il est touché à la fois par le jeu et par l'animation Une force de renversement est également appliquée. de même pour mon personnage lorsque l' ennemi m'attaque. Nos personnages réagissent désormais lorsqu'ils reçoivent des dégâts, mais notre combat ne semble pas très intéressant. Je vous verrai dans la prochaine vidéo. 59. 8-3 jus: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter des effets de particules à notre combat pour le rendre plus percutant. À partir de notre scène de personnage de joueur, nous allons ajouter un nouveau type de nœud à notre scène, un nœud émetteur de particules Godot a deux types différents, CPU et GPU. Le nœud de particules du processeur affichera les particules de la même manière que nous dessinons les sprites de nos personnages l'aide du processeur central de l'appareil, ce qui est moins efficace mais plus compatible avec les anciens appareils Alors qu'un nœud de particules du GPU déléguera entièrement le dessin de ces particules à la carte graphique de l'appareil, ce qui est plus efficace, mais uniquement sur les appareils modernes. Le nœud de particules du GPU peut gérer nombre beaucoup plus élevé de particules sans compromettre les performances Je recommande d' utiliser des particules du processeur uniquement si vous ciblez spécifiquement un téléphone ou une tablette pour votre jeu. Dans le cas contraire, vous devez utiliser des particules GPU. En ajoutant un nœud GPU Particles two D à notre scène de personnage, je vais simplement le nommer particules, déplacer vers le haut pour qu'il soit au centre du personnage et examiner personnage et examiner ses propriétés dans l'inspecteur. Avant qu'un émetteur de particules puisse dessiner quoi que ce soit, il a besoin d'un matériau de traitement Il s'agit d'une ressource qui indique à l'émetteur comment générer des particules et comment les particules doivent se comporter après leur apparition des particules et comment les particules . Il existe deux options différentes pour notre matériau de traitement, un matériau de traitement par particules ou un matériau Shadum Le matériau de traitement des particules sera créé en tant que ressource de projet que nous pouvons modifier directement dans l'inspecteur, tandis qu'un matériau de shader nous permettra d' écrire un script de shader pour faire la même chose Les scripts de shader ne sont pas écrits en GDScript comme tous nos scripts jusqu'à présent Ils sont écrits dans le shader GD, qui ne sera pas abordé dans ce cours Nous utiliserons donc plutôt une ressource matérielle issue du traitement des particules . Cliquez sur la ressource pour afficher et modifier ses propriétés. Maintenant que notre nœud émetteur de particules possède un matériau de traitement, il génère des pixels blancs individuels à partir de son point d'origine qui tombent sous l'effet de la gravité Pour que les particules soient plus visibles, je vais masquer le sprite de mon personnage Avant d'entrer dans chaque propriété individuelle, il est utile de désactiver d'abord la gravité, qui se trouve sous la section d'accélération. Et comme ces particules seront utilisées pour produire un impact pendant le combat, je vais régler leur explosivité à un J'ai une feuille de sprites que j' aimerais utiliser pour mes particules Je vais donc l'importer dans mon dossier d'effets, puis l'attribuer comme propriété de texture à mes émetteurs de particules Mais cela dessine simplement la totalité de la feuille de sprite pour chaque particule Pour animer une particule, nous devons lui donner un matériau personnalisé selon les propriétés héritées de l'élément Canvas Nous allons créer un nouveau matériau pour un objet Canvas , puis activer sa propriété d'animation de particules. Nous pouvons maintenant modifier le nombre d'images d' animation horizontalement et verticalement dans la feuille de sprites Les particules dessinent désormais uniquement la première image. En élargissant la section d'animation du matériau de traitement des particules, nous pouvons définir la vitesse d'animation des particules. Je veux que mes particules aient une vitesse constante Je vais donc régler le minimum et le maximum à un. Une courbe peut également être utilisée ici pour modifier la randomisation de la vitesse d'animation de chaque particule Et les mêmes valeurs peuvent également être fournies pour donner à chaque particule son propre décalage d'animation. En élargissant la section de portée, nous pouvons modifier la position où les particules apparaîtront, leur angle de rotation et leur vitesse initiale Nous pouvons modifier la forme d'émission partir d'un point unique pour obtenir une variété d'autres formes et modifier la taille de la forme si nous le voulons. Les formes d'émission ponctuelle sont généralement les plus appropriées pour combattre les particules. L'angle permet de randomiser la rotation des particules Pour le rendre complètement aléatoire, il suffit de régler le maximum sur 360. Comme j'utilise le pixel art, je ne veux pas que mes particules soient pivotées. La vitesse initiale donnera nos particules un aspect plus explosif. La quantité de force sera randomisée pour chaque particule entre le minimum et le maximum, ce qui rendra les particules moins uniformes au toucher La pâte à tartiner créera une forme d'éventail. En le maximisant à 180 degrés, la direction sera complètement aléatoire La section de vélocité animée contient des variables que vous pouvez utiliser pour appliquer différentes vitesses constantes à vos particules tout au long de leur durée de vie Angular les fera pivoter. Directional continuera à les déplacer dans la direction dans laquelle ils se déplacent déjà. Orbital les fera orbiter autour du point d'apparition. La radio les éloignera du point d'apparition. Et la limite de vitesse utilise une courbe pour limiter la vitesse de chaque particule. La section des accélérations contient des variables similaires que vous pouvez utiliser pour affecter progressivement la vitesse de chaque particule au cours de sa durée de vie, ce qui les rendra plus réalistes La gravité est une force constante dans une direction pour toutes les particules. Linéaire est la direction dans laquelle la particule se déplace déjà. Radial est éloigné du point d'apparition. Et la tangentielle est similaire à l'orbitale. L'amortissement est une force utile qui provoque la décélération des particules au cours de leur durée de vie, ce qui est utile pour les particules explosives ou d'impact comme celles que nous fabriquons actuellement attracteurs de particules ne sont pas disponibles pour deux D, donc ce réglage n'a aucun effet. En élargissant la section d'affichage, nous pouvons modifier la façon dont chaque particule est dessinée. L'échelle fera en sorte que les particules répartissent leur propre taille de manière aléatoire. Si nous ajoutons une courbe d'échelle, cela changera la façon dont chaque particule change d'échelle au cours de sa durée de vie. Nous passerons bientôt en revue l'éditeur de courbes. L'échelle par rapport à la vitesse déterminera plutôt l'échelle des particules par rapport à leur vitesse plutôt qu'à leur durée de vie. Ceci est particulièrement utile pour créer des nuages de poussière qui se dissipent. Les courbes de couleur possèdent de nombreuses propriétés différentes, à commencer par une couleur de base pour toutes les particules. La palette de couleurs nous permettra de créer un dégradé, chaque particule passant de la couleur de gauche à la couleur de droite au cours de sa durée de vie Cette couleur est multipliée par la couleur de base pour obtenir le résultat. dégradé de couleurs initial répartira aléatoirement la couleur de départ de chaque particule sur le dégradé La courbe d'émission peut être utilisée pour faire en sorte que trois particules D émettent différentes quantités de lumière au cours de leur durée de vie, ce qui n'est pas le cas pour deux particules D. La courbe Alpha est utile uniquement pour modifier l'alpha de vos particules au cours de leur durée de vie. Créons ici une nouvelle ressource de texture de courbe. Cette ressource de texture de courbe nécessite une autre ressource de courbe qui lui est propre. Cliquez dessus pour ouvrir un éditeur de courbes que nous pouvons facilement utiliser pour créer une grande variété d'effets. L'axe X de ce graphique représente temps, zéro étant le moment où la particule est générée et un étant la fin de la durée de vie de la particule. Pas une seconde. L'axe Y est la valeur que nous sommes en train de modifier, c' est-à-dire les couleurs des particules Alpha, un étant opaque et zéro étant invisible. Nous pouvons modifier les valeurs minimale et maximale de notre axe, mais nous n'avons pas besoin de le faire dans ce contexte. Il suffit de cliquer sur le graphique pour ajouter un point que nous pouvons déplacer selon les besoins. Je veux que mes particules deviennent opaques et deviennent invisibles au cours de leur durée de vie. C'est idéal pour faire disparaître les particules au lieu de simplement disparaître Les tangentes sont automatiquement appliquées aux points pour créer une courbe En sélectionnant n'importe quel point du graphique, nous pouvons modifier les tangentes pour créer le type de courbe dont nous avons besoin Nous pouvons également modifier manuellement les points et les tangentes en développant la section des points en bas La variation de teinte peut être utilisée pour aléatoire la teinte des couleurs de vos particules, rendre aléatoire la teinte des couleurs de vos particules, ce qui les rend moins uniformes Les autres propriétés ne sont pas très applicables à notre projet, mais je vais vous donner un bref résumé de leur utilité. La turbulence peut être appliquée pour simuler la façon dont les courants d'air affecteraient vos particules Vous pouvez modifier le modèle de bruit utilisé pour calculer la turbulence lorsqu'il est activé Les particules peuvent être bloquées ou tuées par des collisions. collisions ici ne sont pas les mêmes que celles que nous avons utilisées présent, car les particules sont traitées par la carte graphique. Ils ne peuvent entrer en collision qu'avec des occulteurs de lumière, et non Et si vos particules évoluent, leur rayon de collision peut également être adapté à celles-ci. Et un sous-émetteur peut être utilisé pour créer des effets tels que des feux d'artifice, provoquant omissions de particules supplémentaires Pour que mes particules correspondent à la fréquence d'images des autres jeux, je vais régler la durée de vie des particules à huit images divisées par 12 images par seconde. Maintenant que l' émetteur de particules est configuré, nous devons définir sa propriété one shot sur true Désormais, il n'émettra que des particules en une seule rafale , que nous pouvons déclencher via notre script. Je vais réactiver le sprite de mon personnage, puis ouvrir le script de mon personnage donnant un nom unique au nœud de particules, nous pouvons le stocker dans une variable avec la balise on ready. Ensuite, lorsque le personnage subit des dégâts, nous pouvons indiquer à la neige d'émettre des particules en réglant sa propriété d' émission sur true. Notez que cela ne fonctionnera pas s'il est utilisé en succession rapide, car l'émetteur de particules émettra déjà des particules Ainsi, le simple fait de régler l'émission sur true ne produira pas plus de particules de tels cas, vous devez soit créer un nouveau nœud de particules du GPU chaque accès, soit appeler la fonction de redémarrage à la place redémarrage forcera l'émetteur de particules à arrêter son émission actuelle et à recommencer avec un nouvel ensemble de particules N'oubliez pas de copier ce nœud dans vos scènes ennemies selon vos besoins. Essayons-le. En attaquant l'ennemi, ils émettent désormais des particules lorsqu'ils sont touchés. Et le personnage du joueur émet également des particules lorsqu'il subit des dégâts Nos attaques déclenchent désormais des effets de particules, mais nous pouvons faire davantage pour rendre combat encore plus palpitant. Je vous verrai dans la prochaine vidéo. 60. Médulle 8-4: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter un tremblement de caméra qui peut rendre le combat encore plus percutant. À partir du script de caméra, nous aurons besoin d'une variable que nous pouvons utiliser pour le secouer, qui sera un vecteur deux. Bien qu'il existe différentes manières de créer un effet de tremblement de l'appareil photo, je pense qu'il est logique d'utiliser un interpolation, car il s'agit d'un changement de propriété qui se produit sur une période donnée Déclarons donc une nouvelle variable d'interpolation nommée shake tween. Déclarez également une nouvelle fonction qui sera accessible au public et qui pourra secouer la caméra. Tout d'abord, vérifiez si l'appareil photo tremble déjà en vérifiant si le shake tween existe déjà et si c'est le cas, éteignez-le Nous pouvons ensuite créer un nouveau tween. n'y a pas vraiment besoin de types spéciaux de transition ou d'assouplissement pour cela. Nous ne voulons pas espacer une propriété de manière uniforme d' une valeur à une autre, mais simplement appeler une méthode plusieurs fois sur une courte durée Nous devrons déclarer la fonction que nous appellerons, mais je la nommerai set shake en tant que fonction privée. Ensuite, nous devons fournir un argument à transmettre à la fonction du début à la fin de l'interpolation Il s'agira de l'intensité de l'effet de tremblement mesurée en pixels. Nous pouvons accepter cela comme paramètre de la fonction de tremblement afin que tout script souhaitant déclencher un tremblement de caméra puisse en spécifier l'intensité. Ensuite, pendant la durée du tremblement de l'appareil photo réduisez progressivement l' intensité jusqu'à zéro. Vous pouvez éventuellement définir ce paramètre comme un autre si vous souhaitez autoriser les tremblements de l'appareil photo d' une intensité constante ou croissante Le dernier argument est la durée de l'intervalle, que nous pouvons également transformer en un autre paramètre. Ensuite, nous allons écrire la fonction set shake, qui accepte l' intensité comme paramètre. Cette fonction sera appelée chaque image pendant toute la durée du tremblement l'intensité passant progressivement de la valeur fournie lors de l'appel de fonction d'origine à zéro. Il suffit donc de définir la valeur de shake sur un nouveau vecteur deux. Si nous commençons avec le vecteur à deux points vers la droite, nous le faisons pivoter dans une direction aléatoire. Un angle de rotation aléatoire peut être un flottant aléatoire compris entre zéro et tau. Nous pouvons ensuite multiplier les résultats par l'intensité. Si, pour une raison ou une autre, votre interpolation ne parvient pas à fixer la valeur de la secousse à zéro, vous devrez le faire à la fin de l'interpolation Nous pouvons connecter le signal de fin du tremblement avant la fin à la fonction de secousse définie et fixer à zéro l'intensité Cela garantira que la valeur du tremblement sera remise à zéro à chaque fois l'appareil photo aura fini que l'appareil photo aura fini de trembler. Pour que le vecteur de tremblement déplace réellement la caméra, il suffit de l'ajouter à la position de la caméra dans notre fonction de traitement. Comme dans notre scène de jeu, nous pouvons désormais connecter tous les signaux que nous voulons déclencher pour déclencher un tremblement de caméra à la fonction de tremblement de notre caméra. Comme, par exemple, lorsque le personnage du joueur attaque un ennemi ou lorsqu'il subit des dégâts. Dans le script du personnage du joueur, nous pouvons ajouter des signaux pour ces événements. De retour dans la scène du jeu, nous pouvons connecter ces signaux à la fonction de tremblement de l'appareil photo. Pour ajouter des arguments à une connexion par signal, nous devons développer la section avancée. Nous pouvons ensuite sélectionner un float dans la liste des types d' arguments puisque le paramètre d'intensité est un float dans notre script. Cliquez ensuite sur le bouton Ajouter. Le shake a également besoin d'une durée, qui est également du type flottant. Nous pouvons donc cliquer à nouveau sur le bouton Ajouter pour ajouter un autre flottant. Les valeurs que nous fournissons pour le premier argument modifieront l'intensité du tremblement mesurée en pixels, et le deuxième argument sera la durée du tremblement en secondes. Je vais demander à mes personnages d' attaquer et de faire trembler la caméra d'une intensité de quatre pixels en un quart de seconde. Mais lorsqu'ils sont endommagés, je secoue l'appareil photo avec une intensité de huit pixels en une demi-seconde. Pour passer à la scène du personnage du joueur, nous devons émettre ces signaux aux moments appropriés, en commençant par le signal des dégâts reçus par les boîtes à blessures, qui est déjà connecté à une fonction nommée d'après les dégâts subis dans le script du personnage. Si nous annulons cette fonction dans le script du personnage du joueur, nous pouvons appeler la fonction de superclasse, puis émettre le signal Ensuite, nous pouvons sélectionner la case à cocher et ajouter une autre connexion de signal au signal saisi dans la zone et lui faire appeler une nouvelle fonction. Appelons ça « Attack Landed ». Cela n'a pas besoin d'être concerné par l'autre nœud de zone, nous pouvons donc utiliser la section avancée pour dissocier cet argument de la connexion du signal Puisque nous avons dissocié l'argument area, la fonction n'a aucun paramètre suffit à cette fonction d' émettre le signal qui provoquera le tremblement de l'appareil photo. Non, essayons-le. Si j'attaque la souris Knight, cela déclenche le signal que les cases de frappe sont saisies, qui traversera le personnage du joueur jusqu'à la scène du jeu et déclenchera un tremblement de caméra. Laisser la souris Knight toucher le personnage du joueur déclenche le signal reçu endommagé par la boîte Hurt, ce qui provoque un tremblement de caméra plus intense. Notre caméra tremble maintenant personnage du joueur attaque ennemis et subit des dégâts, mais nos personnages ne meurent pas lorsqu'ils n'ont plus de santé. Je vous verrai dans la prochaine vidéo. 61. 8-5 Mort: Bonjour, mes amis. Dans cette vidéo, nos personnages meurent lorsqu'ils n' ont plus de santé. En commençant par la scène nocturne avec la souris, en sélectionnant le nœud Animation Player, je vais rapidement créer une nouvelle animation morte en dupliquant l'animation sélectionnée . Après avoir remplacé le sprite le bon cadre dans la feuille Sprite, il est conseillé de désactiver la Hurt Box afin qu'ils ne puissent plus subir de dégâts et de ne pas la réactiver La même chose peut être faite pour tous les autres nœuds de la zone à Di, en désactivant les dégâts de contact et en désactivant la zone de frappe deux, afin que l'ennemi mort ne puisse plus infliger de dégâts au personnage du joueur. En sélectionnant le nœud Animation Tree, nous pouvons ajouter cette animation morte à la machine à états et y passer automatiquement si le personnage est mort. Contrairement aux autres animations, il n'est pas nécessaire de sortir de l'état mort. Il ne nous reste plus qu'à ajouter cette variable Is dead au script du personnage. Je vais le mettre en haut du script sous forme de booléen. Et déclarez également un signal deux mort, juste au cas où nous voudrions que quelque chose réagisse à la mort de certains personnages. Écrivez ensuite une fonction publique nommée die qui définira la valeur de cette variable sur true et émettra le signal. N'importe où dans ce script où un personnage peut effectuer une action qui ne devrait pas être autorisée après sa mort, nous pouvons simplement d'abord vérifier la valeur de la variable is dead. Donc, si on demande au personnage de faire face à une direction, mais qu'il est mort, il doit ignorer cette demande. De la même manière, nous l'ignorons s'ils attaquent. De même, si on demande à ce personnage de sauter, mais qu'il est mort, il ne doit pas sauter. Pareil pour l'attaque. Et dans le cadre du processus physique, je mettrai également leur direction de déplacement à zéro s'ils sont morts, afin qu'ils ne bougent jamais lorsqu'ils sont morts, mais qu'ils soient affectés par la physique. Dans le script Hurt Box, nous avons déjà créé le signal teint et l'avons émis lorsque le personnage n' avait plus de santé lorsque nous avons écrit le script dans la section précédente Mais pour jouer une animation de mort et non une animation à succès lorsque le personnage subit des dégâts et meurt en conséquence, nous devons nous assurer que nous n' émettons que le signal teint à ce moment-là Nous allons donc déplacer le signal endommagé dans un bloc se, donnant la priorité au signal teint Il suffit de connecter le signal teinté de la Hurt Box à la fonction de mise en dés de l'ennemi pour déclencher l'animation ce soit dans la scène de l'ennemi ou dans la scène du contenu de la pièce, quel que soit l'endroit où se trouvent les nœuds IA de votre ennemi, vous pouvez également associer le signal de l'ennemi au fonctionnement libre de ces nœuds. Vous pouvez également le faire dans les scripts eux-mêmes. En annulant la fonction Ready, les ennemis morts peuvent être connectés à Ure Cela vous évitera d' avoir à connecter le signal manuellement des centaines de fois pendant tout le projet. Essayons-le. Si j' attaque cinq fois la souris Knight, sa santé atteint zéro et elle meurt, ce qui déclenche l'animation de la mort et arrête toutes les actions. Je peux également le toucher sans l'abîmer. ce qui concerne le personnage du joueur, je n'ai pas vraiment de sprites d'animation mortelle pour ce personnage Je vais plutôt réutiliser l'animation à succès, en la dupliquant pour créer une animation de mort, car je sais que lorsque ce personnage meurt, la scène du jeu s'estompe et se réinitialise Comme pour l'ennemi, il est conseillé de désactiver également toutes les boîtes de blessures et les cases de frappe. Le seul vrai changement que je vais apporter ici est d'avoir la boucle d'animation. Dans l'arbre d'animation, j'ajouterai l'animation morte, comme précédemment, avec une transition automatique si le personnage est mort. Mais cette fois, ajoutez également une transition pour sortir de l'état mort condition qu'ils ne soient plus morts, puisque le personnage du joueur sera ressuscité après sa mort Après avoir connecté le signal mort de la Hurt Box au script du personnage, je passerai au script du personnage du joueur. Nous allons devoir écrire une fonction de relance qui puisse être utilisée pour redonner vie au personnage du joueur, en redonnant à la variable I dead la valeur false. Nous pouvons également demander à la Hurt Box de récupérer sa pleine santé en même temps. Pour ajouter plus de détails à l'animation de mort du personnage du joueur, je vais remplacer la fonction de dé dans le script du personnage du joueur Je vais commencer par appeler la fonction de superclasse, puis faire d'autres choses spécifiques au personnage du joueur En réutilisant le nœud d' effets de particules, je vais définir sa propriété one shot sur false, son explosivité Et il émet des propriétés réelles, transformant l'explosion instantanée de particules en un flux constant En plus de cela, je vais également modifier la couleur de modulation du personnage pour augmenter son intensité Après avoir créé un nouvel interpolation, je vais ajuster la couleur de modulation de ce nœud à une nouvelle couleur avec des valeurs RVB de 255 chacune Ensuite, dans la fonction de relance, je vais tous les remettre à leurs valeurs normales. Comme dans la scène de jeu, la caméra peut également réagir à la mort du joueur avec un autre tremblement de caméra encore plus intense. Le game manager devra également réagir à la mort du personnage du joueur afin de tout réinitialiser. Nous pouvons donc connecter le signal dD du personnage du joueur au script du game manager. Nommons cette fonction sur Player DD. Lorsque le joueur meurt, nous pouvons d'abord désactiver le gestionnaire de saisie afin qu'il ne puisse plus contrôler le personnage Je vais d'abord attendre 1 seconde pour laisser jouer l'animation de la mort de mon personnage, ce qui peut être fait en demandant l'arbre des scènes de créer un chronomètre. Nous pouvons obtenir l' arbre des scènes à tout moment en utilisant la fonction get tree et en appelant la fonction create timer, qui accepte un argument pour la durée du chronomètre. Cela renvoie le chronomètre déjà démarré afin que nous puissions attendre son signal d'expiration Cela interrompra l'exécution de cette fonction sur cette ligne pendant exactement 1 seconde. Une fois passé au noir, nous devrons repositionner le personnage du joueur à l'endroit où nous voulons qu'il réponde. Comme nous n'avons pas encore mis en place de systèmes appropriés pour gérer cela, je vais simplement les replacer à l'origine de la scène du jeu et laisser un commentaire indiquant que cela devra être implémenté plus tard. Nous pouvons maintenant faire revivre le personnage du joueur, réapparaître et réactiver le gestionnaire de saisie afin que le joueur puisse continuer à jouer Si vous souhaitez afficher du texte, vous pouvez ajouter un nœud d'étiquette à la couche Canvas. Je vais nommer Mind game over et lui donner un nom unique. Ensuite, remplissez-le avec du texte, centrez-le. Donnez-lui une taille de police plus grande. Et ancrez-le au centre de l'écran. Avant de passer au noir, je vais également créer un tween qui fera l' alpha de l'étiquette à Je vais moduler son Alpha à zéro, il est donc invisible par défaut Sans aucune attente, cela se produira en même temps que l' écran passe au noir L'étiquette devra être dessinée devant le fondu pour être visible. Après avoir repositionné le personnage du joueur, j'attendrai encore une seconde avant de passer au texte Mais je vais le faire plus vite qu'il ne s'estompe. Après avoir fait revivre le personnage du joueur, j'afficherai un message différent au fur et à mesure que le jeu reprendra Je vais dupliquer le message de fin de jeu existant, le nommer Revival et modifier le texte. Avant que le fondu ne disparaisse, je vais utiliser un autre interpolateur pour faire en sorte que ce texte s'estompe Patientez encore une seconde, puis effacez à nouveau le texte. Essayons-le. Je vais laisser la souris tuer le personnage de mon joueur. Nos personnages sont maintenant en train de mourir et le game manager réagit à la mort du personnage du joueur, mais il n'y a pas encore de boss dans le jeu. Je vous verrai dans la prochaine vidéo. 62. 8-6 Boss 1: Bonjour, mes amis. Dans cette vidéo, nous allons créer pour notre jeu un boss plus complexe que celui de nos autres ennemis. Je vais commencer par créer un nouveau dossier de ressources pour contenir les actifs de ce boss. Importez ensuite les sprites. Je vais ensuite créer une nouvelle scène dans mon dossier de scènes ennemies nommé Mac Mouse avec un nœud racine de type CharacterBody two D. Ce boss est composé de plusieurs composants de sprites différents que je dois assembler et superposer les uns sur abord, je vais ajouter un numéro deux D normal que je peux utiliser pour inverser tous les composants visuels du boss lorsqu' il fait demi-tour et le nommer flip Ajoutez ensuite plusieurs sprites pour les différents composants. J'aurai besoin d'un sprite pour le blindage, qui sera une texture d'atlas Après avoir renseigné la texture, je sélectionnerai la région appropriée dans la feuille de sprites Cela sera décalé de 48 pixels. En dupliquant ce nœud de sprite, je vais le renommer engrenages et changer son type en Animated Sprite two D. En donnant au nœud une ressource d'images de sprites, j'ajouterai les sprites d'équipement à l' Modifiez ensuite sa vitesse d'animation à 12 images par seconde. Cela doit être dessiné derrière le blindage, je vais donc réorganiser les nœuds En dupliquant à nouveau le nœud de sprite blindé, je vais créer un autre sprite pour l' Après avoir rendu la texture de l'atlas unique à ce nœud, je peux sélectionner une autre région à dessiner et réorganiser ce nœud pour qu'il soit dessiné derrière les autres Ce fond est également destiné à accrocher les engrenages afin que tout ce qui se trouve à l'extérieur du corps ne soit pas dessiné. Nous pouvons le faire en plaçant les engrenages en tant qu'enfant du nœud d' arrière-plan. Ensuite, en sélectionnant l'arrière-plan sous la section de visibilité, faites passer les enfants du clip de «   désactivé » à « Clipper et dessiner ». Désormais, les engrenages ne dessinent qu'à l'intérieur du corps. Il existe également une touche de remontage animée. Je vais donc dupliquer mon nœud Gears pour créer un autre nœud Animated Sprite tout et le nommer key Après avoir rendu la ressource de cadres Sprite unique à ce nœud, je remplacerai les cadres Gear Sprite les cadres de sprites clés Je repositionnerai ensuite la touche pour qu'elle soit à la position appropriée à l'arrière du corps de la souris Mc me faudra plus de nœuds Animated Sprite ( deux nœuds D) pour les roues Je vais donc dupliquer la clé pour créer une roue animée Après avoir rendu la ressource de cadres Sprite unique, je remplacerai les cadres Sprite clés par les cadres Sprite Wheel Placez ensuite la roue dans une bonne position et décalez-la vers le haut pour qu'elle soit au sol. O. Pour dessiner les roues situées derrière le corps, je vais les réorganiser pour qu'elles soient au-dessus du corps dans l'arbre des scènes Je vais dupliquer la roue avant pour en faire une deuxième roue et la repositionner Le dernier élément visuel de ce boss est un baril qui sort de sa bouche, qui ne sera qu' un sprite ordinaire Après avoir attribué la texture des sprites, je vais la déplacer pour qu'elle soit autour bouche de la souris Mac et la superposer derrière les sprites corporels I Quand ce canon tire des projectiles, je veux qu'il sorte de la bouche de la souris Mac, afin qu'il ait un décalage de 16 pixels négatifs Je vais ajouter un nœud Tutti de zone à cette position, qui sera le projectile Donnez-lui ensuite un nœud Animated Sprite Tutti avec la ressource Sprite frames et ajoutez les deux images Fireball Après avoir réglé la fréquence d'images, j'aurai également cette lecture automatique par défaut. Cela nécessitera une forme de collision, qui ne sera qu'un cercle. Pour fonctionner comme un projectile, il aura besoin du script du projectile joint Le script du projectile prévoit que le projectile aura une animation d'impact Je vais donc en ajouter une en utilisant les mêmes sprites d'impact que mon Cela devra surveiller et masquer la couche Hurt Box du joueur Nous pouvons connecter les signaux saisis dans la zone et dans le corps au script du projectile pour déclencher l' animation de l'impact et les dégâts O. Une fois la boule de feu assemblée, nous pouvons l'enregistrer comme scène à part entière dans le dossier du projectile Je vais ajouter un nœud Toti en tant qu'enfant de la boule de feu pour qu'il serve endroit où les projectiles apparaîtront, comme nous l' avons fait Réorganisez ensuite le nœud Tutti marqueur pour qu'il soit le frère de la boule de feu, en conservant sa position relative et en supprimant la boule conservant sa position relative et Réinitialisez ensuite le décalage des barils à sa position par défaut. En plus de retourner le corps de la souris vers la gauche et vers la droite, je veux aussi que le corps de la souris Mc gronde , mais pas les roues Je vais donc mettre tout ce que je veux raconter en tant qu' enfant d'un autre corps sans nom D. Chaque fois que la souris Mc bouge, je veux que les roues soulèvent de la poussière et des pierres du sol. Je vais donc ajouter une particule GP à deux nœuds D pour les roches. Attribuez ensuite un sprite de roche comme texture et fabriquez un matériau de traitement des particules OK. Pour que les pierres se soulèvent du sol, me suffit changer la direction de la vélocité vers le haut et de donner à chaque roche une vitesse aléatoire de 32 à 64 pixels par seconde Pour ce qui est de la poussière, je vais commencer par dupliquer l' émetteur de particules de roche et Attribuez ensuite la même feuille de sprites de particules que celle que j'ai utilisée pour les impacts d'attaque comme propriété de texture Comme il s'agit d'une feuille de sprites destinée à être animée, ce nœud aura besoin d'un élément de toile dont ce nœud aura besoin d'un élément de toile propriété d'animation des particules est activée avec le nombre correct d'images Après avoir rendu le matériau de traitement des particules unique, je vais conserver la même vitesse, mais en supprimant la gravité et ajoutant un amortissement suffisant pour contrebalancer la vitesse initiale À l'écran, j'ajouterai une vitesse d'animation de 1 pour animer les particules et une courbe Alpha les faire disparaître au fil du temps Je veux qu'il soit dessiné au premier plan, donc je vais définir sa propriété de commande sur un. Cela devrait suffire Je vais donc dupliquer les deux nœuds de particules et les ajouter à l'autre roue. Je ne veux pas qu'ils émettent par défaut Je vais donc les sélectionner tous en groupe et désactiver leurs propriétés d'émission. Comme tous les autres ennemis, celui-ci aura besoin d'une forme de collision pour entrer en collision avec l'environnement, ainsi que de boîtes à blessures et de boîtes de frappe Comme cet ennemi a une forme plutôt unique, j'utiliserai un polygone de collision plutôt qu'une forme de collision En ajoutant quelques sommets au polygone obtenir la forme générale du corps du boss, je dois m'assurer que le polygone de collision entre en contact avec le sol Je ne veux pas non plus vraiment m' embêter à retourner ce polygone, donc je vais le rendre symétrique Cela suffira en cas de collision avec l'environnement, mais permettra également au personnage du joueur de se tenir au-dessus de l'ennemi. Pour la Hurt Box, je m' intéresse un peu moins à ce que la forme de l'ennemi corresponde aussi étroitement J'utiliserai donc une capsule ordinaire. Si vous souhaitez combiner plusieurs formes standard pour créer une Hurt Box plus complexe, vous pouvez simplement ajouter d'autres nœuds de forme de collision. J'ajouterai une deuxième gélule au-dessus de la première pour couvrir une plus grande partie du corps. Je ne veux pas non plus m' embêter à retourner ces boîtes Hurt, cela aide à ce qu'elles soient symétriques Le nœud de zone 2 D émettra ses signaux comme si toutes les formes étaient combinées en une seule forme. Mais n'oubliez pas que si les formes sont éloignées les unes des autres, objet peut entrer dans une forme de collision, puis en sortir, puis entrer une autre forme de collision, provoquant de multiples collisions. Je vais également ajouter une Hurt Box séparée pour la clé de remontage. donner à cette clé sa propre boîte à blessures signifie qu'elle n'a pas besoin d'être connectée à la santé du boss, mais qu'elle peut émettre des signaux lorsque le joueur l'attaque Cela peut simplement avoir une simple forme de collision circulaire, mais il devra être inversé Je vais donc m'assurer que c'est l'exposition du nœud de forme qui détermine de quel côté se trouve la Hurt Box. Enfin, cet ennemi a besoin d'une boîte de frappe. Cela sera utilisé lorsque la souris Mc se chargera vers l'avant. Je veux que cela blesse le personnage du joueur s'il est devant ou au-dessus du boss. Je vais donc utiliser une capsule pivotée de 90 degrés qui s'étend au-delà du polygone de collision du corps situé devant et au-dessus, mais pas derrière En sélectionnant le nœud racine du corps du personnage, l'ennemi devra être considéré comme terrain pour que le personnage du joueur puisse s'y tenir debout, mais également exister sur la couche ennemie et masquer uniquement le terrain. Aucune des boîtes Hurt ou Hit Box n'aura besoin d'être surveillée ou surveillable par défaut Nous les activerons par le biais de scripts ou d'animations lorsqu'ils auront besoin d'être activés. Mais les boîtes à blessures peuvent être configurées la couche de collision de la boîte à blessures ennemie, et les boîtes de frappe peuvent être configurées pour masquer la couche de collision de la boîte à blessures du joueur couche de collision de la boîte à blessures afin que, lorsqu'elles sont activées, elles fonctionnent. Nous avons maintenant créé un boss pour notre jeu, mais aucun script ne le contrôle encore. Je vous verrai dans la prochaine vidéo. 63. 8-7 Boss 2: Bonjour, mes amis. Dans cette vidéo, nous allons donner à notre boss des comportements plus complexes que ceux de nos ennemis habituels. mécanismes de progression réels seront abordés dans la section suivante. Mais pour l'instant, il sera utile de réfléchir à la manière dont notre patron devrait exister par rapport à son arène. Mettons donc ce boss ennemi dans une arène simple avec un mur de chaque côté. En général, les boss Metroidvania piègent le joueur dans une arène, et une fois que le joueur entre, il doit vaincre le boss avant d'être autorisé Il s'agit d'un événement qui devra être déclenché lorsque personnage du joueur entrera dans le nœud D de la zone 2 Nous allons donc en ajouter un à la scène et le nommer boss Encounter. Donnez-lui ensuite une forme de collision. Je vais utiliser un rectangle pour qu'il couvre une très grande surface afin que le joueur ne puisse pas le contourner et le faire surveiller le corps du personnage du joueur. Cela nécessitera un script joint, mais je vais le créer depuis l'onglet système de fichiers un nouveau dossier de scripts ennemis pour les boss, nous pouvons nommer Boss Encounter, étendant ainsi la zone 2 D. Ce script sera chargé contrôler le déroulement global de la rencontre avec le boss, y compris son début, sa fin et les transitions de phase, comme les cartes de titre, musique changeante, etc. Nous devrons lui donner un nom de classe afin de pouvoir l'étendre ultérieurement. Pour réagir à l' entrée du personnage dans cette rencontre avec un boss, nous pouvons écrire la fonction «   on body entered », qui acceptera un paramètre nommé body de type 2 D et ne renverra rien. Le personnage du joueur entre dans cette rencontre avec un boss. Tout d'abord, nous devons désactiver toutes les futures collisions avec cette zone en utilisant set deferred pour définir la propriété de surveillance sur false. N'oubliez pas que lorsqu'une fonction est appelée par un événement de collision, nous ne devons pas modifier nos objets en même temps Nous reportons donc cela jusqu'à ce que les collisions aient été traitées Nous pouvons ensuite fermer l'arène, piéger le joueur à l'intérieur et effectuer toute initialisation requise Mais nous y reviendrons plus tard. Pour l'instant, nous allons déclarer une variable exportée contenant le boss ennemi lui-même et une variable destinée au personnage du joueur comme cible. Lorsque le personnage du joueur entre dans la rencontre avec le boss, nous pouvons définir la valeur de la cible comme étant le corps, ainsi qu'une variable de phase locale sous forme d'entier. Ajoutez ensuite une fonction de début, une fonction de fin et également une fonction de transition de phase, acceptant la phase en tant que paramètre et en mettant à jour la variable à sa nouvelle valeur. Dans la fonction de démarrage, nous pouvons régler la phase sur un et appeler notre fonction de prise de décision pour démarrer le combat. Nous aurons également besoin d'une fonction qui indique au patron ce qu'il doit faire ensuite. Pour l'instant, je vais appeler la fonction Start lorsque le personnage du joueur entre dans l'arène du boss. Assurez-vous d'enregistrer ce script afin que le nom de classe soit enregistré. Maintenant que la structure de base est en place, attachons un nouveau script à notre nœud de rencontre avec le boss. Je vais le nommer d'après mon boss, Neck Mouse Encounter extend boss encounter, et je l'enregistrerai dans le dossier approprié. Avec le script joint, nous pouvons affecter le boss ennemi à la variable exportée, définir le masque de collision sur la couche de personnage du joueur et connecter le signal saisi par le corps. Comme la fonction « on body entered existe déjà dans la superclasse Boss Encounter, nous n'avons pas à nous en préoccuper dans ce script Cependant, nous allons annuler la fonction de prise de décision et donner à ce boss en particulier son propre algorithme pour décider de ce qu'il fera ensuite Cette structure permet de modifier plus facilement le comportement d'un boss en fonction de la phase dans laquelle il se trouve actuellement ajouter des risques environnementaux à l'arène en réaction aux actions du boss ou de synchroniser le comportement de plusieurs boss lors d'une seule Toute nouvelle rencontre avec un boss que nous souhaitons créer peut également étendre la classe de combat contre un boss et fournir ses propres implémentations uniques pour chaque boss en particulier abord, c'est une bonne idée de vérifier si le boss est mort avant de le laisser décider de la marche à suivre. Donc, s'ils sont déjà morts, nous pouvons simplement rentrer. Il est également conseillé d'espacer les actions d'un boss en faisant une brève pause en attendant le signal d'expiration du chronomètre Nous pouvons le rendre moins prévisible en randomisant la durée du chronomètre et même en augmentant la cadence du combat à chaque phase en divisant par le numéro de phase Et peu importe ce que le boss décide de faire, il devrait probablement faire face à la cible. Nous pouvons donc appeler une fonction pour indiquer au boss de faire face à gauche si l'exposition globale de la cible est inférieure à la sienne. En utilisant une instruction match sur la variable de phase, nous pouvons facilement proposer différentes options d'action pour différentes phases. Comme mon patron est si simple, je choisirai d'augmenter l'intensité des actions par phase plutôt que d'en introduire de nouvelles. Avec une autre instruction match sur un entier aléatoire de 0 à 1, je vais créer une chance égale de choisir entre deux actions différentes Soit le boss se déplacera vers une position aléatoire dans l'arène, qui sera la position globale de ce nœud de rencontre avec un boss plus un nombre aléatoire compris entre moins 300 et plus 300, soit le boss lancera des boules de feu sur le joueur Je vais répartir aléatoirement le nombre de boules de feu en fonction de la phase en cours Je veux également que le boss ait une troisième action, qui consiste à charger le personnage du joueur à une vitesse plus élevée, mais uniquement sous certaines conditions. Donc, si la souris Mc est prête à être chargée, elle se chargera. Si le chargement n'est pas terminé, l' action sera aléatoire. Et je vais lui donner le signe de la position globale de la cible moins la position globale du Mc Mouse comme direction. La planification des actions que vous souhaitez que votre patron utilise et à quel moment vous permet savoir exactement quelles variables et fonctions publiques vous devrez écrire dans ses scripts. Nous pouvons donc voir dans ce script que le script de notre boss a besoin d'une variable « is dead », d'une variable « prête à charger », ainsi que des fonctions face à gauche, charge, déplacement vers la position et tir en forme de boule de feu Il s'agit d'une méthode simple pour aborder l' encapsulation lors de l' écriture de scripts complexes Nous pouvons écrire le script qui doit d' abord s'interfacer avec celui-ci afin de savoir exactement ce dont nous avons besoin. L'encapsulation nous aide également à réaliser l'abstraction. Puisque nous nous concentrons uniquement sur ce qui doit être accessible au public, nous pouvons également supposer que tout le reste doit être privé. Attachons ensuite un script au nœud racine des McMus et enregistrons-le dans le dossier des scripts ennemis Nous pouvons déclarer toutes les variables et fonctions acceptant les paramètres correspondants à partir du script de rencontre avec Boss. Si nous déclarons un signal et que nous le nommons « terminé », nous pouvons émettre ce signal à partir de toutes les actions sélectionnées dans la fonction de prise de décision. Pour l'instant, imprimons simplement ce que nous attendions du patron. Nous pouvons d'abord vérifier si cet ennemi est mort, et si c'est le cas, émettre immédiatement le signal final et revenir pour que rien ne se passe. Attendez ensuite 1 seconde avant d'émettre le signal final. Ensuite, sélectionnez le nœud boss ennemis dans la scène de contenu, que nous pouvons utiliser en fonction de la rencontre avec le boss lui-même si nous le voulons et connecter le signal final à la fonction de prise de décision. Désormais, chaque fois que ce boss ennemi termine une action, il décidera automatiquement de la marche à suivre. Cela devrait être suffisant pour montrer le déroulement de notre combat contre les boss. Alors essayons-le. Toutes les secondes ou toutes les deux secondes, nous pouvons voir l'ennemi prend une décision quant à la marche à suivre. Notre boss ennemi est désormais contrôlé par un script de combat contre un boss, mais nous devons encore implémenter le fonctionnement interne de la scène des boss. Je vous verrai dans la prochaine vidéo. 64. 8-8 Boss 3: Bonjour, mes amis. Dans cette vidéo, je vais vous expliquer comment j'ai écrit les fonctions de mon patron afin que vous puissiez comparer mes méthodes à la façon dont vous avez implémenté les vôtres. Tout d'abord, j'ai joint les scripts Hit box et Hurt Box respectivement à la hit box et aux Hurt Boxes du boss Ensuite, j'ai commencé les scripts du boss ennemi. J'ai émis des signaux pour tout ce qui serait utilisé pour démarrer ou terminer le combat contre le boss ou pour provoquer une transition de phase. Une autre pour savoir quand le boss change direction pour que je sache quand changer les choses, et deux autres pour savoir quand le boss est arrivé à destination ou s'est écrasé contre un mur. Ensuite, il y a aussi le signal, qui sera omis lorsque l' action décidée en cours par le boss sera terminée, et il devra décider de ce qu'il fera J'ai connecté le signal de changement de direction à la Hit box et aux touches de remontage Hurt Box pour qu'elles puissent être retournées Le script Hurt Box n'avait pas réellement cette fonction, ai donc copiée à partir du script Hit Boox Cependant, les touches de remontage Hurt Box se trouvent derrière le boss J'ai donc dû ajouter une variable exportée pour inverser la direction dans ce cas précis. en revenir au script de Mac Mouse, j'avais besoin d'une référence au corps du boss pour le faire gronder Cela est donc stocké dans une variable, car je vais l' utiliser très fréquemment. Et, bien sûr, j'ai besoin de savoir si le boss est vivant ou mort. J'aimerais que mon combat contre le boss commence avec la Mcmuse éteinte et que le joueur appuie plusieurs fois sur la touche de remontée pour le démarrer J'ai donc déclaré une variable indiquant si le moteur est actuellement démarré ou non , plus une vitesse pour la touche de remontage, démarrant à un huitième du régime normal, et un interpolateur que je peux utiliser pour modifier la vitesse progressivement au fil du temps Pour créer cet effet, j'ai fait jouer l'animation des touches de remontage automatiquement, mais avec une échelle de vitesse de zéro et sa Hurt Box était surveillable par défaut J'ai ensuite connecté son signal endommagé à mon script boss, en appelant une fonction nommée on key attack. Pour que la boîte à blessures de la clé ne meure jamais, je l'appelle fonction de récupération, car cela ne reflète pas la santé du boss, mais simplement une cible que le personnage du joueur peut car cela ne reflète pas la santé du boss, attaquer Après avoir réglé l' échelle de vitesse d'animation des touches de remontage sur le double, j'ai utilisé le tween pour la ramener progressivement à sa valeur attendue en une seconde Si le moteur a déjà été démarré, appuyez sur la touche de remontée, la souris Mac se chargera vers le personnage du joueur sa prochaine action. Sinon, j'ai doublé la vitesse de la touche et vérifié si elle avait atteint une valeur d'au moins un. Avec une valeur par défaut d'un huitième, cela se produira après la troisième attaque de la clé de liquidation. Lorsque cela se produit, j'ai appelé une fonction pour démarrer le moteur de la souris Mc. Cette fonction ne fait que demander à l'animation des engrenages de commencer à jouer, de démarrer un chronomètre, réglé sur un 12 de seconde, sorte que le moteur démarre de manière variable true et émet le signal Tous les 12 de seconde, lorsque le chronomètre expire, je déplace la position Y du corps à un entier aléatoire compris entre moins un et un positif, sorte que le corps gronde de haut en bas Mettre le boss face gauche était très similaire à la façon dont cela était fait avec le personnage du joueur, à l'exception du fait que ce boss ennemi est orienté vers la gauche par défaut. Pour que le boss se déplace et fonce vers le personnage du joueur, j'ai utilisé plusieurs variables de locomotion identiques dans le script du personnage, mais avec des noms différents, et j'ai également inclus la destination du boss et la distance qui le sépare sous forme de flotteurs, et la distance qui le sépare sous forme de flotteurs, afin de pouvoir les utiliser pour déterminer où le boss doit aller dans le J'ai également inclus la gravité au cas où et réglé la vitesse de déplacement sur la vitesse de conduite par défaut. J'ai enregistré les roues dans un tableau afin de pouvoir les synchroniser facilement. Bien que cela puisse sembler inutile pour deux roues uniquement, l' écrire de cette façon fonctionnera pour n'importe quel nombre de roues. J'ai utilisé une variable publique pour indiquer si touche de remontage de cette souris Mc a été attaquée et si elle est prête à effectuer une attaque en cours de chargement et un entier pour compter le nombre de fois qu'elle s'est écrasée sur un mur. Lorsque le script de rencontre avec le boss décide que la souris Mc doit se déplacer vers une position dans l'arène du boss et fournit la position vers laquelle se déplacer en tant que paramètre, vérifiant rapidement si le boss est mort afin que la demande puisse être ignorée, j'ai enregistré la destination, défini la direction du déplacement, la vitesse de déplacement, et je passe à vrai. J'ai appelé une fonction privée pour animer toutes les roues, puis j'ai attendu mon signal d'arrivée avant d'émettre le signal final Le signal arrivé sera émis ultérieurement par le processus physique. L'argument passé à la rotation des roues contrôle la vitesse à laquelle elles s'animeront, ainsi que le fait que l'animation sera jouée en avant ou en arrière Donc, si la souris du Mac est orientée vers la gauche et se déplace vers la gauche ou vers la droite et se déplace vers la droite, je vais lancer l'animation à une vitesse d'un. Dans le cas contraire, une vitesse négative joue les animations à l'envers. Charger le personnage du joueur fait à peu près les mêmes choses. Cependant, je veux que la souris Mc toujours orientée dans la direction dans laquelle elle se charge et fasse tourner les roues à double vitesse. Après une courte pause, cela télégraphiera la charge au joueur afin qu'il puisse réagir et s'éloigner. Comme l'accusation est une attaque, la propriété de surveillance de la boîte de frappe est définie sur true. Une fois que le chargement est réglé sur true, j'attends le signal qui sera émis lorsque la Mcmuse se sera écrasée contre un mur et autre courte pause pour que le boss reste stupéfait pendant un court N'oubliez pas de connecter le signal saisi à la zone de frappe pour réellement infliger des dégâts. faisant tourner les roues et en acceptant la direction de rotation comme paramètre, j'ai parcouru chacune des roues de mon réseau de roues et j'ai demandé à chacune de jouer son animation par défaut en utilisant la valeur absolue de la direction comme vitesse d'animation et en indiquant si la direction était négative ou non pour déterminer si l'animation devait être jouée en sens inverse J'ai également démarré les émetteurs de particules de roche et de poussière attachés à chaque roue en même temps si la valeur de la direction était autre que zéro Dans le cas contraire, ils seront désactivés. Passons maintenant au processus physique, qui rendra ces deux actions possibles Si le boss est déjà mort, il ne peut pas bouger volontairement Sa direction de déplacement sera donc fixée à zéro J'ai ensuite appliqué l'accélération ou décélération à la vitesse X du boss, ainsi que la gravité à sa vitesse Y avant appeler la fonction move and slide pour appliquer la vélocité au corps du Si le patron conduit actuellement, je dois vérifier s'il est arrivé à destination, ou s'il est en train de se recharger et touche actuellement un mur, alors je sais qu'il s'est écrasé. Pour savoir si le patron est arrivé à destination, je dois d'abord connaître la distance qui le sépare de sa destination, qui est la valeur absolue de la destination moins l'exposition globale actuelle du patron En inversant la formule de la hauteur de saut, nous pouvons déterminer si le boss est suffisamment proche de la destination pour commencer à décélérer Si la distance est inférieure au carré de la vitesse divisé par la décélération, divisé Lorsque cela est vrai, j'arrête de faire tourner les roues, mets le sens du déplacement à zéro, je passe à faux et j'ai émis le signal arrivé. Lorsque le boss s'écrase contre un mur, j'ai fait à peu près les mêmes choses, mais j'ai aussi ajouté de la vélocité pour qu' il rebondisse dessus Et j'ai éteint le hit box. J'ai également compté le nombre de fois où cela se produit et, au troisième crash, endommagé le blindage de la souris Mc , ce qui lui a permis d' entrer dans la deuxième phase Lorsque le blindage est endommagé à cause d'un trop grand nombre de collisions, j'ai augmenté la vitesse de la touche de remontage à deux Pour endommager le blindage, il me suffisait de changer la région de la feuille de sprite dessinée par le nœud de sprite d'armure J'ai également doublé la vitesse de la touche de remontage et des animations de l'équipement, ainsi que celle du chronomètre pour rendre la scène du boss encore plus instable Et j'ai activé la propriété surveillable de la Hurt Box afin que le personnage du joueur puisse désormais attaquer le corps du Mc Mouse pour lui infliger des dégâts A ensuite émis le signal pour déclencher la transition de phase. Pour photographier les boules de feu, j'avais besoin d'une scène complète pour les boules de feu, ainsi que des nouvelles boules de feu J'instanciais le marqueur indiquant où les instancier, ainsi que le canon et une interpolation pour les déplacer Quand on demande au boss de tirer plusieurs boules de feu, j'ai d'abord attendu d' étendre le canon, puis j'ai fait une boucle à plusieurs reprises, en m' j'ai d'abord attendu d' étendre le canon, puis j'ai fait une boucle à plusieurs reprises, arrêtant un quart de seconde avant chaque tir, puis en tirant une puis en tirant Après avoir tiré toutes les boules de feu, j'ai attendu de rétracter le canon avant d'émettre le signal final étendre ou rétracter le canon, il suffisait de l'interpoler en un quart de seconde, en décalant les barils de X jusqu' au chiffre souhaité Tirer sur une seule boule de feu est à peu près la même chose qu'avec les projectiles du personnage du joueur Il suffit de l'ajouter en tant que frère ou sœur placer dans la bonne position et de tirer dans le sens orienté vers l'avant Dans mon script de projectile, lorsque je demande à une boîte à blessures de subir des dégâts, je dois également indiquer la direction des dégâts Enfin, lorsque le boss n' a plus de santé, j'utilise le set différé pour désactiver la case de frappe et les deux cases de blessure et pour arrêter toutes les animations avant d' émettre le signal teint pour mettre fin à l'affrontement avec le boss Dans la scène du contenu de la salle, j'ai connecté le signal de démarrage du moteur à la fonction de démarrage de la rencontre avec le boss et le signal d'arrêt pour mettre fin à la deuxième rencontre. J'ai également connecté le signal endommagé par le blindage à la fonction de phase définie, liant deux comme argument pour déclencher la transition vers la phase deux. J'ai commenté l'appel à la fonction de démarrage afin pouvoir déclencher le début de la bataille après le démarrage du moteur. Oui Oh. maintenant Notre patron exécute maintenant une séquence complexe d' actions dont l' intensité augmente en plusieurs phases Mais notre jeu n'a aucune sorte de progression significative. Je vous verrai dans la section suivante. 65. Point de sauvegarde 9-1: Bonjour, mes amis. Dans cette section, nous allons transformer cette plateforme à deux D en Metroidvania en suivant correctement la progression du joueur Nous allons commencer par ajouter un point de sauvegarde à notre jeu. J'ai déplacé ma rencontre avec le boss dans sa propre pièce et je l'ai déplacée sur le côté de ma carte dans une région volcanique distincte également créé une nouvelle zone de sauvegarde pour ma région forestière sur la gauche. J'ai laissé mon personnage de joueur ici. Je vais juste rétablir leur position d'origine. Commençons par les données de sauvegarde des joueurs, où nous devrons enregistrer l'endroit où le joueur a enregistré sa dernière partie. façon dont vous stockez ces informations varie en fonction de la structure de votre jeu. Mais pour mon jeu, je vais utiliser un ensemble de chaînes. Bien qu'il soit peut-être plus efficace de stocker les points de sauvegarde sous forme de nombres, il ne s' agit que d'une variable unique, sorte que l'impact sera négligeable Cela permet également de garder le fichier de sauvegarde lisible par l'homme à des fins de débogage. Le premier élément du tableau sera le nom de la région et le second le nom de la pièce. Ce modèle suit la structure de mon arbre de scènes. Lorsque je charge les données de sauvegarde du joueur, il me suffit de trouver la région correspondant à la première chaîne, puis de trouver la pièce correspondant à la deuxième chaîne et de positionner le personnage du joueur au point de sauvegarde de cette pièce. Notez que ce point de sauvegarde doit exister dans le jeu au moment du chargement des données de sauvegarde et qu' aucun contenu de la pièce n'a encore été chargé. Par conséquent, l' objet Save Point doit se trouver dans la scène de la pièce plutôt que dans la scène du contenu de la pièce. Je vais ajouter un nœud en deux D à ma scène de salle de sauvegarde et le nommer point de sauvegarde Pour simplifier les choses, je vais placer ce nœud à l'endroit où je souhaite faire apparaître le personnage Comme nous aurons besoin de plusieurs de ces points de sauvegarde dans notre jeu, celui-ci doit être enregistré en tant que scène à part entière. Nous pouvons ensuite le modifier de manière isolée. C'est à vous de décider comment activer votre point de sauvegarde. Je vais juste utiliser un simple événement de collision. Ainsi, chaque fois que le joueur touche un point de sauvegarde, sa progression sera sauvegardée. Je vais donc ajouter un nœud en deux D à la scène et le décaler de 96 pixels par rapport au sol pour que le joueur doive sauter pour le toucher. J'ai importé des actifs pour mon point de sauvegarde, savoir un livre et un sprite à effets que je dessinerai derrière le livre pour le faire briller Je vais ajouter un Sprite two D no au nœud de zone pour dessiner la lueur en premier Ajoutez ensuite un Sprite animé en deux D pour le livre. Donnez-lui une ressource Sprite frames et remplissez-la avec les sprites du livre Lancer l'animation vers l'avant puis de nouveau vers l'arrière. La zone doit avoir une forme de collision Je vais donc lui donner un cercle et utiliser le rayon de la lueur, qui est de 32 pixels. Comme il s'agit de la scène la pièce et non de la scène du contenu de la pièce, il devra être commandé devant le contenu de la pièce. Il devra surveiller le corps du personnage du joueur. un En attachant script au point de sauvegarde, nous pouvons ensuite connecter le signal saisi dans le corps de la zone au script. Lorsque le personnage du joueur touche le point de sauvegarde, nous définissons la valeur de la dernière sauvegarde dans ses données de sauvegarde comme un nouveau tableau le premier élément du tableau étant le nom de la région et le second , le nom de la pièce. Nous pouvons automatiser ces noms à l'aide de la balise on ready, car le parent du point de sauvegarde sera toujours la pièce dans laquelle il se trouve, et le parent de la pièce sera toujours la région. La nature de l'arbre de scènes qui oblige les frères et sœurs à porter des noms uniques garantit que cela est suffisant pour déterminer exactement dans quelle pièce ils ont enregistré leur dernier enregistrement. Nous pouvons également prendre une référence au nœud Animated Sprite two D et lui demander de jouer son animation lorsque cela se produit N'oubliez pas de demander au nœud global du fichier de sauvegarder le jeu chaque fois que vous souhaitez rendre quelque chose permanent. Pour passer au script du gestionnaire de jeu, nous devrons charger la dernière position enregistrée par le joueur. Une fois toutes les initialisations terminées, nous appellerons une fonction pour positionner le personnage du joueur Si les données de sauvegarde du joueur ont une valeur pour la dernière sauvegarde, nous pouvons obtenir le nom de la région puisque nous savons qu'il s'agit d'un nœud enfant du monde. Ensuite, faites de même pour récupérer la chambre, sachant qu'il s'agit d'un enfant de la région. Nous pouvons ensuite positionner le personnage du joueur à la position globale du point de sauvegarde dans cette pièce. Cela déclenchera l'entrée du joueur dans cette pièce, chargera son contenu et disparaîtra comme prévu. Si le joueur n'a pas encore atteint un point sûr, je le mettrai à l' origine pour commencer la partie. Cependant, un problème survient lorsque le joueur meurt, car nous voudrons également placer le personnage du joueur à la dernière position enregistrée à ce moment-là. La séquence des événements mortels et le joueur entrant dans une pièce manipuleront le fondu en même temps Il existe plusieurs manières de résoudre ce problème, mais pour simplifier les choses, je vais vérifier si le personnage du joueur change de chambre au moment de sa mort. S'ils meurent et réapparaissent dans la même pièce, le joueur entré dans la pièce ne sera pas déclenché La séquence de mort peut donc gérer le fondu Sinon, je le remplacerai par une simple pause d'une seconde. Pour savoir si le repositionnement du personnage du joueur a changé de chambre, je vais faire en sorte que cette fonction renvoie un booléen Et retournez si la nouvelle pièce est identique à la pièce actuelle ou fausse par défaut. Essayons-le. Lorsque je charge mon jeu pour la première fois, mon personnage commence à la position par défaut dans ma salle de départ. Si je passe à gauche, je trouverai le point de sauvegarde. Sauter dans le point de sauvegarde déclenche la sauvegarde de ma partie. Si je ferme le jeu et que je rejoue , mon personnage repart au point de sauvegarde. Pour rendre mon point de sauvegarde un peu plus magique, je vais le faire flotter de haut en bas. Je vais exporter quelques variables relatives à la plage et à la vitesse d'oscillation avec une valeur par défaut de 16 pixels et une oscillation par seconde. Ce qui va se déplacer, c'est le nœud de zone, qui déplacera également les sprites lorsqu'ils sont des enfants J'ai besoin de connaître sa position Y initiale et combien de temps s'est écoulé. remplaçant la fonction du processus, je vais définir T comme étant lui-même plus Delta multiplié par la vitesse d'oscillation comprise entre zéro et tau Cela permettra à l'oscillation de se répéter à l'infini sans jamais atteindre le maximum d'un nombre à virgule flottante La position Y de la zone peut ensuite être réglée sur sa position initiale plus le sinus de T multiplié par la plage d'oscillation. Pour dessiner le point de sauvegarde sur la carte, il suffit d'ajouter un Sprite deux D à la scène du point de sauvegarde et lui donner la texture que nous voulons dessiner Agrandissez-le vraiment pour qu' il soit visible par la caméra cartographique, puis masquez-le pour qu'il ne gêne pas et joignez le script de l'icône de la carte. Il devra se trouver sur la couche de visibilité deux, et non sur la couche un, et tous ses ancêtres dans l'arbre de scène doivent être visibles à la fois sur la couche un et sur la couche deux. Je veux aussi tester le problème de la mort Je vais donc ajouter une fonction de saisie simple au script de mon personnage de joueur. Donc, lorsque j'appuie sur la barre d'espace, le personnage meurt. Maintenant, lorsque je lance le jeu, le point de sauvegarde flotte de haut en bas, et je peux le voir sur la carte. Lorsque j'appuie sur la barre d'espace, le personnage meurt et répond au point de sauvegarde. Si je déménage dans une autre pièce, je peux recommencer et répondre une fois de plus au point de sauvegarde. Nous avons maintenant un point de sauvegarde qui mémorisera la dernière position enregistrée par le joueur et la chargera au bon endroit. Dans la vidéo suivante, nous allons ajouter la possibilité de débloquer des objets qui définissent un Metroidvania Je vous verrai dans la prochaine vidéo. 66. 9-2 Metroidvania: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter au joueur des objets à collectionner qui lui permettront de débloquer ses capacités Metroidvania Je vais commencer par créer un nouveau dossier de scènes nommé Upgrades. Dupliquez ensuite ma scène Save Point, nommez-la Gem et placez-la dans le nouveau dossier Upgrades. Ouvrez-le ensuite pour le modifier. Contrairement au point de sauvegarde, je ne veux pas qu' il soit dessiné sur ma carte Je vais donc supprimer l'icône de la carte. Il n'est pas nécessaire que cela soit décalé par rapport à son origine, je vais donc réinitialiser la position des nœuds de zone. Ensuite, faites de la zone deux nœuds D, le nœud racine, renommez-le GEM et supprimez l'ancien nœud Save Point deux D. Je remplacerai les cadres Sprite du livre par de nouveaux qui dessinent une gemme en rotation Ensuite, lancez cette animation automatiquement et faites tourner en boucle à 12 images Nous pouvons ensuite joindre un nouveau script pour nos mises à niveau. En reconnectant le signal saisi par le corps des nœuds de la zone 2 au script, nous pouvons débloquer la nouvelle capacité du personnage du joueur lorsqu'il touche cette amélioration Pour ce faire, nous allons exporter une variable de type Enums dot abilities, référence au script Enums que nous avons Cela crée une liste déroulante pratique dans l'inspecteur qui nous permettra de sélectionner l'une de nos capacités à débloquer pour cet objet d' amélioration. Mais n'oubliez pas qu'une énumération n' est qu'un entier avec un nom Dans mon jeu, la gemme permettra au personnage du joueur de tirer des projectiles De retour dans le script, lorsque le corps du personnage du joueur entre dans cette zone, nous pouvons définir la valeur du point de donnée du fichier (points de données, points, capacités débloquées indexées par capacité) sur true Enregistrez ensuite le jeu pour rendre cette mise à niveau permanente. Pour que cela ait plus d'impact, nous voudrons probablement faire beaucoup de choses sophistiquées avant et après, puis éventuellement supprimer ce nœud lorsque nous aurons terminé Nous pouvons garantir qu' un seul événement de collision se produira avec ce nœud en utilisant set deferred pour désactiver sa propriété de surveillance après la première collision. Dans ma scène de sauvegarde du contenu des salles, je vais le mettre quelque part pour pouvoir le tester. R Cependant, je voulais flotter vers le haut et vers le bas, comme le fait le point de sauvegarde. Plutôt que de copier-coller le code d'un script à un autre, nous devrions en faire un composant qui peut être attaché à n'importe quel nœud deux D, peu comme les scripts de comportement des ennemis. en revenir à la scène des pierres précieuses, je vais juste ajouter un nœud normal et le nommer float. Copiez et collez ensuite le code du script Save Point dans ce script. Au lieu d'un panier de zone, ce sera simplement le parent du nœud flottant, bien qu'il doive être un no tutti ou ancêtre d'un no tutti pour avoir une position Nous pouvons ensuite copier ce nœud dans la scène Save Point et supprimer le code du script Save Point. Ces trois scripts sont beaucoup plus réutilisables lorsqu'ils sont écrits un seul but, tout en étant plus faciles à comprendre et à déboguer Une autre chose à faire est de ne pas avoir cet élément d'amélioration B ici si le joueur a déjà débloqué cette capacité remplaçant la fonction « prêt », nous vérifierons la valeur des capacités débloquées dans les données de sauvegarde des joueurs pour voir si elles sont déjà débloquées et nous mettrons en file d'attente ce nœud pour qu'il soit libéré si c'est débloquées et nous mettrons en file d'attente ce nœud pour qu'il soit libéré si En remplaçant la fonction « prêt », nous vérifierons la valeur des capacités débloquées dans les données de sauvegarde des joueurs pour voir si elles sont déjà débloquées et nous mettrons en file d'attente ce nœud pour qu'il soit libéré si c'est le cas. Essayons-le maintenant. Lorsque je lance le jeu, je peux voir mon objet d'amélioration y flotter. Appuyer sur le bouton pour tirer des projectiles ne fonctionne pas car je n'ai pas encore débloqué cette capacité En sautant pour récupérer l'objet d'amélioration, il disparaît et je peux maintenant tirer des projectiles En fermant le jeu puis en rejouant, l'objet d'amélioration n'est là puisque je l'ai déjà récupéré, et je peux toujours tirer des projectiles car la capacité a été définitivement Nous voulons maintenant que la collecte de cet objet ait plus d' impact pour le joueur Pour tester cela, nous devons supprimer nos données de sauvegarde. Dans le menu du projet, sélectionnez Ouvrir le dossier de données utilisateur pour ouvrir ce dossier dans votre gestionnaire de fichiers, où nous pouvons voir les points de sauvegarde, et nous pouvons le supprimer. Maintenant, lorsque nous lançons le jeu, le joueur n'a aucune dernière position enregistrée et aucune capacité n'est débloquée Je vais juste retourner dans la salle de sauvegarde toucher mon point de sauvegarde, puis fermer le jeu. Si vous voulez essayer de créer vous-même la séquence d'événements pour collecter l' objet, vous voudrez probablement ajouter effets de particules ou d'autres nœuds pour obtenir votre résultat. Mettez la vidéo en pause ici, puis nous passerons en revue ce que j'ai fait. Après avoir implémenté ma séquence d'événements, voici à quoi ressemblent mes résultats. Tout d'abord, j'ai déclaré une couleur blanche brillante constante. Ce n'est pas seulement du blanc, mais il a une intensité maximale, ce qui signifie que d'autres couleurs se rapprocheront également du blanc. Lorsque le personnage du joueur touche l'objet, j'arrête immédiatement le flottement vers le haut et vers le bas et je bloque le personnage du joueur en désactivant le traitement J'ai ensuite démarré un émetteur de particules émettant les particules autour de l'objet en se déplaçant vers l'intérieur Ensuite, placez l'objet à la position du personnage du joueur à mi-hauteur pour qu'il soit autour du centre de son corps, tout en tweetant les couleurs de objet et du personnage pour obtenir un blanc éclatant L'ajout de parallélisme à une fonction interpolation signifie que toutes ces opérations se produiront même temps plutôt que d' attendre la fin de l'une d'elles avant de commencer la suivante Je déverrouille ensuite la capacité et je sauvegarde le jeu comme avant. Une fois la capacité déverrouillée, masquez tous les éléments visuels, particules entrantes, lancez une rafale de particules et mettez à jour le sprite du personnage pour inclure Après avoir redéfini la couleur du personnage du joueur pour revenir au blanc normal, je réactive le traitement du personnage du joueur et je supprime cet objet de l'arborescence des scènes Les particules entrantes réutilisent les mêmes sprites que les particules de poussière du boss Ils émettent depuis une sphère d' un rayon de 32 pixels. Les particules ont une vitesse radiale négative qui les attire vers le point central, sans gravité. Alpha incurvé 1-0 et animé. Les particules émises vers l'extérieur sont généralement les mêmes, sauf qu'il s'agit d'une rafale unique avec explosivité Émission à partir d'un point présentant dispersion maximale et un amortissement suffisant pour annuler la vitesse initiale Nous avons désormais des objets de collection dans notre jeu qui offriront au joueur de nouvelles façons d'explorer le monde Mais notre jeu serait beaucoup plus amusant à explorer s'il comportait des raccourcis. Je vous verrai dans la prochaine vidéo. Et 67. Raccourci 9-3: Des amis. Dans cette vidéo, nous allons ajouter un raccourci que le joueur pourra débloquer pour rendre l'exploration de notre jeu plus fluide et plus gratifiante. J'utiliserai la deuxième pièce à droite de ma salle de départ pour créer mon raccourci dans la scène de contenu de la deuxième pièce. J'ai divisé la pièce en deux parties distinctes, et je vais placer mon raccourci au milieu afin que le joueur ne puisse pas traverser cette pièce s'il y entre par la gauche. En commençant par un corps statique à déchiffrer pour détecter les collisions, et un nœud Sprite Toti pour J'utiliserai une texture d'atlas et peuplerai le terrain de ma forêt sous forme d'atlas, puis j'utiliserai les trois tuiles verticales pour dessiner un mur ajoutant une forme de collision sous forme boîte et en recouvrant le mur d' une collision avec le terrain, le joueur ne pourra pas passer à travers. Nous pouvons ensuite ajouter un autre nœud Sprite tutti en utilisant une texture d'atlas, et j'ai déjà importé une nouvelle feuille de sprite pour un J'utiliserai le premier sprite intact et je le positionnerai sur le côté droit du mur Ainsi, si le joueur entre dans cette pièce par le côté droit, il pourra attaquer cette orthèse, l' endommager et détruire le mur pour ouvrir le raccourci L'orthèse aura besoin d' un nœud en D de la zone Hurt Box avec un enfant à deux nœuds en forme de collision Je vais utiliser une autre forme de boîte et la faire recouvrir le sprite. O. Ce serait une bonne idée de le placer sur une couche de collision différente afin que nous puissions contrôler avec soin ce qui peut l'endommager. J'utiliserai la deuxième couche pour mes raccourcis. N'oubliez pas de nommer vos couches physiques dans les paramètres du projet afin vous rappeler à quoi elles servent. Nous devrons faire en sorte que la zone de frappe masculine de nos personnages masque cette couche pour qu'ils puissent endommager le corset Ainsi que tous les projectiles qu'ils peuvent tirer. en revenir à la scène du contenu de la salle, nous devrions faire de ce raccourci sa propre scène, car nous en aurons probablement plusieurs dans notre jeu. Ce raccourci ne sera spécifiquement conçu que pour la région forestière. Je vais donc l'enregistrer dans ce dossier, et je devrai créer d'autres scènes de raccourci pour mes autres régions. ouvrant cette scène, nous pouvons associer le script Hurt Box au nœud Hurt Box et également attacher un nouveau script au nœud racine pour le comportement des raccourcis. L'objectif principal de ce script sera de sauvegarder lorsque ce raccourci est détruit et de le conserver détruit lors du chargement du contenu de cette pièce. Pour ce faire, nous utiliserons ce que l'on appelle communément un drapeau en exportant une variable de chaîne pour le nom du drapeau. Dans la scène du contenu de la pièce, nous devrons spécifier un nom de drapeau pour ce raccourci. Nous pouvons donner à ce drapeau le nom que nous voulons, mais il doit être unique pour chaque raccourci de notre jeu. Je vais appeler le raccourci Forest Second Room. Pour passer au script de données, nous aurons besoin d'une nouvelle variable exportée pour contenir nos drapeaux dans un dictionnaire. En utilisant la chaîne comme clé, la valeur sera une valeur booléenne De retour dans le script de raccourci, lorsque ce raccourci est détruit, nous pouvons définir la valeur des indicateurs de points de données du fichier la clé étant le nom de notre indicateur, et définir la valeur sur true. Enregistrez ensuite le jeu pour le rendre permanent et après avoir effectué quelques modifications visuelles, supprimez le raccourci de l'arborescence des scènes. remplaçant la fonction ready, nous pouvons vérifier la valeur de notre drapeau pour voir si le raccourci a déjà été détruit et le supprimer de l'arborescence des scènes si c'est le Toutefois, si le raccourci n' a pas encore été détruit, le dictionnaire n'aura pas encore de valeur pour le nom de ce drapeau. Nous devons donc d'abord vérifier si la valeur existe avant d'essayer d'y accéder. Connectons le signal de dégâts reçus de la boîte Hurt à la fonction de destruction des raccourcis, annulant ainsi l'argument Je vais déplacer la deuxième pièce à gauche de la salle de sauvegarde afin de pouvoir la tester. En entrant dans cette pièce par la droite, le mur empêche mon personnage de passer. Je peux attaquer le corset pour le détruire, ce qui détruit le mur, et je peux le traverser En fermant le jeu et en le relançant, le raccourci reste ouvert. Cependant, il y a un petit problème. Je vais réorganiser mes pièces manière à ce que la deuxième pièce soit de nouveau sur la droite, puis je supprimerai mon fichier sécurisé pour rétablir le raccourci Lancer à nouveau le jeu. Le mur empêche mon personnage de continuer. Cependant, je peux toujours ouvrir le raccourci de ce côté. Nous devrons donc empêcher notre personnage d' attaquer à travers les murs. En ouvrant la scène du personnage, nous pouvons ajouter un nœud cast two D à la zone de frappe. Nous utiliserons la même stratégie que celle utilisée pour l'agression ennemie afin vérifier s'il existe une ligne claire entre la zone de frappe et la zone de blessure. Pour ce faire, le rayon doit provenir du centre du personnage, et nous devons masquer tout ce que cette zone de frappe peut toucher, ainsi que tout ce qui peut l' obstruer, comme le terrain, y compris les corps et les zones Le rayon peut également provenir de l'intérieur de certains de ces collisionneurs Il devra donc également être capable de toucher des zones et des corps de l'intérieur de leur forme. Dans le script Hit box, nous pouvons récupérer une référence à ce nœud cast avec une balise on ready, mais je vais modifier le chemin du nœud pour utiliser get node ou null. De cette façon, il n'est pas nécessaire que toutes les boîtes à succès de notre jeu soient associées à un raycast En cas de collision, nous vérifierons d'abord si le rayon existe, puis nous lui demandons de pointer du la boîte à blessures touchée par la zone de frappe et de le forcer à se mettre à jour immédiatement. Si le rayon projeté touche quelque chose et que cet objet est autre chose que la zone, cela signifie qu'il y a autre chose sur le chemin. Le retour empêchera les dommages de se produire. Si nous lançons le jeu maintenant, attaquer le raccourci du mauvais côté sera bloqué par le Walls Collider Si je déplace cette pièce vers la gauche et que j' entre par la droite, je peux attaquer le corset et détruire le mur puisque le rayon tiré par la zone de frappe du personnage n'est pas obstrué Si vous le souhaitez, vous pouvez faire une pause ici et ajouter des effets de particules, secouer et même recourir à plusieurs attaques pour briser le corset avant de détruire le mur Maintenant que j'ai ajouté mes effets, voici à quoi ressemblent mes résultats. Après une attaque, le mur émet des particules de poussière, des secousses et le support est visiblement endommagé Après une seconde attaque, le corset se brise en plusieurs morceaux, le mur est retiré et les particules sont à nouveau émises Pour obtenir cet effet, j'ai ajouté des particules GPU au nœud émettant les mêmes particules de poussière que celles utilisées précédemment, mais cette fois en forme de boîte. J'ai ajouté un nœud de débris sous forme de dossier contenant trois pièces différentes sous forme de corps rigides. Et un minuteur à secousses qui émettra un signal 12 fois par seconde. En connectant le signal reçu endommagé du boîtier Hurt à une fonction reçue endommagée, j'ai redémarré l'émetteur de particules, puis j'ai vérifié si c' la première fois qu' il était Si elle est déjà endommagée, je désactive détection de collision sur la Hurt Box et je détruis le mur. Sinon, réglez les dégâts sur true, mettez à jour le corset, sprite pour dessiner la version endommagée, puis lancez le chronomètre et arrêtez-le 1 seconde Le signal de temporisation du temporisateur appelle cette fonction de tremblement, qui décale simplement le mur d'un pixel dans une direction aléatoire Lorsque le mur est détruit, j'ai mis à jour les données de sauvegarde comme auparavant, mais j'ai également dispersé des débris, masquant à la fois le mur et le support. Attendez ensuite que les particules soient terminées avant de supprimer toute la scène. Pour disperser les débris, je les ai rendus visibles, puis j'ai dégelé toutes les pièces et j'ai ajouté des forces d' impulsion égales à leur position par rapport au parent Nous disposons désormais d'un raccourci que le joueur peut ouvrir, ce qui lui permet de revenir en arrière beaucoup plus facilement lorsqu'il explore notre monde Mais la carte entière est clairement visible pour eux dès le début du jeu Je vous verrai dans la prochaine vidéo. 68. Carte 9-4: Bonjour, mes amis. Dans cette vidéo, nous allons masquer notre carte au joueur et ne dévoiler les pièces que lorsque le joueur y entre. À partir de notre script de sauvegarde des données, nous pouvons utiliser la même stratégie que celle utilisée le point de sauvegarde pour suivre les pièces dans lesquelles le joueur est entré. Nous allons exporter une nouvelle variable nommée map of type dictionary. Les clés de ce dictionnaire seront les noms des régions, et les valeurs seront celles d' un autre dictionnaire. Les clés du second dictionnaire seront les noms des pièces de cette région, et les valeurs seront des booléens si le joueur est entré ou non dans cette pièce Si nous regardons l'une de nos scènes de chambre, la carte sera dessinée par une forme de nœud Tu Di. Dans mon jeu, ils sont dessinés par un nœud de la couche Tile Map. Quel que soit le nœud, il est assez trivial de modifier sa visibilité Nous allons décrire une référence à ce nœud dans notre script de salle. Vous pouvez utiliser la balise ready si le nœud de la carte est uniforme pour toutes les pièces l'ensemble de votre projet ou une balise d'exportation si vous souhaitez plus de flexibilité, mais vous devrez l' attribuer manuellement à chaque pièce. Nous aurons également besoin que chaque pièce connaisse le nom de la région dans laquelle elle se trouve, ce que nous pouvons automatiser à l' aide d'une balise ready, en obtenant le nom du nœud parent de la pièce dans l'arborescence des scènes. Nous pouvons ensuite écrire une fonction pour mettre à jour la visibilité de la carte en fonction du fait que le joueur est déjà entré dans cette pièce ou non . En vérifiant le fichier point data point map indexé au nom de la région nous obtenons un autre dictionnaire pour la région, que nous pouvons indexer au nom de la pièce Il s'agira d'un booléen indiquant si le joueur est déjà entré dans cette salle ou non Et si c'est le cas, nous définirons la visibilité des cartes sur true. Cependant, tout comme pour le dictionnaire des drapeaux, nous devons faire attention à ne pas essayer d' accéder à des entrées de dictionnaire qui n'existent pas. Mais cela offre une opportunité supplémentaire dans ce cas, car nous pouvons utiliser l'absence de l' entrée du dictionnaire comme information supplémentaire. Par exemple, nous pouvons vérifier si le dictionnaire cartographique contient une entrée pour cette région. Si ce n'est pas le cas, cela signifie que le joueur n' est jamais entré dans cette région auparavant. De même, si l' entrée de la pièce n'existe pas, le joueur ne sait même pas que cette pièce existe. Nous devons d'abord vérifier si l'entrée de région existe dans le dictionnaire cartographique. Si ce n'est pas le cas, le joueur ne devrait pas être en mesure de voir cette carte, et nous pouvons simplement quitter cette fonction. Faites ensuite la même chose avec l'entrée de la pièce dans le dictionnaire des régions. Si l'entrée n' existe pas, je masquerai la carte. Cependant, s'il existe, nous pouvons définir la visibilité sur true et vérifier la valeur du booléen Si le booléen est vrai, je vais régler les cartes modulant Alpha à Mais si c'est faux, je vais le configurer pour qu'il soit semi-transparent. Cela signifie que je peux différencier les pièces sur la carte le joueur connaît de celles dans lesquelles il a déjà pénétré. Vous pouvez également utiliser un nœud différent pour dessiner ces différents états et activer la visibilité de chaque nœud individuel Nous pouvons initialiser la visibilité de la carte lors de la fonction de préparation Nous pouvons écrire une autre fonction pour découvrir une pièce et en révéler le plan. Pour créer nos deux états cartographiques différents, nous pouvons accepter un paramètre booléen indiquant si cette pièce est découverte en le saisissant suffit à cette fonction de définir la valeur du fichier point data point map, indexée au nom de la région, indexée au nom de la pièce sur la valeur Entered Mais si cette valeur existe déjà et a été définie sur true, nous ne voulons pas la remettre sur false. Nous pouvons utiliser l' opération logique ou la définir sur false uniquement si ce n'est pas déjà le cas. Appelez ensuite la fonction de visibilité Update Map pour commencer à la dessiner en conséquence. Si la région n' existe pas encore dans le dictionnaire des cartes, il s'agit de la première pièce découverte par le joueur dans cette région. Ce serait une bonne occasion faire quelque chose d'intéressant, comme afficher une carte de titre ou jouer une scène de raccourci pour présenter au joueur la nouvelle région. Je vais appeler une fonction non encore écrite pour la région nommée Discover. Cela sera chargé initialiser l' entrée du dictionnaire cartographique pour la région. passant au script du gestionnaire de jeu, lorsque le personnage du joueur entre dans une nouvelle pièce, nous pouvons découvrir cette pièce avec un argument vrai pour la rendre opaque sur la carte. Dans la scène principale du jeu, nous pouvons associer un script aux régions de notre jeu. écrivant la fonction de découverte, elle sera appelée la première fois En écrivant la fonction de découverte, elle sera appelée la première fois qu'un joueur entre dans une pièce de cette région. Nous pouvons donc commencer par créer l'entrée du dictionnaire cartographique pour cette région dans les données de sauvegarde du joueur. Je profiterai également de l'occasion pour ajouter la région à la carte du joueur en utilisant une fonction de révélation de la carte. Cela va simplement parcourir chaque pièce de cette région et le découvrir, mais avec un argument faux, il sera dessiné de manière semi-transparente Ce script devra être associé à toutes les régions. Dans chacune de mes scènes de région, j'ajouterai également un nœud d'étiquette pour afficher le nom de cette région sur la carte. Pour que cela soit lisible sur la caméra cartographique, il faudra une très grande taille de police. Je vais définir la taille de police à 256. Définissez ensuite la couleur de police pour qu' elle corresponde à la couleur des pièces. Pour le faire ressortir davantage, j'ajouterai également une ombre et un contour. Il devra se trouver sur la couche de visibilité 2 pour que la caméra cartographique puisse le voir. Je vais copier cette note d'étiquette dans la région de mon volcan et changer la couleur du texte pour qu'elle corresponde à cette région. En ajoutant une couche de toile à la deuxième scène de région, nous pouvons créer une simple carte de titre à afficher lorsque le joueur entre pour la première fois dans chaque région. Avec un autre nœud d'étiquette, j'afficherai le nom de cette région au centre de l'écran avec une grande taille de police. Je vais le rendre invisible par défaut et ne l' afficher que lorsque le joueur entre dans cette région pour la première fois. Dans le script de région, je vais animer cet affichage avec un interpolation, interpolant l'alpha du nœud d' étiquette jusqu'à un, attendant 1 seconde, puis en le redescendant à Il devra avoir un Alpha de zéro pour démarrer et être rendu visible. Cela peut être copié dans mes autres régions et mis à jour avec leurs noms. Lorsque la région sera découverte, je sauvegarderai le jeu et je rendrai l'étiquette de la carte visible. Cela devra également être initialisé dans la fonction Ready selon que l'entrée de région existe ou non dans le dictionnaire de cartes Maintenant que les régions ont des enfants qui ne sont pas dans des chambres, je dois vérifier s' sont réellement des chambres avant d'appeler leurs fonctions de découverte. Essayons-le. Lorsque le jeu commence, le joueur entre automatiquement dans la région forestière. La carte de titre de la région forestière est donc affichée. Ses données cartographiques sont révélées, mais seule la salle de départ est opaque puisque c'est la seule pièce dans laquelle je suis entrée. Au fur et à mesure que j'entre dans chaque pièce, les pièces passent de transparentes à opaques. J'ai supprimé le raccourci de l'autre pièce pour faciliter les choses. La région du volcan n'a pas encore été saisie, elle n'est donc pas révélée sur la carte. Et lorsque j'entre dans la région du volcan, elle affiche sa carte de titre et ses chambres sont ajoutées à la carte. Bien que je n'aie encore rien construit d' adapté à cette région. Pour en revenir à la région forestière, la région a déjà été découverte et n' affiche donc pas sa carte de titre. Nous disposons désormais d'un système permettant de révéler progressivement la carte de notre jeu au fur et à mesure que le joueur explore notre monde. Mais les régions de notre jeu seraient beaucoup plus distinctes avec de la musique de fond. Je vous verrai dans la prochaine vidéo. 69. Musique 9-5: Bonjour, mes amis. Dans cette vidéo, nous allons ajouter une musique de fond qui changera selon les régions du jeu. Cela permettra non seulement de mettre en valeur l'apparence unique de chaque région, mais aussi de donner une impression supplémentaire de progression. Lorsque vous importez de la musique de fond dans votre projet de jeu, sélectionnez les fichiers dans l'onglet Système de fichiers, puis ouvrez l'onglet Importer et changez le mode boucle pour avancer. Sinon, votre musique ne sera jouée qu'une seule fois, puis s'arrêtera. Cela nécessitera une réimportation des actifs. Dans chacune de nos scènes régionales, nous pourrions installer un nœud de lecteur de flux audio pour écouter ces morceaux de musique. Mais cela nous obligerait à gérer lequel joue à un moment donné, ce qui est un peu compliqué En général, nous ne voulons pas écouter plus d'une piste de musique de fond à la fois de toute façon. Il serait donc plus facile de n' avoir qu'un seul nœud de lecteur de flux audio dédié à la lecture de musique de fond auquel nous pouvons accéder depuis n'importe où dans notre jeu. Mais chaque région doit tout de même savoir quelle musique de fond doit être jouée pour elle. Dans notre script de région, nous pouvons exporter une variable pour conserver la musique de fond de cette région sous forme de flux audio. Remplissez ensuite la variable exportée pour chaque région dans ses scènes individuelles avec différents fichiers musicaux Nous pouvons ensuite créer un script global pour gérer notre musique de fond, héritant d' Audio stream Player Ouvrez ensuite les paramètres du projet, l'onglet Globals, et ajoutez ce script à la liste des nœuds globaux Pour en revenir au script, nous n'avons vraiment besoin que de deux fonctions publiques, l'une qui indiquera au script de jouer une piste musicale et d'accepter le flux audio comme paramètre, et l'autre pour arrêter de jouer de la musique. Mais arrêter la musique soudainement serait un peu choquant. Il est assez courant d'atténuer la musique en réduisant progressivement le volume avant de l'arrêter. En commençant par la fonction de lecture de piste, nous pouvons régler le flux en cours de lecture selon le paramètre de piste et appeler la fonction de lecture du lecteur de flux audio pour commencer à le lire. Mais si quelque chose fonctionne déjà , nous devons d'abord l'arrêter. Donc, si ce script joue déjà quelque chose et que ce qu'il joue est le même que celui que nous voulons jouer, nous pouvons simplement revenir. Si ce n'est pas pareil, nous pouvons d'abord attendre de passer au volume, puis pouvons d'abord attendre de passer au volume, puis passer à la nouvelle piste et revenir en mode fondu Pour atténuer progressivement le volume, nous aurons besoin d'un interpolation et d'une fonction d' interpolation du volume, acceptant la valeur finale du volume comme paramètre Après avoir vérifié si l'interpolation existe déjà et après l'avoir supprimée, nous allons créer une nouvelle interpolation et interpoler le volume jusqu'à sa valeur finale pendant Je vais juste utiliser une seconde. Le volume est généralement mesuré en décibels, ce qui n'est pas une unité de mesure linéaire Il n'est donc pas recommandé d'interpoler le volume en décibels. Nous utilisons plutôt la valeur de volume linéaire, qui est un simple flottant compris entre zéro pour le volume muet et un pour le volume normal Nous pouvons renvoyer le signal de fin de l'interpolation afin de pouvoir l'attendre Pour arrêter de jouer de la musique, il suffit d'attendre que le volume atteigne zéro, puis d'appeler stop et de renvoyer le signal final. Et après avoir changé de piste, nous devrions baisser le volume à un afin que nous puissions entendre la nouvelle musique. Il ne nous reste plus qu'à indiquer à ce nœud le morceau de musique à écouter et à quel moment. Par souci de simplicité, je suppose que lorsque le contenu d'une pièce est chargé, je souhaite écouter la musique je souhaite écouter la musique associée à cette région. Donc, en appelant Music Play Track, je vais passer par la région, qui est le parent du room point Music. S'il est demandé de jouer la même musique que celle déjà diffusée, le nœud musical global ignorera simplement la demande. Il n'est donc pas nécessaire de vérifier ce qui joue déjà. Essayons-le. En lançant le jeu, je commence par la région forestière, et c'est ainsi que le thème de la musique forestière joue. vestiaires, la musique ne change pas tant que je suis encore dans la région forestière. Mais si je passe à la région des volcans, le thème de la région forestière disparaît et celui de la région des volcans joue à la place Il y aura probablement des moments où vous souhaiterez écouter temporairement un morceau de musique spécifique, exemple lors d'une cinématique ou d'un combat contre un boss. Ajoutons donc deux autres fonctions à notre script musical. Un pour remplacer le morceau de musique actuel et un autre pour revenir au morceau de musique précédent Nous aurons besoin d'une variable pour contenir la musique de fond de la région actuelle. Lorsqu'on nous demande de remplacer la musique de fond par une nouvelle piste musicale, nous stockons d'abord la musique de fond de la région dans notre variable Attendez ensuite que le fondu disparaisse et écoutez notre nouveau morceau. Une fois l'événement terminé, nous pouvons revenir à musique de fond de notre région en disparaissant, puis en écoutant l' ancien morceau de musique Dans notre script de rencontre avec un boss, nous pouvons exporter une variable pour contenir une piste musicale spéciale pour la musique de notre boss. Ensuite, lors de la rencontre avec le boss de Mc Mouse, nous pouvons donner à ce combat de boss son propre morceau de musique spécial. Le nœud musical global peut être invité à jouer cette musique lorsque la rencontre avec le boss commence. Et revient à la musique de fond de la région une fois le combat terminé Enfin, il faut indiquer à ce nœud musical à quel bus il appartient sur le bus audio afin que nous puissions contrôler plus facilement son volume dans d'autres paramètres. Ainsi, en remplaçant la fonction Ready, nous pouvons définir manuellement la valeur du bus comme étant de la musique Nous disposons désormais d'un système musical mondial que nous pouvons utiliser pour écouter la musique dont nous avons besoin pour notre jeu, mais notre rencontre avec le boss doit encore être améliorée. Je vous verrai dans la prochaine vidéo. 70. 9-6 Boss final: Bonjour, mes amis. Dans cette vidéo, nous allons terminer la rencontre avec un boss avec une arène et empêcher le boss de réapparaître une fois vaincu J'ai réorganisé mes pièces de manière à ce que le joueur commence dans la salle de sauvegarde située juste à côté de la salle du boss En ouvrant le contenu des salles Boss, j'ai créé la scène de contenu de la salle Boss avec plusieurs couches de parallaxe Pour que le nœud en deux D de la couche Tile Map puisse défiler en parallaxe, j'ai dû créer un nouveau script héritant de la couche Tile Map sans le défilement automatique Comme le nœud 2D de la couche Tile Map ne possède pas la propriété Region Wrecked, il ne peut pas utiliser la même méthode si nous voulions le faire défiler automatiquement Chaque nœud de la couche Tile Map associé à Di possède une échelle de défilement différente et module davantage en fonction de la couleur d'arrière-plan Pour savoir quels boss le joueur a vaincus, ouvrons le script de données et ajoutons une nouvelle variable nommée Boss est vaincu. Une alternative à l'utilisation d'un dictionnaire est un tableau. Chaque fois qu'un boss est vaincu, nous pouvons simplement ajouter son nom à ce tableau Dans le script de rencontre avec un boss, nous pouvons annuler la fonction Ready pour vérifier si ce boss a déjà été vaincu Si le boss du fichier point data point boss est vaincu possède une entrée correspondant au nom du boss, cela signifie que le joueur a déjà vaincu ce boss et que nous pouvons supprimer cette rencontre avec ce boss. Lorsque le boss est vaincu, nous pouvons ajouter son nom au tableau des boss au tableau des boss Enregistrez ensuite le jeu pour le rendre permanent. Contrairement aux dictionnaires, les tableaux peuvent comporter des doublons. Ainsi, lorsque vous stockez des informations de cette manière, vous souhaiterez peut-être vérifier si l'entrée existe déjà avant de l'ajouter. Supprimer le nœud de rencontre avec le boss de l' arborescence des scènes pour le moment supprimera également le boss lui-même, ce que je ne veux pas faire. Mais si le joueur quitte la pièce et y revient, le boss sera supprimé par la fonction « prêt ». Cela sera suffisant pour que le boss reste vaincu, mais la rencontre elle-même pourrait nécessiter quelques améliorations. La première chose que j'ai envie de faire lorsque le combat contre le boss commence est de fermer une porte verrouillant le joueur dans l'arène. Tout comme pour le raccourci, j'ai utilisé un corps statique pour dénouer le nœud, en réutilisant le même sprite mural que le terrain Et une forme de collision rectangulaire. Cependant, le sprite et la forme de collision sont positionnés bien au-dessus du point d'origine de la porte, sorte que la porte est ouverte par défaut Lorsqu'on lui demande de fermer, la porte repositionne la forme de collision, puis ajuste la position du sprite pour qu'elle corresponde, et l'ouverture de la porte ramène la forme de collision et le sprite à leur position initiale donnant un nom unique à cette porte, nous pouvons la fermer dans En donnant un nom unique à cette porte, nous pouvons la fermer dans le script de rencontre du boss au début de la bataille et l'ouvrir à la fin de la bataille N'oubliez pas d'appeler les fonctions de superclasse pour qu'elles fassent également tout le reste dans les fonctions de début et de fin. Je veux aussi que le boss se batte plus fort en faisant tomber des rochers enflammés du plafond J'ai donc créé une autre scène pour les rochers enflammés, qui sont un corps rigide à deux Cela gérera automatiquement la gravité pour moi. Ils sont dessinés et animés par un nœud 2D de sprite animé, parcourt automatiquement les sprites importés à 12 images par seconde. Le corps rigide repose sur une nouvelle couche de collision spécialement conçue pour les dangers et ne masque rien Ils n'entreront donc en collision avec rien, y compris le terrain. Ils tomberont simplement du dessus de l'arène vers le dessous de l'arène, et une boîte de frappe y est attachée, surveillant la boîte à blessures du personnage du joueur. N'oubliez pas de vous connecter au signal de la zone saisie pour infliger des dégâts. Dans mon script Mc Mouse Encounter, j'ai exporté une variable pour ce rocher enflammé prenne la forme d'une scène pleine, que je peux instancier sous la forme d'un nouveau corps rigide de rocher enflammé Lorsqu'on m'a demandé de faire apparaître des rochers enflammés, j'ai fait une boucle plusieurs fois au hasard entre le numéro de phase et le numéro de phase multiplié par deux, de sorte que le nombre de rochers augmente au cours de Instanciez un nouveau rocher, je l'ai ajouté à la scène et je l'ai positionné au-dessus l'arène à une position aléatoire entre les murs gauche et droit Pour rendre l'accident encore plus percutant, je vais également ajouter un tremblement de caméra Godot permet d' accéder assez facilement à la caméra actuelle de n'importe où Tout d'abord, il suffit d'appeler la fonction Get Viewport, puis d'appeler la fonction Viewports Get camera two D. Nous pouvons ensuite appeler notre fonction de tremblement pour secouer l'appareil photo. Je vais lui donner une intensité de deux pixels pendant un quart de seconde. Je peux ensuite connecter le signal de crash de la souris Mc au script de rencontre pour déclencher l'apparition des rochers enflammés en réponse à cela Comme les rochers sont des corps rigides, ils tomberont naturellement sous l'effet de la gravité Je peux ensuite les nettoyer une fois qu'ils sont tombés sous le bas de l'aréna en utilisant une zone deux D. Cette zone de collecte des déchets est juste une zone rectangulaire qui couvre le bas de l'aréna, suffisamment en dessous pour que tout ce qui entre dans cette zone ne soit pas visible par la caméra. Le nœud de zone surveille et masque la couche des dangers Son signal saisi dans le corps est reconnecté au contre-script de la souris Mc pour les supprimer de l'arbre des scènes. À la suite des modifications apportées à la zone de frappe de notre personnage, qui exigeaient que le casting entre la zone de frappe et la boîte à blessures ne soit pas obstrué, j'ai dû réorganiser la boîte à touches de ma souris Mac À présent, la Hurt Box détermine la position et la forme de collision est à sa position d'origine locale. Comme le nœud Area two D détermine lui-même la position, le script n'a plus besoin de faire référence à la forme de collision et change sa propre position en réponse au changement de direction du personnage Essayons-le. J'entrerai dans ma chambre de boss et j'y trouverai mon boss ennemi assis. Je peux attaquer la clé pour terminer la partie et lancer la rencontre avec le boss. Cela déclenche le début de mon combat contre le boss, qui change la musique et ferme la porte de l' arène, me piégeant Lorsque je combats le boss, chaque fois qu'il percute un mur, caméra tremble et fait tomber des rochers enflammés Bien que nous ne puissions pas voir ce qu'il advient des rochers enflammés lorsqu' ils tombent sous la caméra, ils sont en train d'être nettoyés par la zone de collecte des ordures Lorsque le boss entre dans sa deuxième phase, le nombre de rochers enflammés générés augmente, et le fait de le vaincre met fin à la rencontre, redonnant la musique à la région du volcan et ouvrant la En quittant la pièce et en revenant, la rencontre avec le boss n' est plus là. Nous avons maintenant tout ce dont nous avons besoin pour créer un jeu Metroidvania complet Dans la vidéo suivante, nous allons passer en revue les prochaines étapes. Je vous verrai dans la prochaine vidéo. 71. 9-7 Final: Bonjour, mes amis. Félicitations pour avoir terminé le cours. Vous disposez désormais de tous les outils et compétences nécessaires pour créer un jeu Metroidvania de base, des capacités à débloquer qui permettront progressivement au joueur d'accéder à une plus grande partie du monde pour explorer une carte indiquant sa position actuelle et économiser des points pour suivre Il ne reste plus qu'à répéter la plupart des leçons enseignées tout au long du cours pour en créer davantage. Plus de pièces, plus de régions avec plus d'ennemis à combattre et plus de raccourcis à débloquer. Suivez ces étapes pour tirer parti de ce cours et continuer à acquérir de nouvelles compétences que vous pourrez utiliser pour créer votre propre jeu Metroidvania Première étape. S'il s'agit de votre premier projet de jeu majeur, vous devriez être capable de créer un jeu suivant ce modèle avec au moins trois régions différentes, chacune avec plusieurs pièces contenant différents types d' ennemis, défis de plateforme, et ces régions devraient être distinctes les unes des autres Conformément aux principes de conception du jeu Metroidvania, votre jeu doit démontrer au joueur les obstacles qu'il est incapable de surmonter avant de débloquer la possibilité de le Le chemin critique du jeu devrait nécessiter de revenir en arrière dans les zones précédentes et donner au joueur nombreuses nouvelles opportunités d' exploration avec ses nouvelles capacités. Essayez de créer un jeu qui prend au moins 10 minutes du début à du début à fin sans être trop répétitif. Deuxième étape, une fois que vous aurez terminé votre jeu et que vous aurez envie de relever plus de défis, vous voudrez peut-être penser à quelque chose que vous souhaitez changer. Peut-être que vous n'aimez pas la façon dont fonctionne le saut de mur ou que vous souhaitez ajouter une force de recul à l'attaque du personnage du joueur Essayez de trouver un moyen d' ajuster le mécanisme pour qu'il fonctionne comme vous le souhaitez et de changer la façon dont il est implémenté dans le jeu. Essayez d'éviter de créer quelque chose de complètement nouveau pour le moment. Concentrez-vous simplement sur les ajustements à apporter à ce qui existe déjà. Troisième étape. Une fois que vous serez en mesure d'apporter des modifications aux mécanismes existants, étape suivante devrait être d'ajouter un nouveau mécanisme utilisant les outils déjà fournis. Vous voudrez peut-être ajouter au jeu un objet de collection qui augmente la santé maximale du joueur ou un nouveau sort qui soigne le personnage du joueur L'ajout de ces mécanismes au jeu ne nécessite aucune nouvelle compétence, mais vous devez apprendre à intégrer plusieurs systèmes existants d'une nouvelle manière. Vous pouvez également rechercher de nouveaux actifs à utiliser pour vos nouveaux mécanismes ou essayer de créer les vôtres. Quatrième étape. Maintenant que vous pouvez faire fonctionner les mécanismes existants comme vous le souhaitez et les intégrer à de nouveaux systèmes, il est temps de concevoir et construire un nouveau mécanisme à partir de zéro. Il pourrait s'agir d'une toute nouvelle capacité de Metroidvania qui permettrait au joueur d' accéder à une plus grande partie du monde, en ajoutant des PNJ avec lesquels le joueur pourrait parler via un système de dialogue, en obligeant les ennemis à déposer de l'argent pour que le joueur puisse le collecter et en leur permettant de dépenser cet argent dans un magasin pour Avant de commencer, assurez-vous prendre le temps de réfléchir à tous les systèmes existants qui devront communiquer avec le nouveau mécanicien. Déterminez quelles parties de votre conception doivent être abstraites ou quelles parties peuvent être héritées de scripts existants Cinquième étape. Si vous pouvez créer un système entièrement nouveau et l'intégrer avec succès dans ce jeu, vous devriez être prêt à créer un nouveau jeu à partir de zéro. Trouvez un pack d'actifs différent en ligne ou créez vos propres actifs à utiliser pour créer un tout nouveau jeu Metroidvania à partir de zéro, entièrement personnalisé Vous êtes invités à partager votre travail sur notre serveur Discord tout en continuant à apprendre et à développer vos compétences grâce à ce projet Sixième étape. Une fois que votre jeu est prêt, vous pouvez le partager sur des plateformes comme Ich pour recueillir commentaires des joueurs et même vendre le jeu une fois terminé. Vous ne gagnerez probablement pas beaucoup d'argent en vendant des jeux sur IH, mais les commentaires seront une valeur inestimable pour améliorer vos compétences en matière de développement de jeux. Si vous avez un jeu qui s'est bien comporté sur Ich, vous pouvez essayer de le vendre sur Steam pour toucher un public beaucoup plus large. Mais la barre de qualité pour qu'un jeu réussisse sur Steam est bien plus élevée. Et vous aurez besoin d' une stratégie de marché si vous voulez que votre jeu soit remarqué par les joueurs. Bonne chance dans la réalisation de votre projet. J'ai hâte de voir votre travail.