Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

監聽玩家的輸入

Building upon the previous lesson, 建立腳本, let's look at another important feature of any game: giving control to the player. To add this, we need to modify our sprite_2d.gd code.

../../_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 專案中預定義的。它們分別在玩家按鍵盤上的左右箭頭或遊戲手柄上的左右鍵時觸發。

備註

打開“專案 -> 專案設定”並點擊“輸入對應”分頁,就可以查看並編輯專案中的輸入動作。

最後,當我們更新節點的 rotation 時,我們使用 direction 作為乘數: rotation += angular_speed * direction * 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

總結

In summary, every script in Godot represents a class and extends one of the engine's built-in classes. The node types your classes inherit from give you access to properties, such as rotation and position in our sprite's case. You also inherit many functions, which we didn't get to use in this example.

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

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

Input 單例允許您在程式碼中的任何位置對玩家的輸入做出反應。 尤其是,你在 _process() 迴圈中使用它。

In the next lesson, 繫結訊號, we'll build upon the relationship between scripts and nodes by having our nodes trigger code in scripts.