diff --git a/scenes/candy_survival_hud.tscn b/scenes/candy_survival_hud.tscn index 89fa643..1cd3cc3 100644 --- a/scenes/candy_survival_hud.tscn +++ b/scenes/candy_survival_hud.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=2 format=3] +[gd_scene load_steps=2 format=3 uid="uid://c6091875aa42720bfa9f9a7917331a09"] [ext_resource type="FontFile" uid="uid://xnjx058n4tsw" path="res://assets/fonts/Nougat-ExtraBlack.ttf" id="1_font"] @@ -13,37 +13,93 @@ anchor_right = 0.5 offset_top = 70.0 grow_horizontal = 2 -[node name="SlowMoLabel" type="Label" parent="TopContainer"] +[node name="SugarRushBar" type="ProgressBar" parent="TopContainer"] +custom_minimum_size = Vector2(300, 30) layout_mode = 2 +theme_override_fonts/font = ExtResource("1_font") theme_override_font_sizes/font_size = 18 -theme_override_colors/font_color = Color(0.3, 0.5, 1.0, 1) +theme_override_colors/font_color = Color(1, 1, 1, 1) theme_override_colors/font_outline_color = Color(0, 0, 0, 1) theme_override_constants/outline_size = 4 -theme_override_fonts/font = ExtResource("1_font") -text = "SLOW-MO" -horizontal_alignment = 1 +max_value = 1.0 +value = 0.0 +show_percentage = false visible = false +[node name="SugarRushLabel" type="Label" parent="TopContainer/SugarRushBar"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("1_font") +theme_override_font_sizes/font_size = 18 +theme_override_colors/font_color = Color(1, 0.2, 0.2, 1) +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 4 +text = "SUGAR RUSH!" +horizontal_alignment = 1 +vertical_alignment = 1 + [node name="BottomContainer" type="CenterContainer" parent="."] anchors_preset = 7 anchor_left = 0.5 anchor_top = 1.0 anchor_right = 0.5 anchor_bottom = 1.0 -offset_top = -120.0 +offset_top = -150.0 grow_horizontal = 2 grow_vertical = 0 -[node name="VBoxContainer" type="VBoxContainer" parent="BottomContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="BottomContainer"] +layout_mode = 2 +theme_override_constants/separation = 40 + +[node name="SabotagePanel" type="VBoxContainer" parent="BottomContainer/HBoxContainer"] layout_mode = 2 theme_override_constants/separation = 4 -[node name="PhaseLabel" type="Label" parent="BottomContainer/VBoxContainer"] +[node name="KnockChargesLabel" type="Label" parent="BottomContainer/HBoxContainer/SabotagePanel"] layout_mode = 2 -theme_override_font_sizes/font_size = 24 -theme_override_colors/font_color = Color(1, 0.6, 0.8, 1) +theme_override_font_sizes/font_size = 20 +theme_override_colors/font_color = Color(1, 0.6, 0.2, 1) +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 5 +theme_override_fonts/font = ExtResource("1_font") +text = "🥊 Knocks: 5" +horizontal_alignment = 1 + +[node name="GhostChargesLabel" type="Label" parent="BottomContainer/HBoxContainer/SabotagePanel"] +layout_mode = 2 +theme_override_font_sizes/font_size = 20 +theme_override_colors/font_color = Color(0.8, 0.8, 1.0, 1) +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 5 +theme_override_fonts/font = ExtResource("1_font") +text = "👻 Ghosts: 5" +horizontal_alignment = 1 + +[node name="ScorePanel" type="VBoxContainer" parent="BottomContainer/HBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="CandyStackBadge" type="Label" parent="BottomContainer/HBoxContainer/ScorePanel"] +layout_mode = 2 +theme_override_font_sizes/font_size = 28 +theme_override_colors/font_color = Color(1, 0.4, 0.8, 1) theme_override_colors/font_outline_color = Color(0, 0, 0, 1) theme_override_constants/outline_size = 6 theme_override_fonts/font = ExtResource("1_font") -text = "🍬 OPEN ARENA" +text = "Stack: 0 (x1)" horizontal_alignment = 1 + +[node name="PointsLabel" type="Label" parent="BottomContainer/HBoxContainer/ScorePanel"] +layout_mode = 2 +theme_override_font_sizes/font_size = 20 +theme_override_colors/font_color = Color(0.4, 1.0, 0.4, 1) +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 5 +theme_override_fonts/font = ExtResource("1_font") +text = "Score: 0" +horizontal_alignment = 1 \ No newline at end of file diff --git a/scripts/managers/candy_survival_manager.gd b/scripts/managers/candy_survival_manager.gd index 36497b5..3fdecc5 100644 --- a/scripts/managers/candy_survival_manager.gd +++ b/scripts/managers/candy_survival_manager.gd @@ -44,6 +44,49 @@ var current_face: CandyColor = CandyColor.HEART var face_timer: float = 0.0 var game_elapsed: float = 0.0 +# ── HUD ── +var hud_layer: CanvasLayer +var hud_knock_label: Label +var hud_ghost_label: Label +var hud_rush_bar: ProgressBar +var hud_rush_label: Label +var hud_stack_badge: Label +var hud_points_label: Label +var _candy_survival_hud_scene: PackedScene = preload("res://scenes/candy_survival_hud.tscn") + +func _ready(): + set_process(false) + _setup_hud() + +func _setup_hud() -> void: + var hud_instance = _candy_survival_hud_scene.instantiate() + hud_layer = hud_instance + hud_layer.visible = false + add_child(hud_layer) + + var bot_box = hud_layer.get_node_or_null("BottomContainer/HBoxContainer") + if bot_box: + hud_knock_label = bot_box.get_node_or_null("SabotagePanel/KnockChargesLabel") + hud_ghost_label = bot_box.get_node_or_null("SabotagePanel/GhostChargesLabel") + hud_stack_badge = bot_box.get_node_or_null("ScorePanel/CandyStackBadge") + hud_points_label = bot_box.get_node_or_null("ScorePanel/PointsLabel") + + var top_box = hud_layer.get_node_or_null("TopContainer") + if top_box: + hud_rush_bar = top_box.get_node_or_null("SugarRushBar") + if hud_rush_bar: + hud_rush_label = hud_rush_bar.get_node_or_null("SugarRushLabel") + +func start_game_mode() -> void: + if multiplayer.is_server(): + activate_client_side() + +func activate_client_side() -> void: + active = true + if hud_layer: + hud_layer.visible = true + set_process(true) + # Per-player state var player_candies: Dictionary = {} # pid -> int (stack count) var player_candy_color: Dictionary = {} # pid -> CandyColor (-1 if none) @@ -380,11 +423,22 @@ func get_score(pid: int) -> int: # ── RPCs (stubs — HUD client handles visuals) ── +@rpc("authority", "call_remote", "unreliable") func sync_candy_badge(pid: int, count: int, mult: float) -> void: - pass + if pid == multiplayer.get_unique_id(): + if hud_stack_badge: + hud_stack_badge.text = "Stack: %d (x%.1f)" % [count, mult] +@rpc("authority", "call_remote", "unreliable") func sync_knock_result(attacker: int, target: int, candies: int) -> void: - pass + var local = multiplayer.get_unique_id() + if attacker == local or target == local: + if hud_knock_label and player_knocks.has(local): + hud_knock_label.text = "🥊 Knocks: %d" % player_knocks[local] +@rpc("authority", "call_remote", "unreliable") func sync_ghost_active(pid: int, active_on: bool) -> void: - pass + if pid == multiplayer.get_unique_id(): + if hud_ghost_label and player_ghosts.has(pid): + hud_ghost_label.text = "👻 Ghosts: %d" % player_ghosts[pid] +