Den Feind erschaffen¶
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.
Stellen Sie in den RigidBody2D Eigenschaften Gravity Scale
auf 0
, damit der Gegner nicht nach unten fällt. Klicken Sie außerdem unter dem Abschnitt CollisionObject2D auf die Eigenschaft Mask
und deaktivieren das erste Kontrollkästchen. Dadurch wird sichergestellt, dass die Gegner nicht miteinander kollidieren.
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
.
Stelle die Eigenschaft Playing
im Inspektor auf "On".
Wir werden eine der Animationen zufällig auswählen, sodass die Gegner eine gewisse Vielfalt haben.
Wie die Spieler-Bilder müssen auch diese Gegner-Bilder verkleinert werden. Setze die Scale
Eigenschaft von AnimatedSprite
auf (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¶
Fügen Sie ein Skript zur Mob
wie folgt hinzu:
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
Lassen Sie uns nun den Rest des Skripts betrachten. In _ready()
wählen wir zufällig einen der drei Animationstypen:
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()]);
}
Zunächst werden wir die Liste der Animationsnamen von der Eigenschaft frames
im AnimatedSprite erhalten. Diese gibt ein Array zuruück, dass alle drei Animationsnamen enthält: ["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 Gegner (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.
Da nun die Spieler und die Gegner fertig sind, werden wir sie im nächsten Teil in einer neuen Szene zusammenführen. Wir werden die Gegner zufällig rund um das Spielfeld erscheinen lassen und sie vorwärts bewegen, was unser Projekt zu einem spielbaren Spiel macht.