Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
建立腳本¶
在本課中,你將用 GDScript 編寫第一個腳本,使 Godot 圖示轉圈。正如我們 在介紹中 提到的,我們假設你有程式設計基礎。方便起見,我們在單獨的分頁中包含了等價的 C# 程式碼。
也參考
要瞭解更多關於GDScript、其關鍵字和語法的資訊,請前往 GDScript 參考 。
也參考
更多資訊請參考 C# API 與 GDScript 的不同 一頁。
設定專案¶
請從頭開始 建立一個新專案 。您的專案應該包含一張圖片:Godot 圖示,我們經常在社區中使用它來製作原型。
我們需要建立一個 Sprite2D 節點來在遊戲中顯示它。在“場景”停靠面板中,點擊“其他節點”按鈕。
在搜索欄中輸入“Sprite2D”來篩選節點,按兩下 Sprite2D 來建立節點。
你的“場景”分頁現在應該只有一個 Sprite2D 節點。
Sprite2D 節點需要用於顯示的紋理。在右邊的“屬性面板”中,你可以看到 Texture(紋理)屬性寫著“[空]”。要顯示 Godot 圖示,請點擊瓶拖拽“檔案系統”面板中的 icon.svg
檔案到 Texture 插槽上。
備註
您可以通過將圖像拖放到視口上來自動建立 Sprite2D 節點。
然後,點擊並拖動視口中的圖示,使其在遊戲視圖中居中。
建立腳本¶
在場景面板的 Sprite2D 上點擊右鍵並選擇“新增腳本”,來建立或附加一個新的腳本到我們的節點上。
接著會彈出腳本建立視窗。在這個視窗裡可以設定腳本所使用的語言、類別名稱以及其他相關設定。
Change the Template field from "Node: Default" to "Object: Empty" to start with a clean file. Leave the other options set to their default values and click the Create button to create the script.
此時 Script 工作區將自動打開並顯示你新建的 sprite_2d.gd
檔,顯示以下程式碼行:
extends Sprite2D
using Godot;
public partial class MySprite2D : Sprite2D
{
}
每個 GDScript 檔都是一個隱含的類。 extends
關鍵字定義了這個腳本所繼承或擴充的類。本例中它是 Sprite2D
,意味著我們的腳本將獲得 Sprite2D 節點的所有屬性和函式,包括它繼承的 Node2D
、 CanvasItem
、 Node
等類。
備註
在GDScript中,如果你沒有寫帶有 extends
關鍵字的一行,你的類將隱式地擴充自 RefCounted,Godot使用這個類來管理你的應用程式的記憶體。
繼承的屬性包括您可以在“屬性面板”面板中看到的屬性,例如節點的 texture
。
備註
“屬性面板”預設使用“Title Case”形式展示節點的屬性,將單詞的首字母大寫、用空格分隔。在 GDScript 程式碼中,這些屬性使用的是“snake_case”,全小寫、單詞之間使用底線分隔。
你可以在屬性面板中懸停任何屬性的名稱來查看它的描述和在程式碼中的識別字。
Hello, world!¶
我們的腳本目前沒有做任何事情。讓我們開始列印文字“Hello, world!”到底部輸出面板。
往腳本中新增以下程式碼:
func _init():
print("Hello, world!")
public MySprite2D()
{
GD.Print("Hello, world!");
}
讓我們把它分解一下。 func
關鍵字定義了一個名為 _init
的新函式。這是類建構子的一個特殊名稱。如果你定義了這個函式,引擎會在記憶體中建立每個物件或節點時呼叫 _init()
。
備註
GDScript 是基於縮進的語言。行首的定位字元是 print()
程式碼正常工作的必要條件。如果你省略了它或者沒有正確縮進一行,編輯器將以紅色高亮顯示,並顯示以下錯誤資訊:“Indented block expected”(應有縮進塊)。
如果你還沒有保存場景為 sprite_2d.tscn
,請保存,然後按 F6 (macOS 上為 Cmd + R )來運作它。看一下底部展開的 輸出 面板。它應該顯示“Hello, world!”。
將 _init()
函式刪除,這樣你就只有一行 extends Sprite2D
了。
四處旋轉¶
是時候讓我們的節點移動和旋轉了。為此,我們將向腳本中新增兩個成員變數:以像素每秒為單位的移動速度,和以弧度每秒為單位的角速度。將下述內容新增到 extends Sprite2D
行的後面。
var speed = 400
var angular_speed = PI
private int _speed = 400;
private float _angularSpeed = Mathf.Pi;
成員變數位於腳本的頂部,在“extends”之後、函式之前。附加了此腳本的每個節點實例都將具有自己的 speed
和 angular_speed
屬性副本。
備註
與其他一些引擎一樣,Godot 中的角度預設使用弧度為單位,但如果您更喜歡以度為單位計算角度,則可以使用內建函式和屬性。
為了移動我們的圖示,我們需要在遊戲迴圈中每一影格更新其位置和旋轉。我們可以使用 Node
類中的虛函式 _process()
。如果你在任何擴充自 Node 類的類中定義它,如 Sprite2D,Godot將在每一影格呼叫該函式,並傳遞給它一個名為 delta
的參數,即從上一影格開始經過的時間。
備註
遊戲的工作方式是每秒鐘渲染許多圖像,每幅圖像稱為一影格,而且是迴圈進行的。我們用每秒影格數(FPS)來衡量一個遊戲產生圖像的速度。大多數遊戲的目標是60FPS,儘管你可能會發現在較慢的移動裝置上的數位是30FPS,或者是虛擬實境遊戲的90至240。
引擎和遊戲開發者盡最大努力以恒定的時間間隔更新遊戲世界和渲染圖像,但在影格的渲染時間上總是存在著微小的變化。這就是為什麼引擎為我們提供了這個delta時間值,使我們的運動與我們的畫面播放速率無關。
在腳本的底部,定義該函式:
func _process(delta):
rotation += angular_speed * delta
public override void _Process(double delta)
{
Rotation += _angularSpeed * (float)delta;
}
func
關鍵字定義了一個新函式。在它之後,我們必須在括弧裡寫上函式的名稱和它所接受的參數。冒號結束定義,後面的縮進塊是函式的內容或指令。
備註
請注意 _process()
和 _init()
一樣都是以底線開頭的。按照約定,這是 Godot 的虛函式,也就是你可以覆蓋的與引擎通信的內建函式。
函式內部的那一行 rotation += angular_speed * delta
每一影格都會增加我們的精靈的旋轉量。這裡 rotation
是從 Sprite2D
所擴充的 Node2D
類繼承的屬性。它可以控制我們節點的旋轉,以弧度為單位。
小訣竅
在程式碼編輯器中,你可以按住 ctrl 按一下任何內建的屬性或函式,如 position
、 rotation
、 _process
以在新標籤頁中打開相應的文件。
運作該場景,可以看到 Godot 的圖示在原地轉動。
備註
在 C# 中,請注意 _Process()
所採用的 delta
參數型別是 double
。 故當我們將其應用於旋轉時,需要將其轉換為 float
。
下一頁¶
現在我們來讓節點移動。在 _process()
函式中新增下面兩行程式碼,確保每一行都和之前的 rotation += angular_speed * delta
行的縮進保持一致。
var velocity = Vector2.UP.rotated(rotation) * speed
position += velocity * delta
var velocity = Vector2.Up.Rotated(Rotation) * _speed;
Position += velocity * (float)delta;
正如我們所看到的, var
關鍵字可以定義新變數。如果你把它放在腳本頂部,定義的就是類的屬性。在函式內部,定義的則是區域變數:只在函式的作用域中存在。
We define a local variable named velocity
, a 2D vector representing both a
direction and a speed. To make the node move forward, we start from the Vector2
class's constant Vector2.UP
, a vector pointing up, and rotate it by calling the
Vector2 method rotated()
. This expression, Vector2.UP.rotated(rotation)
,
is a vector pointing forward relative to our icon. Multiplied by our speed
property, it gives us a velocity we can use to move the node forward.
我們在節點的 position
里加上 velocity * delta
來實作移動。位置本身是 Vector2 型別的,是 Godot 用於表示 2D 向量的內建型別。
運作場景就可以看到 Godot 頭像在繞圈圈。
備註
使用這樣的方法不會考慮與牆壁和地面的碰撞。在 您的第一個 2D 遊戲 中,你會學到另一種移動物件的方法,可以偵測碰撞。
Our node currently moves by itself. In the next part, 監聽玩家的輸入, we'll use player input to control it.
GDScript 範例¶
這是完整的 sprite_2d.gd
檔案,僅供參考。
extends Sprite2D
var speed = 400
var angular_speed = PI
func _process(delta):
rotation += angular_speed * delta
var velocity = Vector2.UP.rotated(rotation) * speed
position += velocity * delta
using Godot;
public partial class MySprite2D : Sprite2D
{
private int _speed = 400;
private float _angularSpeed = Mathf.Pi;
public override void _Process(double delta)
{
Rotation += _angularSpeed * (float)delta;
var velocity = Vector2.Up.Rotated(Rotation) * _speed;
Position += velocity * (float)delta;
}
}