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.
Checking the stable version of the documentation...
Übersicht 2D-Bewegung
Einführung
Jeder Anfänger hat diese Frage: "Wie bewege ich meinen Charakter?" Abhängig vom Stil des Spiels, das Sie erstellen, haben Sie möglicherweise spezielle Anforderungen, aber im Allgemeinen basiert die Bewegung in den meisten 2D-Spielen auf einer kleinen Menge von Designs.
Wir verwenden CharacterBody2D für diese Beispiele, aber die Prinzipien gelten auch für andere Node-Typen (Area2D, RigidBody2D).
Einrichtung
Jedes der folgenden Beispiele verwendet den gleichen Szenenaufbau. Beginnen Sie mit einem CharacterBody2D
mit zwei Child-Nodes: Sprite2D
und CollisionShape2D
. Sie können das Godot-Symbol ("icon.png") für die Textur des Sprite2D verwenden oder jedes andere 2D-Bild, das Sie haben.
Öffnen Sie Projekt -> Projekteinstellungen
und wählen Sie den Tab "Eingabe-Zuordnung". Fügen Sie die folgenden Eingabeaktionen hinzu (siehe InputEvent für Details):

8-Wege-Bewegung
In diesem Szenario soll der Benutzer die vier Richtungstasten (oben/links/unten/rechts oder W/A/S/D) drücken und sich in die ausgewählte Richtung bewegen. Der Name "8-Wege-Bewegung" kommt daher, dass sich der Spieler durch gleichzeitiges Drücken von zwei Tasten diagonal bewegen kann.

Fügen Sie ein Skript in den Charakter-Body ein und fügen Sie den folgenden Code hinzu:
extends CharacterBody2D
@export var speed = 400
func get_input():
var input_direction = Input.get_vector("left", "right", "up", "down")
velocity = input_direction * speed
func _physics_process(delta):
get_input()
move_and_slide()
using Godot;
public partial class Movement : CharacterBody2D
{
[Export]
public int Speed { get; set; } = 400;
public void GetInput()
{
Vector2 inputDirection = Input.GetVector("left", "right", "up", "down");
Velocity = inputDirection * Speed;
}
public override void _PhysicsProcess(double delta)
{
GetInput();
MoveAndSlide();
}
}
In der Funktion get_input()
verwenden wir Input-get_vector()
, um auf die vier Schlüsselereignisse zu prüfen und in der Summe einen Richtungsvektor zurückzugeben.
Wir können dann unsere Geschwindigkeit festlegen, indem wir diesen Richtungsvektor, der eine Länge von 1
hat, mit unserer gewünschten Geschwindigkeit multiplizieren.
Tipp
Wenn Sie noch nie Vektor-Mathematik verwendet haben oder eine Auffrischung benötigen, können Sie eine Erklärung der Vektorverwendung in Godot unter Vektormathematik einsehen.
Bemerkung
Wenn der obige Code nichts bewirkt, wenn Sie die Tasten drücken, überprüfen Sie, ob Sie die Eingabeaktionen korrekt eingerichtet haben, wie im Einrichtung-Teil dieses Tutorials beschrieben.
Rotation + Bewegung
Diese Art der Bewegung wird manchmal als "Asteroids-Stil" bezeichnet, weil sie der Funktionsweise dieses klassischen Arcade-Spiels ähnelt. Durch Drücken von links/rechts wird die Figur gedreht, während sie durch Drücken von oben/unten vorwärts oder rückwärts in die jeweilige Richtung bewegt wird.

