Heads up display¶
The final piece our game needs is a User Interface (UI) to display things like score, a "game over" message, and a restart button.
Create a new scene, and add a CanvasLayer node named
HUD
. "HUD" stands for "heads-up display", an informational display that
appears as an overlay on top of the game view.
Mit dem Node CanvasLayer können wir unsere Oberflächenelemente auf einer Ebene über dem Rest des Spiels zeichnen, so dass die angezeigten Informationen nicht durch irgendwelche Spielelemente wie den Spieler oder Gegner verdeckt werden.
Das HUD sollte die folgenden Informationen anzeigen:
Punktzahl, geändert durch
ScoreTimer
.Eine Nachricht, wie z.B. "Game Over" oder "Get Ready!"
Eine "Start"-Taste, um das Spiel zu starten.
Der Basis-Node für UI-Elemente ist Control. Um unsere Benutzeroberfläche zu erstellen, verwenden wir zwei Arten vom Control Node: Label und Button.
Erstelle das Folgende als Unterobjekte des HUD
-Nodes:
Label genannt
ScoreLabel
.Label genannt
Message
.Button genannt
StartButton
.Timer genannt
MessageTimer
.
Klicken Sie auf das ScoreLabel
und geben eine Zahl in das Text
-Feld im Inspektor ein. Die Standardschriftart für Control
-Nodes ist klein und lässt sich nicht gut skalieren. In den Spielassets ist eine Schriftdatei namens "Xolonium-Regular.ttf" enthalten. Um diese Schriftart zu verwenden, gehen Sie für jeden der drei Control
-Nodes wie folgt vor:
Under Theme overrides > Fonts click on the empty box and select "New DynamicFont"

Click on the "DynamicFont" you added, and under Font > FontData, choose "Load" and select the "Xolonium-Regular.ttf" file.

Set the "Size" property under Settings
, 64
works well.

Once you've done this on the ScoreLabel
, you can click the down arrow next
to the Font property and choose "Copy", then "Paste" it in the same place
on the other two Control nodes.
Bemerkung
Anchors and Margins: Control
nodes have a position and size,
but they also have anchors and margins. Anchors define the origin -
the reference point for the edges of the node. Margins update
automatically when you move or resize a control node. They represent
the distance from the control node's edges to its anchor.
Ordnen Sie die Nodes wie unten gezeigt an. Klicken Sie auf den "Layout"-Knopf, um das Layout eines Control-Nodes festzulegen:

Sie können die Nodes manuell verschieben um sie zu platzieren oder verwenden Sie die folgenden Einstellungen für eine genauere Platzierung:
ScoreLabel (HighScore)¶
Layout : "Oben groß"
Text :
0
Align : "Center"
Nachricht¶
Layout : "HCenter groß"
Text :
Dodge the Creeps!
Align : "Center"
Autowrap : "An"
Das HUD mit Main verbinden¶
Jetzt, da wir die HUD
-Szene erstellt haben, gehen Sie zurück zu Main
und platziere die HUD
-Szene in Main
genauso wie die Player
-Szene. Der gesamte Szenenbaum sollte so aussehen, also stellen Sie sicher, dass nichts fehlt:

Nun müssen wir die HUD
-Funktionalität mit unserem Main
-Skript verbinden. Dies erfordert einige Ergänzungen in der Main
-Szene:
Verbinden Sie auf der Registerkarte "Node" das Signal start_game
des HUD mit der Funktion new_game()
des Main-Nodes, indem Sie "new_game" in die "Empfängermethode" im Fenster "Ein Signal mit einer Methode verbinden" eingeben. Stellen Sie sicher, dass das grüne Verbindungssymbol jetzt neben func new_game()
im Skript angezeigt wird.
Aktualisieren Sie in new_game()
die Punkteanzeige und zeigen Sie die Meldung "Get Ready" an:
$HUD.update_score(score)
$HUD.show_message("Get Ready")
var hud = GetNode<HUD>("HUD");
hud.UpdateScore(Score);
hud.ShowMessage("Get Ready!");
_hud->update_score(score);
_hud->show_get_ready();
In game_over()
müssen wir die entsprechende HUD
Funktion aufrufen:
$HUD.show_game_over()
GetNode<HUD>("HUD").ShowGameOver();
_hud->show_game_over();
Abschließend fügen Sie nachfolgendes in _on_ScoreTimer_timeout()
hinzu, um die Anzeige mit den sich ändernden Punkten zu synchronisieren:
$HUD.update_score(score)
GetNode<HUD>("HUD").UpdateScore(Score);
_hud->update_score(score);
Jetzt können Sie spielen! Klicken Sie auf die Schaltfläche "Projekt abspielen (F5)". Sie werden aufgefordert, eine Hauptszene auszuwählen. Wählen Sie dann Main.tscn
aus.
Alte Gegner entfernen¶
Wenn Sie bis zum "Game Over" spielen und dann ein neues Spiel starten, befinden sich die Gegner des vorherigen Spiel noch auf dem Bildschirm. Es wäre besser wenn diese beim Start eines neuen Spiels verschwinden würden. Wir benötigen einen Weg um alle Gegner zu entfernen und dies geschieht mit der "Gruppen" Funktion.
Wählen Sie in der Szene Mob
den Wurzel-Node und klicken Sie auf die Registerkarte "Node" neben dem Inspektor (die gleiche Stelle, an der Sie die Signale des Nodes finden). Klicken Sie neben "Signale" auf "Gruppen", und Sie können einen neuen Gruppennamen eingeben und auf "Hinzufügen" klicken.

Now all mobs will be in the "mobs" group. We can then add the following line to
the new_game()
function in Main
:
get_tree().call_group("mobs", "queue_free")
// Note that for calling Godot-provided methods with strings,
// we have to use the original Godot snake_case name.
GetTree().CallGroup("mobs", "queue_free");
get_tree()->call_group("mobs", "queue_free");
Die Funktion call_group()
ruft die benannte Funktion auf jedem Node in einer Gruppe auf - in diesem Fall sagen wir jedem Gegner, dass er sich selbst löschen soll.
The game's mostly done at this point. In the next and last part, we'll polish it a bit by adding a background, looping music, and some keyboard shortcuts.