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.