Erstellen eines ersten Skripts

In this lesson, you will code your first script to make the Godot icon turn in circles. As we mentioned in the introduction, we assume you have programming foundations.

This tutorial is written for GDScript, and the equivalent C# code is included in another tab of each codeblock for convenience.

../../_images/scripting_first_script_rotating_godot.gif

Siehe auch

To learn more about GDScript, its keywords, and its syntax, head to the GDScript section. To learn more about C#, head to the C#/.NET section.

Projektkonfiguration

Bitte legen Sie ein neues Projekt an, um mit einem neuen Projekt zu beginnen. Ihr Projekt sollte bereits ein Bild enthalten: das Godot-Icon, das wir in der Community häufig für Prototypen verwenden.

../../_images/scripting_first_script_icon.svg

We need to create a Sprite2D node to display it in the game. In the Scene dock, click the Other Node button.

../../_images/scripting_first_script_click_other_node.webp

Geben Sie "Sprite2D" in die Suchleiste ein, um Nodes zu filtern, und doppelklicken Sie auf Sprite2D, um den Node zu erstellen.

../../_images/scripting_first_script_add_sprite_node.webp

Das Szene-Tab sollte jetzt nur einen Sprite2D-Node enthalten.

../../_images/scripting_first_script_scene_tree.webp

A Sprite2D node needs a texture to display. In the Inspector on the right, you can see that the Texture property says <empty>. To display the Godot icon, click and drag the file icon.svg from the FileSystem dock onto the Texture slot.

../../_images/scripting_first_script_setting_texture.webp

Bemerkung

Sie können Sprite2D-Nodes automatisch erzeugen, indem Sie Bilder per Drag&Drop auf den Viewport ziehen.

Klicken und ziehen Sie dann das Icon in den Viewport, um es in der Spielansicht zu zentrieren.

../../_images/scripting_first_script_centering_sprite.webp

Ein neues Skript erstellen

To create and attach a new script to our node, right-click on Sprite2D in the Scene dock and select Attach Script.

../../_images/scripting_first_script_attach_script.webp

The Attach Node Script window appears. It allows you to select the script's language and file path, among other options.

Change the Template field from Node: Default to Object: Empty to start with a clean file. Leave the other options set to their default values and click the Create button to create the script.

../../_images/scripting_first_script_attach_node_script.webp

Bemerkung

Die Namen von C#-Skripten müssen mit den Namen ihrer Klassen übereinstimmen. In diesem Fall sollten Sie die Datei MySprite2D.cs nennen.

Der Skript-Arbeitsbereich sollte mit der neuen Datei sprite_2d.gd und der folgenden Code-Zeile geöffnet sein:

extends Sprite2D

Jede GDScript-Datei ist implizit eine Klasse. Das Schlüsselwort extends definiert die Klasse, die das Skript erbt oder erweitert. In diesem Fall ist es Sprite2D, was bedeutet, dass unser Skript Zugriff auf alle Eigenschaften und Funktionen des Sprite2D-Nodes erhält, einschließlich der Klassen, die es erweitert, wie Node2D, CanvasItem und Node.

Bemerkung

Wenn Sie in GDScript die Zeile mit dem Schlüsselwort extends weglassen, erweitert Ihre Klasse implizit RefCounted, das Godot zur Verwaltung des Speichers Ihrer Anwendung verwendet.

Zu den vererbten Eigenschaften gehören diejenigen, die Sie im Inspektor-Dock sehen können, wie z.B. Textur in unserem Node.

Bemerkung

Der Inspektor zeigt die Eigenschaften eines Nodes standardmäßig auf deutsch übersetzt an. Im GDScript-Code werden diese Eigenschaften auf englisch verwendet, und zwar in "snake_case", also kleingeschrieben mit Underscores. Klicken Sie im Inspektor auf das Icon mit dem Schraubenschlüssel, um die Angaben zwischen deutsch, englisch und dem internen Namen umzuschalten.

Sie können mit dem Mauszeiger über den Namen einer beliebigen Eigenschaft im Inspektor fahren, um eine Beschreibung und ihren Bezeichner im Code anzuzeigen.

