Game1硬幣收集 - 第4部分 用戶界面 - Godot引擎游戲開發(fā)項(xiàng)目實(shí)踐

第4部分 用戶界面

您的游戲制作的最后一塊是用戶界面(UI)。這是一個(gè)界面,用于顯示玩家在游戲過程中需要查看的信息。在游戲中,這也被稱為平視顯示器(HUD),因?yàn)樾畔⒃谟螒蛞晥D的頂部顯示為疊加。您還將使用此場(chǎng)景顯示開始按鈕。

HUD將顯示以下信息:

  • 分?jǐn)?shù)
  • 剩余時(shí)間
  • 消息,例如Game Over
  • 開始按鈕

節(jié)點(diǎn)設(shè)置

創(chuàng)建一個(gè)新場(chǎng)景并添加名為HUD的CanvasLayer節(jié)點(diǎn)。CanvasLayer節(jié)點(diǎn)允許您在游戲剩余部分上方的圖層上繪制UI元素,這樣它顯示的信息就不會(huì)被玩家或硬幣等任何游戲元素所覆蓋。

Godot提供了各種各樣的UI元素,可用于創(chuàng)建從健康欄等指標(biāo)到庫(kù)存等復(fù)雜界面的任何內(nèi)容。事實(shí)上,你用來(lái)制作這個(gè)游戲的Godot編輯器是使用這些元素在Godot中構(gòu)建的。 UI元素的基本節(jié)點(diǎn)從Control擴(kuò)展,并在節(jié)點(diǎn)列表中以綠色圖標(biāo)顯示。要?jiǎng)?chuàng)建UI,您將使用各種控制節(jié)點(diǎn)來(lái)定位,格式化和顯示信息。以下是完成后HUD的樣子:

HUD界面

錨點(diǎn)和邊距

控制節(jié)點(diǎn)具有位置和大小,但它們也具有稱為anchors(錨點(diǎn))和margins(邊距)的屬性。錨定義節(jié)點(diǎn)邊緣相對(duì)于父容器的原點(diǎn)或參考點(diǎn)。邊距表示從控制節(jié)點(diǎn)的邊緣到其對(duì)應(yīng)錨點(diǎn)的距離。移動(dòng)控件節(jié)點(diǎn)或調(diào)整控件節(jié)點(diǎn)大小時(shí),邊距會(huì)自動(dòng)更新。


信息標(biāo)簽

Label節(jié)點(diǎn)添加到場(chǎng)景并將其名稱更改為MessageLabel。此標(biāo)簽將顯示游戲的標(biāo)題,以及游戲結(jié)束時(shí)的Game Over。此標(biāo)簽應(yīng)以游戲屏幕為中心。您可以使用鼠標(biāo)拖動(dòng)它,但要精確放置UI元素,您應(yīng)該使用Anchor屬性。

選擇View|Show Helpers顯示幫助程序以顯示可幫助您查看錨點(diǎn)位置的引腳,然后單擊Layout菜單并選擇HCenter Wide(水平居中):

Layout菜單

MessageLabel現(xiàn)在跨越屏幕的寬度并垂直居中。 Inspector中的Text屬性設(shè)置標(biāo)簽顯示的文本。把它設(shè)置為Coin Dash!并將AlignValign設(shè)置為Center。

Label節(jié)點(diǎn)的默認(rèn)字體非常小,因此下一步是分配自定義字體。向下滾動(dòng)到Inspector中的Custom Fonts部分,然后選擇New DynamicFont,如以下屏幕截圖所示:

自定義字體

現(xiàn)在,單擊DynamicFont,您可以調(diào)整字體設(shè)置。從FileSystem側(cè)邊欄中,拖動(dòng)Kenney Bold.ttf字體并將其放在Font Data屬性中。將Size設(shè)置為48,如以下屏幕截圖所示:

字體屬性

分?jǐn)?shù)和時(shí)間顯示

HUD的頂部將顯示玩家的分?jǐn)?shù)和時(shí)鐘剩余的時(shí)間。這兩個(gè)都是Label節(jié)點(diǎn),排列在游戲屏幕的兩側(cè)。您可以使用Container節(jié)點(diǎn)來(lái)管理其位置,而不是單獨(dú)定位它們。

Containers容器

UI容器自動(dòng)排列其子Control節(jié)點(diǎn)(包括其他Containers)的位置。您可以使用它們?cè)谠刂車砑犹畛洌又?,或按行或列排列元素。每種類型的Container都有特殊的屬性來(lái)控制他們?nèi)绾伟才抛禹?xiàng)。您可以在檢查器的Custom Constants部分中看到這些屬性。

提示
請(qǐng)記住,容器會(huì)自動(dòng)調(diào)整其子項(xiàng)。如果移動(dòng)或調(diào)整Container節(jié)點(diǎn)內(nèi)的Control,您會(huì)發(fā)現(xiàn)它會(huì)快速恢復(fù)到原始位置。您可以手動(dòng)排列控件或使用容器排列它們,但不能同時(shí)排列兩者。

MarginContainer節(jié)點(diǎn)添加到HUD。使用Layout菜單將錨點(diǎn)設(shè)置為Top Wide。在Custom Constants部分中,將Margin Right,Margin TopMargin Left設(shè)置為10。這將添加一些填充,以便文本不會(huì)對(duì)著屏幕的邊緣。

由于得分和時(shí)間標(biāo)簽將使用與MessageLabel相同的字體設(shè)置,因此如果您復(fù)制它,將節(jié)省時(shí)間。單擊MessageLabel并按兩次Ctrl + D(在macOS上為Cmd + D)以創(chuàng)建兩個(gè)重復(fù)標(biāo)簽。拖動(dòng)它們并將它們放在MarginContainer上以使它們成為子項(xiàng)。將一個(gè)命名為ScoreLabel,另一個(gè)命名為TimeLabel,并將Text屬性設(shè)置為0。為ScoreLabel設(shè)置為Align to Left,為TimeLabel設(shè)置為Align to Right。


