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...
監聽玩家的輸入
延續先前的課程,建立腳本,讓我們看看任何遊戲的另一個重要功能:將控制權交給玩家。要加入這個功能,我們需要修改我們的 sprite_2d.gd 程式碼。
在 Godot 中,你有兩個主要工具來處理玩家的輸入:
內建的輸入回呼函式,主要是
_unhandled_input()。像_process(),它是一個內建的虛函式,Godot 每次在玩家按下一個鍵時都會呼叫。它是你想用來對那些不是每一影格都發生的事件做出反應的工具,比如按 Space 來跳躍。要瞭解更多關於輸入回呼函式的資訊,請參閱 使用 InputEvent 。Input單例。單例是一個全域可存取的物件。Godot 在腳本中提供對幾個物件的存取。它是每一影格檢查輸入的有效工具。
我們這裡將使用 Input 單例,因為我們需要知道在每一影格中玩家是否想轉身或者移動。
對於轉彎,我們應該使用一個新的變數: direction 。在我們的 _process() 函式中,將 rotation += angular_speed * delta 替換成以下程式碼。
var direction = 0
if Input.is_action_pressed("ui_left"):
direction = -1
if Input.is_action_pressed("ui_right"):
direction = 1
rotation += angular_speed * direction * delta
var direction = 0;
if (Input.IsActionPressed("ui_left"))
{
direction = -1;
}
if (Input.IsActionPressed("ui_right"))
{
direction = 1;
}
Rotation += _angularSpeed * direction * (float)delta;
我們的 direction 區域變數是一個乘數,代表玩家想要轉向的方向。 0 的值表示玩家沒有按左或右方向鍵。 1 表示玩家想向右轉,而 -1 表示他們想向左轉。
為了產生這些數值,我們將引入條件判斷與 Input 的使用。GDScript 中的條件敘述以關鍵字 if 開頭,並以冒號結尾;條件則是該行關鍵字與冒號之間的運算式。
為了檢查目前影格玩家是否按下了某個鍵,我們需要呼叫 Input.is_action_pressed() 。這個方法使用一個字串來表示一個輸入動作。當該按鍵被按下時,函式返回 true ,否則這個函式將返回 false 。
上面我們使用的兩個動作,“ui_left”和“ui_right”,是每個 Godot 專案中預定義的。它們分別在玩家按鍵盤上的左右箭頭或遊戲手柄上的左右鍵時觸發。
備註
你可以前往 ,並點選 Input Map 分頁來檢視與編輯專案的輸入動作。
最後,當我們更新節點的 rotation 時,我們使用 direction 作為乘數: rotation += angular_speed * direction * delta 。
將 var velocity = Vector2.UP.rotated(rotation) * speed 和 position += velocity * delta 這幾行程式碼註解掉,像這樣:
#var velocity = Vector2.UP.rotated(rotation) * speed
#position += velocity * delta
//var velocity = Vector2.Up.Rotated(Rotation) * _speed;
//Position += velocity * (float)delta;
這會忽略前一個練習中,在沒有使用者輸入的情況下,讓圖示以圓形路徑移動位置的程式碼。
如果你用這段程式碼運作場景,當你按下 左方向鍵 和 右方向鍵 時,圖示應該會旋轉。
按“上”時移動
若要僅在按下按鍵時移動,我們需要修改計算速度的程式碼。取消註解該段程式碼,並將以 var velocity 開頭的那一行替換為以下程式碼。
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
velocity = Vector2.UP.rotated(rotation) * speed
var velocity = Vector2.Zero;
if (Input.IsActionPressed("ui_up"))
{
velocity = Vector2.Up.Rotated(Rotation) * _speed;
}
我們將 velocity 的值初始化為 Vector2.ZERO ,這是內建 Vector 型別的一個常數,代表長度為 0 的二維向量。
如果玩家按下“ui_up”動作,我們就會更新速度的值,使精靈向前移動。
GDScript 範例
這是完整的 sprite_2d.gd 檔案,僅供參考。
extends Sprite2D
var speed = 400
var angular_speed = PI
func _process(delta):
var direction = 0
if Input.is_action_pressed("ui_left"):
direction = -1
if Input.is_action_pressed("ui_right"):
direction = 1
rotation += angular_speed * direction * delta
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
velocity = Vector2.UP.rotated(rotation) * speed
position += velocity * delta
using Godot;
public partial class MySprite2D : Sprite2D
{
private float _speed = 400;
private float _angularSpeed = Mathf.Pi;
public override void _Process(double delta)
{
var direction = 0;
if (Input.IsActionPressed("ui_left"))
{
direction = -1;
}
if (Input.IsActionPressed("ui_right"))
{
direction = 1;
}
Rotation += _angularSpeed * direction * (float)delta;
var velocity = Vector2.Zero;
if (Input.IsActionPressed("ui_up"))
{
velocity = Vector2.Up.Rotated(Rotation) * _speed;
}
Position += velocity * (float)delta;
}
}
如果你運作這個場景,你現在應該能夠用左右方向鍵進行旋轉,並通過按 Up 向前移動。
總結
總之,Godot 中的每個腳本都代表一個類別,並繼承引擎內建的其中一個類別。您的類別繼承的節點類型讓您可以存取屬性,例如我們精靈範例中的 rotation 和 position 。您也會繼承許多函式,但在這個範例中我們沒有用到。
在 GDScript 中,放在檔頂部的變數是類的屬性,也稱為成員變數。除了變數之外,您還可以定義函式,在大多數情況下,這些函式將是類的方法。
Godot 提供了幾個虛函式,您可以定義這些函式來將類與引擎連接起來。其中包括 _process() ,用於每影格將更改應用於節點,以及 _unhandled_input() ,用於接收使用者的輸入事件,如按鍵和按鈕。還有很多。
Input 單例允許你在程式碼的任何地方回應玩家輸入。特別是,你會在 _process() 迴圈中使用它。
在下一個單元,繫結訊號,我們將透過讓節點觸發腳本中的程式碼,來進一步探討腳本和節點之間的關聯。