Hello, world!

Unser Skript tut derzeit nichts. Lassen wir es den Text "Hallo, Welt!" in den Ausgabe-Bereich des Unteren Bedienfelds drucken, um loszulegen.

Fügen Sie den folgenden Code in Ihr Skript ein:

func _init():
    print("Hello, world!")

Schauen wir uns das mal an. Das Schlüsselwort func definiert eine neue Funktion namens _init. Dies ist ein spezieller Name für den Konstruktor unserer Klasse. Die Engine ruft _init() für jedes Objekt oder jeden Node auf, sobald es im Speicher erstellt wird, falls Sie diese Funktion definieren.

Bemerkung

GDScript ist eine einrückungsbasierte Sprache. Der Tabstopp am Anfang der Zeile mit der Aufschrift print() ist notwendig, damit der Code funktioniert. Wenn Sie es weglassen oder eine Zeile nicht richtig einrücken, hebt der Editor dies rot hervor und zeigt die folgende Fehlermeldung an: "Expected indented block" (deutsch: „eingerückter Block erwartet“).

Speichern Sie die Szene unter dem Namen sprite_2d.tscn, falls Sie das noch nicht getan haben, und drücken Sie dann F6 (Cmd + R unter macOS), um sie zu starten. Schauen Sie sich den Bereich Ausgabe im Unteren Bedienfeld an, das sich aufklappt. Es sollte "Hello, world!" anzeigen.

../../_images/scripting_first_script_print_hello_world.webp

Löschen Sie die Funktion _init(), so dass nur noch die Zeile extends Sprite2D übrig bleibt.

Im Kreis drehen

Jetzt ist es an der Zeit, unseren Node zu bewegen und zu rotieren. Dazu fügen wir zwei Variablen in unser Skript ein: die Bewegungsgeschwindigkeit in Pixeln pro Sekunde und die Winkelgeschwindigkeit in Radiant pro Sekunde. Fügen Sie das Folgende nach der Zeile extends Sprite2D ein.

var speed = 400
var angular_speed = PI

Member-Variablen befinden sich am Anfang des Skripts, nach allen "extends"-Zeilen, aber vor Funktionen. Jede Node-Instanz, an die dieses Skript angehängt ist, hat eine eigene Kopie der Eigenschaften speed und angular_speed.

Bemerkung

Winkel in Godot funktionieren standardmäßig im Bogenmaß, aber Sie haben Built-in-Funktionen und -Eigenschaften zur Verfügung, wenn Sie es vorziehen, Winkel stattdessen in Grad zu berechnen.

Um unser Icon zu bewegen, müssen wir seine Position und Drehung in jedem Frame der Spielschleife aktualisieren. Wir können die virtuelle Funktion _process() der Klasse Node verwenden. Wenn Sie diese Funktion in einer Klasse definieren, die von der Node-Klasse erbt, wie z.B. Sprite2D, wird Godot die Funktion bei jedem Frame aufrufen und ihr ein Argument namens delta übergeben; die Zeit, die seit dem letzten Frame verstrichen ist.

Bemerkung

Bei Spielen werden viele Bilder pro Sekunde gerendert, die als Frames bezeichnet werden, und zwar in einer Schleife. Wir messen die Rate, mit der ein Spiel Bilder produziert, in Frames pro Sekunde (FPS). Die meisten Spiele streben 60 FPS an, obwohl man bei langsameren Mobilgeräten auch Werte wie 30 FPS oder bei Virtual-Reality-Spielen 90 bis 240 FPS finden kann.

Die Engine- und Spieleentwickler tun ihr Bestes, um in einem konstanten Zeitintervall die Spielwelt zu aktualisieren und die Bilder zu rendern, aber es gibt immer kleine Abweichungen bei den Renderzeiten der Frames. Deshalb liefert uns die Engine diesen Delta-Zeitwert, der unsere Bewegung unabhängig von unserer Framerate macht.

Definieren Sie am Ende des Skripts die Funktion:

