ETH官方钱包

前往
大廳
主題 達人專欄

【Godot 教學】製作你的第一個 2D 遊戲:加入 UI 護盾能量條 和 分數- EP9

Muryan | 2023-11-13 20:00:22 | 巴幣 1210 | 人氣 645

前言

這篇拖得有點久。
因為最近想買臺新電腦,陷入嚴重的選擇障礙。
花了不少時間去了解規格。我絕對不會說是我懶了。

這系列已經進入尾聲,遊戲大致上完成了,剩下一些UI還需要處理。


Godot 開拓者交流互助公會 無論是新手還是有經驗的 Godot 使用者,都歡迎你的參與。

開拓者交流互助公會
  • 飛船護盾條(ProgressBar)製作
    • 建立 UI 場景
    • MarginContainer 設置
    • Anchor preset 說明
    • 護盾條外觀設定
  • 分數計算(Label)
    • 設定文字及樣式
  • 腳本編寫
    • 更新分數和護盾條


今天的主題是UI,主要會完成的有兩樣功能。
一個是飛船的護盾(血量),另一個是計分。

每擊落一個敵人,計分就會增加。
而護盾會在飛船碰到攻擊的時候減少,歸零遊戲就結束了。


護盾(ProgressBar)


我們開始製作護盾前,我們選擇 MarginContainer 作為第一個 Node ,命名為UI
護盾和分數都會放在UI底下。
新增一個資料夾也命名為 ui,然後把我們剛建立的UI場景存到裡面。




MarginContainer 前面的 Margin 是指邊緣,
Container 它是一個容器,可以拿來裝UI的元素。
所以它可以控制放到 MarginContainer 裡的 UI元素之間的距離。

底下我們就來看看它的效果。
先設定 MarginContainer 上下左右距離都要 10。


可以看到放到 MarginContainer 裡面的 UI元素會被強制往內縮了一圈。


接著我們要設置 Anchor preset
Anchor preset 是什麼?
它是預設的錨點,可以固定UI的位置。


這裡我們選擇 Top Wide
讓它保持在畫面頂部,橫向佔滿。

補充影片

有中文字幕記得打開


剛剛我們新增的 MarginContainer 依照上面的範例,我們全部設為 10。
然後 Anchor preset 設為 Top Wide。

接著我們在 MarginContainer 底下增加 HBoxContainer
它會把放進去的東西會自動排成橫排。


HBoxContainer 底下我們新增兩個 NodeProgressBarLabel
ProgressBar 要用來顯示護盾剩餘多少能量,Label 要用來顯示分數。
命名為 ShieldBarScoreLabel

先來設定 ProgressBar
Show Percentage(%) 關掉。


ProgressBar 的最小尺寸。
保證它至少不能小於我們設好的尺寸。


可以調 Value 看看 ProgressBar 動起來的效果。


Vertical 設定 Shrink Center,在垂直方向的是往中心對齊縮小。
有點像文字置中的操作。


雖然直接用預設的外觀也可以達到一樣的功能,但是就沒有那麼好看
所以我們這邊來稍微調整它的外觀。

這裡用最簡單的方式。
Background(進度條背景)和 Fill(進度條顏色)都用 StyleBoxFlat
單色的長方形。


顏色看個人喜好調整。
背景的顏色可以考慮用深色系。
然後這裡我調整 Skew,讓護盾條有一些歪斜。


換下一個一樣顏色選自己喜歡的。
那我用背景顏色的比較亮的淺色版本。
然後讓它跟背景歪一樣的角度。


跟背景不一樣的是這裡我還要再設定護盾條的邊框。
上下左右各設 2,邊框顏色設為透明,讓它感覺像是被背景包起來。
讓進度條的外觀更有護盾能量(血量)的感覺。


ProgressBar 的設定大致上就這樣。
先跳過程式的部分,繼續設定 Label


分數(Label)


Label 的部分很簡單。
Text 中的字會顯示在螢幕,我們會用腳本去控制它顯示分數。
這裡簡單打了一些數字做測試。


Label Settings,則是可以對字體做更詳細的設定。
先新增一個 New LabelSettings,等一下再調整。
接著把字的位置設定為 Right靠右)、Bottom底部)。

