Créer l'ennemi¶
Il est temps maintenant de créer des ennemis que notre joueur devra esquiver. Leur comportement ne sera pas très complexe : des monstres vont apparaître au hasard aux bords de l'écran et se déplacer dans une direction aléatoire en ligne droite, puis disparaître lorsqu'ils sortent de l'écran.
Nous allons créer une scène Mob
, que nous pouvons ensuite instancier pour créer un nombre quelconque de monstres indépendants dans le jeu.
Configuration du nœud¶
Cliquez sur Scène -> Nouvelle scène et ajoutez les nœuds suivants :
RigidBody2D (nommé
Mob
)
N'oubliez pas de configurer les enfants pour qu'ils ne puissent pas être sélectionnés, comme vous l'avez fait avec la scène Player.
Dans les propriétés du RigidBody2D, réglez Gravity Scale
sur 0
, afin que le monstre ne tombe pas vers le bas. De plus, sous la section CollisionObject2D, cliquez sur la propriété Mask
et décochez la première case. Cela permettra de s'assurer que les monstres n'entrent pas en collision les uns avec les autres.
Configurez l'AnimatedSprite comme vous l'avez fait pour le joueur. Cette fois, nous avons 3 animations : fly
, swim
, et walk
. Il y a deux images pour chaque animation dans le dossier art.
Ajustez la vitesse "Speed (FPS)" à 3
pour toutes les animations.
Mettez la propriété Playing
dans l'inspecteur sur "On".
Nous allons choisir une de ces animations au hasard pour que les monstres aient une certaine variété.
Comme les images du joueur, ces images de monstre doivent être réduites. Réglez la propriété Scale
d' AnimatedSprite
sur (0.75, 0.75)
.
Comme dans la scène Player
, ajouter un CapsuleShape2D
pour la collision. Pour aligner la forme avec l'image, vous aurez besoin de paramétrer la propriété Rotation Degrees
à 90
(sous "Transform" dans l'inspecteur).
Enregistrer la scène.
Script de l'ennemi¶
Ajoutez un script au Mob
comme ceci :
extends RigidBody2D
public class Mob : RigidBody2D
{
// Don't forget to rebuild the project.
}
// Copy `player.gdns` to `mob.gdns` and replace `Player` with `Mob`.
// Attach the `mob.gdns` file to the Mob node.
// Create two files `mob.cpp` and `mob.hpp` next to `entry.cpp` in `src`.
// This code goes in `mob.hpp`. We also define the methods we'll be using here.
#ifndef MOB_H
#define MOB_H
#include <AnimatedSprite.hpp>
#include <Godot.hpp>
#include <RigidBody2D.hpp>
class Mob : public godot::RigidBody2D {
GODOT_CLASS(Mob, godot::RigidBody2D)
godot::AnimatedSprite *_animated_sprite;
public:
void _init() {}
void _ready();
void _on_VisibilityNotifier2D_screen_exited();
static void _register_methods();
};
#endif // MOB_H
Maintenant, regardons le reste du script. Dans _ready()
, nous jouons l'animation et choisissons au hasard un des trois types d'animation :
func _ready():
$AnimatedSprite.playing = true
var mob_types = $AnimatedSprite.frames.get_animation_names()
$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]
public override void _Ready()
{
var animSprite = GetNode<AnimatedSprite>("AnimatedSprite");
animSprite.Playing = true;
string[] mobTypes = animSprite.Frames.GetAnimationNames();
animSprite.Animation = mobTypes[GD.Randi() % mobTypes.Length];
}
// This code goes in `mob.cpp`.
#include "mob.hpp"
#include <RandomNumberGenerator.hpp>
#include <SpriteFrames.hpp>
void Mob::_ready() {
godot::Ref<godot::RandomNumberGenerator> random = godot::RandomNumberGenerator::_new();
random->randomize();
_animated_sprite = get_node<godot::AnimatedSprite>("AnimatedSprite");
_animated_sprite->_set_playing(true);
godot::PoolStringArray mob_types = _animated_sprite->get_sprite_frames()->get_animation_names();
_animated_sprite->set_animation(mob_types[random->randi() % mob_types.size()]);
}
Tout d'abord, nous obtenons la liste des noms d'animation à partir de la propriété frames
de l'AnimatedSprite. On obtient ainsi un tableau contenant les trois noms d'animation : ["walk", "swim", "fly"]
.
Nous devons ensuite choisir un nombre aléatoire entre 0
et 2
pour sélectionner l'un de ces noms dans la liste (les indices des listes commencent à 0
). La fonction randi() % n
sélectionne un nombre entier aléatoire entre 0
et n-1
.
Note
Vous devez utiliser randomize()
si vous voulez que votre séquence de nombres "aléatoires" soit différente à chaque fois que vous exécutez la scène. Nous allons utiliser randomize()
dans notre scène Main
, alors nous n'en aurons pas besoin ici.
La dernière étape est de faire en sorte que les monstres se suppriment eux-mêmes lorsqu'ils quittent l'écran. Connecter le signal screen_exited()
du nœud VisibilityNotifier2D
et ajouter ce code :
func _on_VisibilityNotifier2D_screen_exited():
queue_free()
public void OnVisibilityNotifier2DScreenExited()
{
QueueFree();
}
// This code goes in `mob.cpp`.
void Mob::_on_VisibilityNotifier2D_screen_exited() {
queue_free();
}
Cela complète la scène Mob.
Le joueur et les ennemis étant prêts, dans la partie suivante, nous allons les réunir dans une nouvelle scène. Nous ferons en sorte que les ennemis apparaissent de manière aléatoire sur le plateau de jeu et avancent, transformant notre projet en un jeu jouable.