func _process(delta):
    rotation += angular_speed * delta

Das Schlüsselwort func definiert eine neue Funktion. Danach müssen wir den Namen der Funktion und die Argumente, die sie benötigt, in Klammern setzen. Ein Doppelpunkt beendet die Definition, und die folgenden eingerückten Blöcke sind der Inhalt oder die Anweisungen der Funktion.

Bemerkung

Beachten Sie, dass _process(), wie _init(), mit einem führenden Unterstrich beginnt. Godots virtuelle Funktionen, d.h. Built-in-Funktionen, die Sie überschreiben können, um mit der Engine zu kommunizieren, beginnen mit einem Unterstrich.

Die Zeile innerhalb der Funktion, rotation += angular_speed * delta, erhöht die Rotation des Sprites in jedem Frame. Hier ist rotation eine Eigenschaft, die von der Klasse Node2D geerbt wurde, die Sprite2D erweitert. Sie kontrolliert die Rotation unseres Node und arbeitet im Bogenmaß.

Tipp

In the code editor, you can Ctrl + Click (Cmd + Click on macOS) on any built-in property or function like position, rotation, or _process to open the corresponding documentation in a new tab.

Führen Sie die Szene aus, um zu sehen, wie sich das Godot-Icon an Ort und Stelle dreht.

../../_images/scripting_first_script_godot_turning_in_place.gif

Bemerkung

In C# ist das Argument delta, das von _Process() verwendet wird, ein double. Wir müssen es daher in float umwandeln, wenn wir es auf die Rotation anwenden.

Gehen wir voran

Lassen Sie uns nun den Node bewegen. Fügen Sie die folgenden zwei Zeilen innerhalb der Funktion _process() ein und achten Sie darauf, dass die neuen Zeilen genauso eingerückt sind wie die Zeile rotation += angular_speed * delta davor.

var velocity = Vector2.UP.rotated(rotation) * speed

position += velocity * delta

Wie wir bereits gesehen haben, definiert das Schlüsselwort var eine neue Variable. Wenn Sie es an den Anfang des Skripts setzen, definiert es eine Eigenschaft der Klasse. Innerhalb einer Funktion definiert es eine lokale Variable: Sie existiert nur innerhalb des Funktionsbereichs.

Wir definieren eine lokale Variable namens velocity, ein 2D-Vektor, der sowohl eine Richtung als auch eine Geschwindigkeit repräsentiert. Um den Node vorwärts zu bewegen, gehen wir von der Konstante Vector2.UP der Klasse Vector2 aus, einem Vektor, der nach oben zeigt, und rotieren ihn, indem wir die Vector2-Methode rotated() aufrufen. Dieser Ausdruck, Vector2.UP.rotated(rotation), ist ein Vektor, der relativ zu unserem Icon nach vorne zeigt. Multipliziert mit unserer Eigenschaft speed ergibt sich eine Geschwindigkeit, mit der wir den Node vorwärts bewegen können.

Wir fügen velocity * delta zu der position des Nodes hinzu, um ihn zu verschieben. Die Position selbst ist vom Typ Vector2, einem Built-in-Typ in Godot, der einen 2D-Vektor darstellt.

Führen Sie die Szene aus, um den Godot-Kopf im Kreis laufen zu sehen.

../../_images/scripting_first_script_rotating_godot.gif

Bemerkung

Beim Verschieben eines solchen Nodes werden Kollisionen mit Wänden oder dem Boden nicht berücksichtigt. In Ihr erstes 2D-Spiel lernen Sie einen anderen Ansatz, um Objekte zu bewegen und dabei Kollisionen zu erkennen.

Unser Node bewegt sich derzeit von selbst. Im nächsten Teil, Auf Spielereingaben hören, werden wir ihn mit Spielereingaben steuern.

Vollständiges Skript

Hier ist die vollständige Datei sprite_2d.gd als Referenz.

extends Sprite2D

var speed = 400
var angular_speed = PI


func _process(delta):
    rotation += angular_speed * delta

    var velocity = Vector2.UP.rotated(rotation) * speed

    position += velocity * delta