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.

遊戲資訊顯示

我們的遊戲最後還需要使用者介面(User Interface,UI),顯示分數、“遊戲結束”資訊、重啟按鈕。

建立一個新的場景,點擊「其他節點」按鈕並新增一個 CanvasLayer 節點,命名為 HUD 。「HUD」是 "heads-up display"(抬頭顯示器)的縮寫,是一種資訊顯示方式,會以覆蓋層的形式出現在遊戲畫面之上。

使用 CanvasLayer 節點可以讓我們在遊戲上方的圖層上繪製 UI 元素,這樣上面顯示的資訊就不會被其他遊戲元素如玩家或怪物給蓋住。

HUD 需要顯示如下資訊:

  • 分數,會通過 ScoreTimer 來更改。

  • 訊息,如「Gamer Over」或「請準備!」

  • 用來開始遊戲的「Start」按鈕。

UI 元素所使用的基本節點是 Control 。我們需要使用兩種類型的 Control 節點來給這個遊戲建立 UI: Label (標籤)與 Button (按鈕)。

HUD 節點建立下列子節點:

  • Label ,命名為 ScoreLabel

  • Label ,命名為 Message

  • Button ,命名為 StartButton

  • Timer ,命名為 MessageTimer

點擊 ScoreLabel 並在屬性檢視器中的 Text 輸入一個數字。 Control 節點的預設字形很小,而且也縮放得不是很好。遊戲素材裡有包含了一個字形檔,檔名為「Xolonium-Regular.ttf」。依照下列步驟來使用這個字形:

在“Theme Overrides > Fonts”(主題覆蓋 > 字體)中選擇“載入”,然後選中“Xolonium-Regular.ttf”檔。

../../_images/custom_font_load_font.webp

字形尺寸仍然太小,請在“Theme Overrides > Font Sizes”(主題覆蓋 > 字形大小)下將其增加到 64 。當 ScoreLabel 完成此操作後,請重複對 MessageStartButton 節點做同樣的修改。

../../_images/custom_font_size.webp

備註

錨點 (Anchors): Control 節點除了位置和尺寸之外,還有錨點。錨點定義了原點 - 作為節點邊緣的參考點。

請將節點如下圖排列。拖動節點可以手動放置,也可以使用"錨點預設(Anchor Preset)"進行更精確的定位。

../../_images/ui_anchor.webp

ScoreLabel

  1. 新增文字 0

  2. 將“Horizontal Alignment”和“Vertical Alignment”設定為 Center

  3. 為“Anchor Preset”選擇 Center Top

訊息

  1. 新增文字: Dodge the Creeps!

  2. 將“Horizontal Alignment”和“Vertical Alignment”設定為 Center

  3. 將“Autowrap Mode”設定為 Word ,否則標籤只會有一行。

  4. 在“Control - Layout/Transform”中將“Size X”設定為 480 ,使用螢幕的完整寬度。

  5. 為“Anchor Preset”選擇 Center

StartButton

  1. 新增文字: Start

  2. 在“Control - Layout/Transform”中將“Size X”設定為 200、“Size Y”設定為 100,在邊框和文字之間新增間距。

  3. 為“Anchor Preset”選擇 Center Bottom

  4. 在“Control - Layout/Transform”中將“Position Y”設定為 580

MessageTimerWait Time 設為 2 ,將 One Shot 設為「開啟」。

現在將這個腳本新增至 HUD

extends CanvasLayer

# Notifies `Main` node that the button has been pressed
signal start_game

我們現在想要暫時顯示訊息(例如「Get Ready」),所以新增以下程式碼

func show_message(text):
    $Message.text = text
    $Message.show()
    $MessageTimer.start()

當玩家輸了之後會呼叫這個函式。會在畫面上顯示 2 秒「Game Over」,然後回到標題畫面、暫停一下,最後顯示「Start」按鈕。

func show_game_over():
    show_message("Game Over")
    # Wait until the MessageTimer has counted down.
    await $MessageTimer.timeout

    $Message.text = "Dodge the Creeps!"
    $Message.show()
    # Make a one-shot timer and wait for it to finish.
    await get_tree().create_timer(1.0).timeout
    $StartButton.show()

備註

需要暫停一下下的時候,除了使用 Timer 節點外也可以使用 SceneTree(場景樹)的 create_timer() 函式。當需要像上面的程式碼一樣新增一點延遲的時候很有用,上面的例子中我們用它來在顯示「Start」按鈕前增加一點點等待時間。

將以下更新分數程式碼新增到 HUD

func update_score(score):
    $ScoreLabel.text = str(score)

StartButtonpressed() 訊號和 MessageTimertimeout() 訊號連接到 HUD 節點,並將下列程式碼新增到新的函式中:

func _on_start_button_pressed():
    $StartButton.hide()
    start_game.emit()

func _on_message_timer_timeout():
    $Message.hide()

將 HUD 場景連接至 Main 場景

我們現在做好 HUD 場景了。讓我們回到 Main。像剛才實體化 Player 場景一樣,在 Main 場景中實體化 HUD。場景樹會看起來像這樣,檢查一下有沒有漏了什麼:

../../_images/completed_main_scene.webp

我們現在需要把 HUD 的功能連接到 Main 腳本。所以我們需要在 Main 場景內新增一點點東西:

In the Signals tab, connect the HUD's start_game signal to the new_game() function of the Main node by clicking the "Pick" button in the "Connect a Signal" window and selecting the new_game() method or type "new_game" below "Receiver Method" in the window. Verify that the green connection icon now appears next to func new_game() in the script.

new_game() 中,需要更新分數並顯示「Get Ready」訊息:

$HUD.update_score(score)
$HUD.show_message("Get Ready")

game_over() 中我們需要呼叫對應的 HUD 函式:

$HUD.show_game_over()

最後,將這段程式碼加到 _on_ScoreTimer_timeout() 來讓分數改變的時候能同步顯示:

$HUD.update_score(score)

警告

記得移除 _ready() 中對 new_game() 的呼叫(如果你還沒做的話),否則你的遊戲會自動開始。

現在你已經準備好開始遊玩了!點擊「執行專案」按鈕。

刪除舊的怪物

如果一直玩到「Game Over」並直接開始新遊戲的話,上一場遊戲的怪物可能還在畫面上。開始遊戲的時候如果能讓舊的怪物消失會更好。而我們只需要告訴 所有 怪物,刪除自己。我們可以在這裡使用「群組」功能。

In the Mob scene, select the root node and click the Groups tab next to the Signals tab and the "+" button to open the "Create New Group" dialog.

../../_images/group_tab.webp

將群組命名為 mobs ,然後點擊「確定」以新增一個場景群組。

../../_images/add_group_dialog.webp

現在所有怪物都會在「mobs」群組裡了。

../../_images/scene_group_mobs.webp

然後我們可以在 Main 腳本的 new_game() 函式中加入以下這行:

get_tree().call_group("mobs", "queue_free")

call_group() 函式會呼叫群組中所有節點的指定名稱的函式——在這裡我們用來讓所有怪物刪除自己。

遊戲在這一點上大部分已經完成。在下一部分和最後一部分中,我們將通過新增背景,迴圈音樂和一些鍵盤快捷鍵來對其進行一些潤色。