通過腳本更新UI

將腳本添加到HUD節(jié)點(diǎn)。例如,該腳本將在其屬性需要更改時(shí)更新UI元素,并在收集硬幣時(shí)更新分?jǐn)?shù)文本。請(qǐng)參閱以下代碼:

extends CanvasLayer

signal start_game

func update_score(value):
    $MarginContainer/ScoreLabel.text = str(value)
func update_timer(value):
    $MarginContainer/TimeLabel.text = str(value)

Main場(chǎng)景的腳本將調(diào)用這些函數(shù),以便在值發(fā)生變化時(shí)更新顯示。對(duì)于MessageLabel,您還需要一個(gè)計(jì)時(shí)器,使其在短暫的一段時(shí)間后消失。添加Timer節(jié)點(diǎn)并將其名稱更改為MessageTimer。在Inspector中,將其Wait Time設(shè)置為2秒,然后選中One Shot設(shè)置為On。這確保了在啟動(dòng)時(shí),計(jì)時(shí)器只運(yùn)行一次,而不是重復(fù)。添加以下代碼:

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

在此功能中,您將顯示消息并啟動(dòng)計(jì)時(shí)器。要隱藏消息,請(qǐng)連接MessageTimertimeout()信號(hào)并添加以下內(nèi)容:

func _on_MessageTimer_timeout():
    $MessageLabel.hide()

使用按鈕

添加一個(gè)Button節(jié)點(diǎn)并將其名稱更改為StartButton。此按鈕將在游戲開始前顯示,點(diǎn)擊后,它將隱藏自身并向Main場(chǎng)景發(fā)送信號(hào)以啟動(dòng)游戲。將Text屬性設(shè)置為Start并更改自定義字體,就像使用MessageLabel一樣。在Layout菜單中,選擇Center Bottom。這會(huì)將按鈕放在屏幕的最底部,因此可以通過按向上箭頭鍵或編輯Margin并將Top設(shè)置為-150,將Bottom設(shè)置為-50來(lái)將其向上移動(dòng)一點(diǎn)。

單擊按鈕時(shí),會(huì)發(fā)出信號(hào)。在StartButtonNode選項(xiàng)卡中,連接pressed()信號(hào):

func _on_StartButton_pressed():
    $StartButton.hide()
    $MessageLabel.hide()
    emit_signal("start_game")

HUD發(fā)出start_game信號(hào)以通知Main,是時(shí)候開始新游戲了。


游戲結(jié)束

UI的最終任務(wù)是對(duì)游戲結(jié)束作出反應(yīng):

func show_game_over():
    show_message("Game Over")
    yield($MessageTimer, "timeout")
    $StartButton.show()
    $MessageLabel.text = "Coin Dash!"
    $MessageLabel.show()

在此函數(shù)中,您需要將Game Over消息顯示兩秒鐘然后消失,這就是show_message()所做的事情。但是,您還希望在消息消失后??顯示開始按鈕。 yield()暫停函數(shù)的執(zhí)行,直到給定節(jié)點(diǎn)(MessageTimer)發(fā)出給定信號(hào)(timeout)。收到信號(hào)后,該功能繼續(xù),使您返回初始狀態(tài),以便您可以再次游戲。

文檔
yield()


添加HUD到Main場(chǎng)景

現(xiàn)在,您需要設(shè)置Main場(chǎng)景和HUD場(chǎng)景之間的通信。將HUD場(chǎng)景的實(shí)例添加到主場(chǎng)景。在Main場(chǎng)景中,連接GameTimertimeout()信號(hào)并添加以下內(nèi)容:

func _on_GameTimer_timeout():
    time_left -= 1
    $HUD.update_timer(time_left)
    if time_left <= 0:
        game_over()

每當(dāng)GameTimer超時(shí)(每秒)時(shí),剩余時(shí)間就會(huì)減少。接下來(lái),連接Playerpickup()hurt()信號(hào):

func _on_Player_pickup():
    score += 1
    $HUD.update_score(score)

func _on_Player_hurt():
    game_over()

游戲結(jié)束時(shí)需要做幾件事,所以添加以下功能:

func game_over():
    playing = false
    $GameTimer.stop()
    for coin in $CoinContainer.get_children():
        coin.queue_free()
    $HUD.show_game_over()
    $Player.die()

此功能會(huì)暫停游戲,并循環(huán)顯示硬幣并刪除剩余的任何內(nèi)容,以及調(diào)用HUDshow_game_over()函數(shù)。

最后,StartButton需要激活new_game()函數(shù)。單擊HUD實(shí)例并選擇其new_game()信號(hào)。在信號(hào)連接對(duì)話框中,單擊Make Function將函數(shù)設(shè)置為Off,然后在Method In Node字段中鍵入new_game。這會(huì)將信號(hào)連接到現(xiàn)有功能,而不是創(chuàng)建新功能??纯聪旅娴慕貓D:

激活new_game()

_ready()函數(shù)中刪除new_game()并將這兩行添加到new_game()函數(shù)中:

$HUD.update_score(score)
$HUD.update_timer(time_left)

現(xiàn)在,你可以玩游戲了!確認(rèn)所有部件都按預(yù)期工作:分?jǐn)?shù),倒計(jì)時(shí),游戲結(jié)束和重新啟動(dòng)等。如果您發(fā)現(xiàn)一塊不起作用,請(qǐng)返回并檢查您創(chuàng)建它的步驟,以及它與游戲其余部分連接的步驟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容