Creating the enemy¶
Jetzt ist es an der Zeit die Feinde zu erstellen, denen der Spieler ausweichen muss. Ihr Verhalten wird nicht allzu komplex sein: Gegner werden zufällig an den Rändern des Bildschirms erscheinen und sich in einer zufälligen Richtung in einer geraden Linie fortbewegen, um danach geradeaus weiterzugehen.
Wir werden dies in eine Mob
-Szene einbauen, die wir dann instanziieren um beliebig viele unabhängige Gegner im Spiel erstellen zu können.
Node einrichten¶
Klicken Sie auf Szene -> Neue Szene und fügen Sie die folgenden Nodes hinzu:
RigidBody2D (genannt
Mob
)
Vergessen Sie nicht, die Unterobjekte so einzustellen, dass sie nicht ausgewählt werden können, wie Sie es bei der Player-Szene getan haben.
In the RigidBody2D properties, set Gravity Scale
to 0
, so the mob will not fall downward. In addition, under the
CollisionObject2D section, click the Mask
property and uncheck the first
box. This will ensure the mobs do not collide with each other.

Richten Sie das AnimatedSprite so ein, wie wir es für den Spieler getan haben. Dieses Mal haben wir drei Animationen: fly
, swim
, und walk
. Zu jeder Animation gibt es zwei Bilder im "art" Ordner.
Setzen Sie die "Geschwindigkeit (FPS)" für alle Animationen auf 3
.

Set the Playing
property in the Inspector to "On".
Wir werden eine der Animationen zufällig auswählen, sodass die Gegner eine gewisse Vielfalt haben.
Like the player images, these mob images need to be scaled down. Set the
AnimatedSprite
's Scale
property to (0.75, 0.75)
.
Wie in der Szene Player
, fügen Sie eine CapsuleShape2D
für die Kollision hinzu. Um die Form mit dem Bild auszurichten, müssen Sie die Eigenschaft Rotation Degrees
auf 90
(unter Node2D
-Transform im Inspektor) einstellen.
Speichern Sie die Szene.
Feind-Skript¶
Add a script to the Mob
like this:
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
Now let's look at the rest of the script. In _ready()
we play the animation
and randomly choose one of the three animation types:
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()]);
}
First, we get the list of animation names from the AnimatedSprite's frames
property. This returns an Array containing all three animation names: ["walk",
"swim", "fly"]
.
Wir werden eine zufällige Zahl zwischen 0
und 2
auswählen müssen, um einen von diesen Namen aus der Liste auswählen zu können (Arrays starten bei 0
). randi() % n
wählt eine zufällige Ganzzahl zwischen 0
und n-1
aus.
Bemerkung
Sie müssen randomize()
verwenden, wenn Sie möchten, dass Ihre Reihenfolge der "Zufallszahlen" bei jedem erneuten Ausführen der Szene unterschiedlich ist. Wir werden randomize()
in unserer Main
Szene verwenden, so dass wir es hier nicht brauchen. randi() % n
ist der Standardweg, um eine zufällige ganze Zahl zwischen 0
und n-1
zu erhalten.
Der letzte Schritt ist es, die Gagner (Mobs) dazu zu bringen, sich selbst zu löschen, wenn sie den Bildschirm verlassen. Verbinden Sie das Signal screen_exited()
vom Node VisibilityNotifier2D
und füge diesen Code hinzu:
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();
}
Damit ist die Szene des Gegners fertig.
With the player and enemies ready, in the next part, we'll bring them together in a new scene. We'll make enemies spawn randomly around the game board and move forward, turning our project into a playable game.