在先前的遊戲中,我們實作了遊戲狀態並提供處理狀態方法,提供開始及結束時應該要有的操作,同時我們保留了暫停的狀態,今天我們就來實現暫停的功能到我們的遊戲中。
準備我們暫停按鈕的 icon
,儲存到 arts
下建立一個新的資料夾 icons
。
HUD
場景中新增一個按鈕節點命名為: PauseButton
,移動位置到右上角。Control
Transform
postion
到理想的位置。var pause_button:Button
func _ready():
pause_button = $PauseButton
# 新增暫停、結束暫停訊號。
signal game_pause
signal game_unpause
# 宣告是否暫停中。
var is_stop:bool = false
# 綁定按鈕方法。
func _ready():
pause_button.pressed.connect(_on_pause_button_pressed)
# 新增暫停邏輯。
func _on_pause_button_pressed():
if is_stop:
show_game_unpause()
game_unpause.emit()
else:
show_game_pause()
game_pause.emit()
is_stop = !is_stop
# 暫停及結束暫停顯示畫面更新。
func show_game_pause():
message_label.text = "STOP"
message_label.show()
func show_game_unpause():
message_label.hide()
func _on_start_button_pressed():
# ...
# 點擊遊戲開始後開啟。
pause_button.visible = true
func show_game_over():
# 遊戲結束時關閉。
pause_button.visible = false
# ...
主場景
根節點修改程式,綁定暫停及結束暫停訊號到新增方法上。# 紀錄暫停的時間
var pause_time: int
# 綁定方法
func _ready():
hud.game_pause.connect(handle_game_pause)
hud.game_unpause.connect(handle_game_unpause)
# 紀錄暫停時間、更新狀態、暫停場景物件。
func handle_game_pause():
pause_time = Time.get_ticks_msec()
game_state = GAME_STATE.STOP
background.stop()
player.stop()
move_obstacles_timer.set_paused(true)
# 調整開始時間,將時間往後整個暫停的時間確保時間紀錄是正確的。
# 更新狀態、開始場景物件。
func handle_game_unpause():
start_time += (Time.get_ticks_msec() - pause_time)
game_state = GAME_STATE.START
background.start()
player.start()
move_obstacles_timer.set_paused(false)
移動障礙物場景
修改運作邏輯。# 宣告變數是否運行中。
var is_start:bool = true
# 將更新邏輯移動到運行狀態判斷中。
func _process(delta):
if is_start:
# ...
# 暫停邏輯
func _on_game_pause():
timer.stop()
is_start = !is_start
# 重啟邏輯
func _on_game_unpause():
timer.start()
is_start = !is_start
主場景
程式碼綁定訊號到移動障礙上。func _on_move_obstacle_timeout():
var instantiated_obj = move_obstacle_scene.instantiate()
var randf_pos = Vector2(randf_range(0, get_viewport().size.x), -3)
instantiated_obj.position = randf_pos
# 新增下面兩行,綁定訊號到生成的物件上。
hud.game_pause.connect(instantiated_obj._on_game_pause)
hud.game_unpause.connect(instantiated_obj._on_game_unpause)
add_child(instantiated_obj)
角色場景
程式碼修改角色狀態
邏輯。# 宣告儲存暫停時仍在運行的計時器。
var stopped_timer:Timer = null
func start():
game_state = GAME_STATE.START
# 新增下述:當有計時器被暫停則重新啟動並重置。
if stopped_timer != null:
stopped_timer.set_paused(false)
stopped_timer = null
get_node("CollisionShape2D").disabled = false
func stop():
get_node("CollisionShape2D").disabled = true
game_state = GAME_STATE.STOP
# 在三個計時器中檢查如果有正在運行的計時器則暫停並將計時器記錄到前面宣告的變數中,等待重啟。
for timer in [invincible_timer, slow_timer, stop_timer]:
if not timer.is_stopped():
timer.set_paused(true)
stopped_timer = timer
break
其實執行起來好像偶爾會出 bug 就讓我先假裝沒看到。
:)