Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
2D 運動概述¶
前言¶
每個初學者都曾遇過同樣的情況:「我要怎麼控制我的角色?」根據你想做的遊戲風格,你可能會有特殊的需求。但普遍來說,大部分2D遊戲的操控是以少數幾種設計為基礎的。
這裡我們用 KinematicBody2D 當做例子,不過其他型別的節點(Area2D, RigidBody2D) 也適用相同原則。
設定¶
以下每個範例都使用相同的場景佈置。從帶有 Sprite2D
和 CollisionShape2D
這兩個子節點的 CharacterBody2D
開始。你可以將 Godot 圖示(“icon.png”)用於 Sprite2D 的紋理,也可以使用你擁有的任何其他 2D 圖像。
打開``專案 -> 專案設定``並選擇“輸入對應”分頁。新增以下輸入操作(相關詳細資訊請參閱 InputEvent):
八向移動¶
在這種情況下, 您希望使用者按下四個方向鍵(上/左/下/右或W / A / S / D)並沿所選方向移動. "8向移動" 意味著遊戲角色可以通過同時按下兩個鍵實作斜向移動.
點擊 [場景] -> [新增場景],然後新增下列節點:
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();
}
}
在函式 get_input()
中,我們使用 Input 的 get_vector()
來檢查四個按鍵事件,並返回一個方向向量的累加值。
然後,我們可以將長度為 1
的方向向量乘以所需的速度來設定速度。
小訣竅
如果你之前從未接觸過向量數學, 或者需要複習, 你可以在 向量數學 看到Godot中向量用法的解釋.
備註
如果在你按下鍵時上面的程式碼不起任何作用, 請仔細檢查你是否按照本教學的 設定 部分所描述的正確設定了輸入操作.
旋轉+移動¶
這種型別的運動有時被稱為 "Asteroids式運動", 因為它類似於經典街機遊戲Asteroids的工作方式. 按左/右旋轉角色, 而按上/下使得角色在面向的方向上向前或向後.
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();
}
}
我們新增了兩個新變數來追蹤旋轉方向和速度. 同樣, 一次按下兩個鍵將相互抵消並導致沒有旋轉. 旋轉直接應用於物體的 rotation
屬性上.
要設定速度,我們使用物體的 transform.x
,這是一個指向物體 “前進” 方向的向量,然後乘以速度。
旋轉+移動(滑鼠)¶
這種運動方式是前一種運動方式的變體。這次,方向由滑鼠位置而不是鍵盤設定。角色將始終“看向”滑鼠指標。前進/後退輸入保持不變。
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();
}
}
這裡我們用到 Node2D 中的 look_at()
方法, 使遊戲角色朝向給定的位置. 如果沒有此函式, 為獲得相同的效果, 可能需要像下面這樣設定角度:
rotation = get_global_mouse_position().angle_to_point(position)
var rotation = GetGlobalMousePosition().AngleToPoint(Position);
點擊並移動¶
最後一個範例僅使用滑鼠來控制角色. 按一下螢幕將使遊戲角色移動到目標位置.
extends CharacterBody2D
@export var speed = 400
var target = position
func _input(event):
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)
{
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();
}
}
}
注意我們在移動之前做的 distance_to()
檢查. 如果沒有這個檢查, 物體在到達目標位置時會 "抖動", 因為它稍微移過該位置時就會試圖向後移動, 只是每次移動步長都會有點遠從而導致來回重複移動.
如果你喜歡, 取消注釋的 rotation
程式碼可以使物體轉向其運動方向.
小訣竅
該技術也可以用到“跟隨”的遊戲角色中。target
目標位置可以是任何你想移動到的物件的位置。
總結¶
你可能覺得這些程式碼範例可以作為你自己的專案的一個有用的出發點. 請隨意使用它們並試驗它們, 看看你能做些什麼.
您可以在此處下載這個範例專案:2d_movement_starter.zip