ProgressBar 一樣,也要設定 Label 的最小尺寸。


最後我們回來設定 LabelSettings
Font字體) 是從 itch.io 上找來的。


打開網頁下載後,把裡面的字體直接放到我們創好的UI資料夾。
然後直接把它拉到 Font


剩下也是看自己喜好做調整,例如字的大小、外框(Outline)、陰影(Shadow)。


設定得差不多,我們可以先把它放到 main 看看效果。
Control Node 通常都會放在 CanvasLayer 下面。


雖然還不會動,是不是感覺更像遊戲了。



腳本


我們在 MarginContainerUI)新增一個腳本。
裡面會寫兩個 func,負責更新UI護盾能量條長度 和 分數顯示。
之後可以從其他地方使用它們。


第一個 funcupdate_score(value)
label 的文字變成輸入的值。

補充


「"%08d" % value 」是 GDSript 的一種 format strings格式化字符串)應用
% 是讓 godot 知道它後面要插入我們指定的值
0 是不足的位數補零
8 是指 8 位數
d 是指值的類型

舉例來說我們現在得到了 150 分
它會顯示 00000150
更詳細的官方說明,請點這裡



第二個 funcupdate_shield(max_value, value)
會去改變 ProgressBarmax_valuevalue
以此來控制護盾條長度

接著我們轉到 main.gd
找到底下之前做好的 on_enemy_died()。
原本的功能只有加分數。

增加一段程式碼,讓它同時呼叫UI更新顯示的分數。
記得要先把UI(Scene)加到 Main 才能用 $CanvasLayer/UI


最後要來處理飛船的護盾條。
我們再跳到 player.gd,先在上面增加兩個 signal


並且增加兩個變數 max_shieldshield


這裡是我們第一次看到變數後面加了 : set = set_shield
每當我們改變 shield 的值,會執行 set_shield()。
來看看我們可以怎麼利用它。


當我們改變 shield 的值。
shield = min(max_shield, value)
會把我們要改變的護盾值和最大護盾值做比較,取比較小的那方。
這樣做的意義是讓護盾的值不要超過我們設好的最大值。

接著發出 shield_changed 的訊號,通知UI去做更新。
最後判斷如果護盾歸零就把飛船隱藏,發出玩家死亡的訊號。

再來我們要處理的是護盾減少的情況。
一個是被敵人直接撞上的時候,另一個是碰到敵人子彈的時候。

被敵人撞到就是需要偵測碰撞,要用到 area_entered


照著之前的做法,我們把訊號連上。
player.gd 中會自動增加 _on_area_entered()。
我們在底下加上這段。


一但跟飛船撞上的是敵人,敵人會爆炸並且扣掉飛船護盾最大值的一半。

接著我們畫面轉到 enemy_bullet.gd,要來處理碰到子彈扣護盾的情況。
很簡單只要在之前已經有的 _on_area_entered() 裡面多加一行程式碼就可以了。


最後我們回到 main
前面已經在 palyer 做好了護盾值改變時的訊號(shield_changed)。
這個訊號要接上UI,讓它可以在飛船發出訊號時,
同時改變UI顯示護盾能量條的長度。


前面的步驟都跟之前一樣。
但是在 Receiver Method 這裡我們要手動改成 update_shield
這樣當飛船發出訊號的時候,會自動呼叫UI裡面的 update_shield 去做更新。



廢話

我們已經完成 99% 了。

這系列快要結束了,一些簡單的感想廢話
我想教學有很多講得不清楚,需要改善的地方,麻煩大家多包涵。

有時候看完跟完一些教學影片,會覺得好像學會了。
我覺得教學只是讓你知道有這些功能的存在,
沒有去操作嘗試,會發現自己還是什麼都不會。

所以底下提供 GMTK 學習 Unity 的心得影片,給各位參考。
雖然不是 Godot 但我覺得是通用的。
希望大家都能做出心目中的好遊戲。

有提供中文(簡體)字幕


開拓者交流互助公會

創作回應

追蹤 創作集

作者相關創作

相關創作

更多創作