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.

監聽玩家的輸入

延續先前的課程,建立腳本,讓我們看看任何遊戲的另一個重要功能:將控制權交給玩家。要加入這個功能,我們需要修改我們的 sprite_2d.gd 程式碼。

../../_images/scripting_first_script_moving_with_input.gif

在 Godot 中,你有兩個主要工具來處理玩家的輸入:

  1. 內建的輸入回呼函式,主要是 _unhandled_input() 。像 _process() ,它是一個內建的虛函式,Godot 每次在玩家按下一個鍵時都會呼叫。它是你想用來對那些不是每一影格都發生的事件做出反應的工具,比如按 Space 來跳躍。要瞭解更多關於輸入回呼函式的資訊,請參閱 使用 InputEvent

  2. 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

我們的 direction 區域變數是一個乘數,代表玩家想要轉向的方向。 0 的值表示玩家沒有按左或右方向鍵。 1 表示玩家想向右轉,而 -1 表示他們想向左轉。

為了產生這些數值,我們將引入條件判斷與 Input 的使用。GDScript 中的條件敘述以關鍵字 if 開頭,並以冒號結尾;條件則是該行關鍵字與冒號之間的運算式。

為了檢查目前影格玩家是否按下了某個鍵,我們需要呼叫 Input.is_action_pressed() 。這個方法使用一個字串來表示一個輸入動作。當該按鍵被按下時,函式返回 true ,否則這個函式將返回 false

上面我們使用的兩個動作,“ui_left”和“ui_right”,是每個 Godot 專案中預定義的。它們分別在玩家按鍵盤上的左右箭頭或遊戲手柄上的左右鍵時觸發。

備註

你可以前往 Project > Project Settings,並點選 Input Map 分頁來檢視與編輯專案的輸入動作。

最後,當我們更新節點的 rotation 時,我們使用 direction 作為乘數: rotation += angular_speed * direction * delta

var velocity = Vector2.UP.rotated(rotation) * speedposition += velocity * delta 這幾行程式碼註解掉,像這樣:

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

#position += velocity * delta

這會忽略前一個練習中,在沒有使用者輸入的情況下,讓圖示以圓形路徑移動位置的程式碼。

如果你用這段程式碼運作場景,當你按下 左方向鍵右方向鍵 時,圖示應該會旋轉。

按“上”時移動

若要僅在按下按鍵時移動,我們需要修改計算速度的程式碼。取消註解該段程式碼,並將以 var velocity 開頭的那一行替換為以下程式碼。

var velocity = Vector2.ZERO
if Input.is_action_pressed("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

如果你運作這個場景,你現在應該能夠用左右方向鍵進行旋轉,並通過按 Up 向前移動。

../../_images/scripting_first_script_moving_with_input.gif

總結

總之,Godot 中的每個腳本都代表一個類別,並繼承引擎內建的其中一個類別。您的類別繼承的節點類型讓您可以存取屬性,例如我們精靈範例中的 rotationposition 。您也會繼承許多函式,但在這個範例中我們沒有用到。

在 GDScript 中,放在檔頂部的變數是類的屬性,也稱為成員變數。除了變數之外,您還可以定義函式,在大多數情況下,這些函式將是類的方法。

Godot 提供了幾個虛函式,您可以定義這些函式來將類與引擎連接起來。其中包括 _process() ,用於每影格將更改應用於節點,以及 _unhandled_input() ,用於接收使用者的輸入事件,如按鍵和按鈕。還有很多。

Input 單例允許你在程式碼的任何地方回應玩家輸入。特別是,你會在 _process() 迴圈中使用它。

在下一個單元,繫結訊號,我們將透過讓節點觸發腳本中的程式碼,來進一步探討腳本和節點之間的關聯。