iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
SideProject30

初探 Godot系列 第 24

[DAY 24] UI 設置 (CanvasLayer, Button, Label, await)

  • 分享至 

  • xImage
  •  

今日目標:加上遊戲開始以及結束介面


▍事前準備

為了建構遊戲流程,我們現在需要加上我們的遊戲界面,包含開始、結束、分數的設置,今天的內容主要是參考官方範例來實作。


▍出發

  • 場景節點設置
    1. 建立一個新場景命名為 HUD 儲存到 scenes 資料夾下,這個場景將作為獨立於遊戲顯示在之上的一層顯示畫面。
    2. 建立一個 CanvasLayer 作為場景根節點,在節點下加入兩個 Label 節點、一個 Button 節點以及一個 Timer 節點(這個節點我們將 one_shot 打勾)。
    # 結構如下:
    |--CanvasLayer
    |   |--Message (Label)
    |   |--Score (Label)
    |   |--StartButton (Button)
    |   |--MessageTimer (Timer)
    
  • 在 2D 頁面調整我們的介面顯示
    1. 在屬性面板 Labeltext 中可以輸入我們的預設文字, Horiontal/Vertical Alignment可以設置文字的對齊方式。
      https://ithelp.ithome.com.tw/upload/images/20231009/20162875vtOm1dAEvG.png
    2. Control 欄位裡的 Layout 中可以設定:
      a. Anchors present 指定錨點的預設位置。
      b. TransformSize 調整文字框的大小,可以透過這個設置保留文字和框之間的間距,Position 調整位置。
      Theme Overrides 中可以設定字體大小。
      => 依序將兩個 LabelButton 調整到我們期望的位置及字體大小:
      https://ithelp.ithome.com.tw/upload/images/20231009/20162875Q1hreoYUS1.png
  • 撰寫界面邏輯
    1. 在根節點上新增腳本,儲存到 scripts 資料夾下。
    2. 宣告並初始化我們介面的元件
    var message_label:Label
    var score_label:Label
    var start_button:Button
    var message_timer:Timer
    
    func _ready():
        message_label = $Message
        score_label = $Score
        start_button = $StartButton
        message_timer = $MessageTimer
    
    1. 建立方法並綁定到按鈕以及計時器上,並建立遊戲開始的訊號
    # 建立訊號
    signal game_start
    
    func _ready():
    # ...
        start_button.pressed.connect(_on_start_button_pressed)
        message_timer.timeout.connect(_on_message_timer_timout)
    
    func _on_start_button_pressed():
        # 點擊開始按鈕後便可以隱藏按鈕。
        start_button.hide()
        # 執行遊戲開始顯示畫面,在下面第 6 步中建立。
        show_game_start()
        # 觸發訊號,通知需要知道遊戲開始的方法。
        game_start.emit()
    
    # 當計時結束時關閉我們的訊息。
    func _on_message_timer_timout():
        message_label.hide()
    
    1. 當遊戲開始及結束時我們需要顯示個別的內容,因此我們先建立一個顯示文字的方法。
    # 顯示一個內容為 text 的訊息,並在 wait_time 後透過上一步訊號連結的方法關閉。
    func show_message(text: String, wait_time: float=2):
        message_label.text = text
        message_label.show()
        message_timer.wait_time = wait_time
        message_timer.start()
    
    1. 建立開始及結束顯示的內容方法。
    func show_game_start():
        show_message("Ready", 0.8)
        # 透過 await 方法等待上一個訊息關閉。
        await message_timer.timeout
        show_message("Go!!!", 0.8)
        await message_timer.timeout
    
    func show_game_over():
        show_message("Game Over")
        await message_timer.timeout
    
        # 恢復起始預設訊息,因為並沒有要關閉所以不用上面的方法。
        message_label.text = "RUN!!"
        message_label.show()
    
        # 建立一個計時器倒數完成後顯示開始按鈕。
        await get_tree().create_timer(1.0).timeout
        start_button.show()
    
    1. 建立設置分數的方法
    func update_score(score):
        score_label.text = str(score)
    

▍執行

為了測試,我們直接在開始後三秒結束遊戲測試結束畫面是否正常執行。

	# for TEST add this inside _on_start_button_pressed function.
	await get_tree().create_timer(3).timeout
	show_game_over()

Yes

▍完成

完整檔案

extends CanvasLayer

signal game_start

var message_label:Label
var score_label:Label
var start_button:Button
var message_timer:Timer
	
func _ready():
	message_label = $Message
	score_label = $Score
	start_button = $StartButton
	message_timer = $MessageTimer
	
	start_button.pressed.connect(_on_start_button_pressed)
	message_timer.timeout.connect(_on_message_timer_timout)
	
func _on_start_button_pressed():
	start_button.hide()
	show_game_start()
	game_start.emit()
	
func _on_message_timer_timout():
	message_label.hide()
	
func show_message(text: String, wait_time: float=2):
	message_label.text = text
	message_label.show()
	message_timer.wait_time = wait_time
	message_timer.start()
	
func show_game_start():
	show_message("Ready", 0.8)
	await message_timer.timeout
	show_message("Go!!!", 0.8)
	await message_timer.timeout
	
func show_game_over():
	show_message("Game Over")
	await message_timer.timeout
	
	message_label.text = "RUN!!"
	message_label.show()
	
	await get_tree().create_timer(1.0).timeout
	start_button.show()
	
func update_score(score):
	score_label.text = str(score)

:)


上一篇
[DAY 23] 組合移動障礙 (VisibleOnScreenNotifier2D)
下一篇
[DAY 25] 組合 UI
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言