feat: introduce StopNGoManager to handle game phases, mission objectives, and dynamic arena setup with synchronized HUD elements.

This commit is contained in:
Yogi Wiguna
2026-02-26 10:02:39 +08:00
parent ef3d018040
commit 36485c7f25
+39 -36
View File
@@ -11,7 +11,7 @@ enum Phase {GO, STOP}
const GO_DURATION: float = 8.0
const STOP_DURATION: float = 4.0
const REQUIRED_GOALS: int = 5
const REQUIRED_GOALS: int = 8
var current_phase: Phase = Phase.GO
var phase_timer: float = GO_DURATION
@@ -28,7 +28,6 @@ const TILE_SAFE = 2 # Green Safe Zone
const TILE_OBSTACLE = 4 # Wall
var hud_layer: CanvasLayer
var phase_label: Label
var mission_label: Label
var red_tint_overlay: ColorRect
@@ -45,6 +44,7 @@ func _ready():
func _setup_hud():
hud_layer = CanvasLayer.new()
hud_layer.layer = 5 # Ensure it's above normal UI but below Pause Menu (10)
hud_layer.visible = false
add_child(hud_layer)
@@ -55,38 +55,24 @@ func _setup_hud():
red_tint_overlay.visible = false # Hidden initially
hud_layer.add_child(red_tint_overlay)
var vbox = VBoxContainer.new()
vbox.set_anchors_preset(Control.PRESET_TOP_RIGHT)
vbox.offset_right = -20
vbox.offset_top = 100
hud_layer.add_child(vbox)
# New container for bottom-mid label
var bottom_container = CenterContainer.new()
bottom_container.set_anchors_preset(Control.PRESET_CENTER_BOTTOM)
bottom_container.grow_horizontal = Control.GROW_DIRECTION_BOTH
bottom_container.grow_vertical = Control.GROW_DIRECTION_BEGIN
bottom_container.offset_bottom = -50
hud_layer.add_child(bottom_container)
# Style for HUD
var style = StyleBoxFlat.new()
style.bg_color = Color(0, 0, 0, 0.4)
style.content_margin_left = 10
style.content_margin_top = 10
style.content_margin_right = 10
style.content_margin_bottom = 10
var panel = PanelContainer.new()
panel.add_theme_stylebox_override("panel", style)
vbox.add_child(panel)
var inner_vbox = VBoxContainer.new()
panel.add_child(inner_vbox)
phase_label = Label.new()
phase_label.text = "PHASE: GO"
phase_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
phase_label.add_theme_font_size_override("font_size", 32)
phase_label.add_theme_color_override("font_color", Color.GREEN)
inner_vbox.add_child(phase_label)
var custom_font = load("res://assets/fonts/Nougat-ExtraBlack.ttf")
mission_label = Label.new()
mission_label.text = "MISSION: Collect 3 Items"
mission_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
inner_vbox.add_child(mission_label)
mission_label.text = "MISSION: Collect Goals"
mission_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
if custom_font: mission_label.add_theme_font_override("font", custom_font)
mission_label.add_theme_font_size_override("font_size", 28) # Slightly larger since it's centered
mission_label.add_theme_color_override("font_outline_color", Color.BLACK)
mission_label.add_theme_constant_override("outline_size", 8)
bottom_container.add_child(mission_label)
func _process(delta):
if not is_active:
@@ -105,12 +91,13 @@ func _process(delta):
# Update HUD locally
_update_hud_visuals()
func _on_goal_count_updated(_peer_id: int, _count: int):
# Refresh visuals whenever points change
_update_hud_visuals()
var _has_notified_mission_complete: bool = false
func _update_hud_visuals():
var phase_name = "GO" if current_phase == Phase.GO else "STOP"
if phase_label:
phase_label.text = "PHASE: %s (%.0fs)" % [phase_name, max(0, phase_timer)]
phase_label.add_theme_color_override("font_color", Color.GREEN if current_phase == Phase.GO else Color.RED)
# Toggle Red Screen Tint
if red_tint_overlay:
red_tint_overlay.visible = (current_phase == Phase.STOP)
@@ -128,8 +115,16 @@ func _update_hud_visuals():
if completed_count >= REQUIRED_GOALS:
mission_label.text = "ALL GOALS COMPLETE!\nREACH THE FINISH!"
mission_label.add_theme_color_override("font_color", Color.GOLD)
# Notify player once
if my_id == multiplayer.get_unique_id() and not _has_notified_mission_complete:
_has_notified_mission_complete = true
var player_node = main.get_node_or_null(str(my_id))
if player_node:
NotificationManager.send_message(player_node, "ALL GOALS COMPLETE!", NotificationManager.MessageType.GOAL)
else:
mission_label.add_theme_color_override("font_color", Color.WHITE)
_has_notified_mission_complete = false
# Update StopTimer (Traffic Light)
_update_stop_timer_visuals()
@@ -190,6 +185,14 @@ func activate_client_side():
is_active = true
if hud_layer:
hud_layer.visible = true
# Connect to GoalsCycleManager for immediate HUD updates
var main = get_node_or_null("/root/Main")
if main:
var gcm = main.get_node_or_null("GoalsCycleManager")
if gcm and not gcm.goal_count_updated.is_connected(_on_goal_count_updated):
gcm.goal_count_updated.connect(_on_goal_count_updated)
set_process(true)
func start_game_mode():