extends CharacterBody2D
@export var speed = 400
@export var rotation_speed = 1.5
var rotation_direction = 0
func get_input():
rotation_direction = Input.get_axis("left", "right")
velocity = transform.x * Input.get_axis("down", "up") * speed
func _physics_process(delta):
get_input()
rotation += rotation_direction * rotation_speed * delta
move_and_slide()
using Godot;
public partial class Movement : CharacterBody2D
{
[Export]
public int Speed { get; set; } = 400;
[Export]
public float RotationSpeed { get; set; } = 1.5f;
private float _rotationDirection;
public void GetInput()
{
_rotationDirection = Input.GetAxis("left", "right");
Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
}
public override void _PhysicsProcess(double delta)
{
GetInput();
Rotation += _rotationDirection * RotationSpeed * (float)delta;
MoveAndSlide();
}
}
Hier haben wir zwei Variablen hinzugefügt, um unsere Rotationsrichtung und Geschwindigkeit zu tracken. Die Rotation wird direkt auf die Property rotation
des Body angewendet.
Um die Geschwindigkeit festzulegen, verwenden wir den Vektor transform.x
des Bodys, der in die "Vorwärts"-Richtung des Bodys zeigt, und multiplizieren ihn mit der Geschwindigkeit.
Rotation + Bewegung (Maus)
Dieser Bewegungsstil ist eine Variation des vorherigen Stils. Diesmal wird die Richtung statt über die Tastatur über die Mausposition vorgegeben. Der Charakter "schaut" immer auf den Mauszeiger. Die Vorwärts-/Rückwärts-Eingaben bleiben jedoch gleich.

extends CharacterBody2D
@export var speed = 400
func get_input():
look_at(get_global_mouse_position())
velocity = transform.x * Input.get_axis("down", "up") * speed
func _physics_process(delta):
get_input()
move_and_slide()
using Godot;
public partial class Movement : CharacterBody2D
{
[Export]
public int Speed { get; set; } = 400;
public void GetInput()
{
LookAt(GetGlobalMousePosition());
Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
}
public override void _PhysicsProcess(double delta)
{
GetInput();
MoveAndSlide();
}
}
Hier benutzen wir die Node2D-look_at()
Methode, um den Spieler auf die Position der Maus auszurichten. Ohne diese Funktion könnte man den gleichen Effekt erzielen, indem man den Winkel wie folgt einstellt:
rotation = get_global_mouse_position().angle_to_point(position)
var rotation = GetGlobalMousePosition().AngleToPoint(Position);
Klicken und Bewegen
Dieses letzte Beispiel verwendet nur die Maus, um den Charakter zu steuern. Wenn Sie auf den Bildschirm klicken, bewegt sich der Spieler zum Zielort.

extends CharacterBody2D
@export var speed = 400
var target = position
func _input(event):
# Use is_action_pressed to only accept single taps as input instead of mouse drags.
if event.is_action_pressed(&"click"):
target = get_global_mouse_position()
func _physics_process(delta):
velocity = position.direction_to(target) * speed
# look_at(target)
if position.distance_to(target) > 10:
move_and_slide()
using Godot;
public partial class Movement : CharacterBody2D
{
[Export]
public int Speed { get; set; } = 400;
private Vector2 _target;
public override void _Input(InputEvent @event)
{
// Use IsActionPressed to only accept single taps as input instead of mouse drags.
if (@event.IsActionPressed("click"))
{
_target = GetGlobalMousePosition();
}
}
public override void _PhysicsProcess(double delta)
{
Velocity = Position.DirectionTo(_target) * Speed;
// LookAt(_target);
if (Position.DistanceTo(_target) > 10)
{
MoveAndSlide();
}
}
}
Beachten Sie den distance_to()
-Check, den wir vor der Bewegung durchführen. Ohne diesen Check würde der Body beim Erreichen der Zielposition "jittern", da er sich leicht an der Position vorbei bewegt und versucht, sich zurück zu bewegen, nur um sich dabei ebenfalls zu weit zu bewegen und sich wieder nach vorn zu bewegen und so weiter.
Wenn Sie die Zeile look_at()
auskommentieren, wird der Body auch so gedreht, dass er in seine Bewegungsrichtung zeigt, wenn Sie möchten.
Tipp
Diese Technik kann auch als Grundlage für ein "Verfolger"-Charakter verwendet werden. Die target
-Position kann die eines beliebigen Objekts sein, zu dem Sie sich bewegen möchten.
Zusammenfassung
Diese Codebeispiele können als Ausgangspunkt für Ihre eigenen Projekte hilfreich sein. Nutzen Sie sie gern, um mit ihnen zu experimentieren und um zu sehen, was Sie damit erschaffen können.
Sie können dieses Beispielprojekt hier herunterladen: 2d_movement_starter.zip