Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

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

Your Scene tab should now only have a Sprite2D node.

../../_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.

The Script workspace should appear with your new sprite_2d.gd file open and the following line of code:

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.

Inherited properties include the ones you can see in the Inspector dock, like our node's texture.

Bemerkung

By default, the Inspector displays a node's properties in "Title Case", with capitalized words separated by a space. In GDScript code, these properties are in "snake_case", which is lowercase with each word separated by an underscore.

You can hover over any property's name in the Inspector to see a description and its identifier in code.

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“).

Save the scene as sprite_2d.tscn if you haven't already, then press F6 (Cmd + R on macOS) to run it. Look at the Output bottom panel that expands. It should display "Hello, world!".

../../_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

It's time to make our node move and rotate. To do so, we're going to add two member variables to our script: the movement speed in pixels per second and the angular speed in radians per second. Add the following after the extends Sprite2D line.

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