diff --git a/Scenes/demo.tscn b/Scenes/demo.tscn index 7d96a85..a2073f7 100644 --- a/Scenes/demo.tscn +++ b/Scenes/demo.tscn @@ -11,7 +11,6 @@ [ext_resource type="Texture2D" uid="uid://dle4xt8upfg42" path="res://Shapes/Square.svg" id="4_qdju7"] [ext_resource type="Script" uid="uid://d2y578q176xkm" path="res://Scripts/high_stage.gd" id="5_high_stage"] [ext_resource type="PackedScene" uid="uid://dao1hqwdldnlw" path="res://Scenes/demo_result_screen.tscn" id="6_a1i4p"] -[ext_resource type="Texture2D" uid="uid://f5ertr28h6kq" path="res://Shapes/feather.svg" id="6_feather"] [ext_resource type="Script" uid="uid://cxd17lrphypsv" path="res://Scripts/game_camera.gd" id="7_camera"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_f2jw5"] @@ -99,10 +98,6 @@ viewport_path = NodePath("HigherThanPlayerA") [sub_resource type="ViewportTexture" id="ViewportTexture_high_b"] viewport_path = NodePath("HigherThanPlayerB") -[sub_resource type="FontVariation" id="FontVariation_countdown"] -base_font = ExtResource("4_font") -variation_transform = Transform2D(1, 0.15, 0, 1, 0, 0) - [sub_resource type="LabelSettings" id="LabelSettings_tcdmn"] font = ExtResource("4_font") font_size = 56 @@ -111,6 +106,9 @@ font_size = 56 font = ExtResource("4_font") font_size = 36 +[sub_resource type="FontVariation" id="FontVariation_countdown"] +base_font = ExtResource("4_font") +variation_transform = Transform2D(1, 0.15, 0, 1, 0, 0) [node name="DemoMain" type="Control" unique_id=1296044060] layout_mode = 3 @@ -384,29 +382,6 @@ script = ExtResource("5_high_stage") [node name="HUD" type="CanvasLayer" parent="." unique_id=1320686328] layer = 10 -[node name="PregameCountdown" type="Label" parent="HUD" unique_id=1745412148] -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = -36.0 -offset_top = -214.0 -offset_right = 34.0 -offset_bottom = -77.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_colors/font_color = Color(1, 0.7058824, 0.09803922, 1) -theme_override_colors/font_shadow_color = Color(1.0039686, 0.33479407, 0, 0.98039216) -theme_override_colors/font_outline_color = Color(1, 0.7058824, 0.21568628, 1) -theme_override_constants/shadow_offset_x = 6 -theme_override_constants/shadow_offset_y = 4 -theme_override_fonts/font = SubResource("FontVariation_countdown") -theme_override_font_sizes/font_size = 85 -text = "3" -horizontal_alignment = 1 -script = ExtResource("2_countdown") - [node name="TimeLabel" type="Label" parent="HUD" unique_id=985672380] anchors_preset = 5 anchor_left = 0.5 @@ -445,102 +420,12 @@ position = Vector2(91, 112) [node name="ScreenA_Health" type="Node2D" parent="HUD" unique_id=261805975] position = Vector2(340, 112) -[node name="Icon0" type="TextureRect" parent="HUD/ScreenA_Health" unique_id=1452463056] -offset_left = -87.0 -offset_top = -15.0 -offset_right = -57.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon1" type="TextureRect" parent="HUD/ScreenA_Health" unique_id=1084471247] -offset_left = -51.0 -offset_top = -15.0 -offset_right = -21.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon2" type="TextureRect" parent="HUD/ScreenA_Health" unique_id=1030381543] -offset_left = -15.0 -offset_top = -15.0 -offset_right = 15.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon3" type="TextureRect" parent="HUD/ScreenA_Health" unique_id=2131930762] -offset_left = 21.0 -offset_top = -15.0 -offset_right = 51.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon4" type="TextureRect" parent="HUD/ScreenA_Health" unique_id=21353598] -offset_left = 57.0 -offset_top = -15.0 -offset_right = 87.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - [node name="ScreenB_Energy" parent="HUD" unique_id=1762839106 instance=ExtResource("3_energy")] position = Vector2(955, 112) [node name="ScreenB_Health" type="Node2D" parent="HUD" unique_id=1056993462] position = Vector2(812, 112) -[node name="Icon0" type="TextureRect" parent="HUD/ScreenB_Health" unique_id=1352515971] -offset_left = -87.0 -offset_top = -15.0 -offset_right = -57.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon1" type="TextureRect" parent="HUD/ScreenB_Health" unique_id=359298265] -offset_left = -51.0 -offset_top = -15.0 -offset_right = -21.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon2" type="TextureRect" parent="HUD/ScreenB_Health" unique_id=1213276918] -offset_left = -15.0 -offset_top = -15.0 -offset_right = 15.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon3" type="TextureRect" parent="HUD/ScreenB_Health" unique_id=425014722] -offset_left = 21.0 -offset_top = -15.0 -offset_right = 51.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - -[node name="Icon4" type="TextureRect" parent="HUD/ScreenB_Health" unique_id=457022701] -offset_left = 57.0 -offset_top = -15.0 -offset_right = 87.0 -offset_bottom = 15.0 -texture = ExtResource("6_feather") -expand_mode = 1 -stretch_mode = 5 - [node name="NameLabelA" type="Label" parent="HUD" unique_id=599978977] anchors_preset = 5 anchor_left = 0.5 @@ -575,6 +460,29 @@ label_settings = SubResource("LabelSettings_tcdmn") horizontal_alignment = 1 vertical_alignment = 1 +[node name="PregameCountdown" type="Label" parent="HUD" unique_id=1745412148] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -36.0 +offset_top = -214.0 +offset_right = 34.0 +offset_bottom = -77.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(1, 0.7058824, 0.09803922, 1) +theme_override_colors/font_shadow_color = Color(1.0039686, 0.33479407, 0, 0.98039216) +theme_override_colors/font_outline_color = Color(1, 0.7058824, 0.21568628, 1) +theme_override_constants/shadow_offset_x = 6 +theme_override_constants/shadow_offset_y = 4 +theme_override_fonts/font = SubResource("FontVariation_countdown") +theme_override_font_sizes/font_size = 85 +text = "3" +horizontal_alignment = 1 +script = ExtResource("2_countdown") + [node name="DemoRenderer" type="Node" parent="." unique_id=295691669 node_paths=PackedStringArray("stage_a", "stage_b", "time_label", "phase_label", "pregame_countdown", "screen_a_energy", "screen_a_health", "screen_b_energy", "screen_b_health", "stage_layer", "high_stage_a", "high_stage_b", "camera_a", "camera_b")] script = ExtResource("1_demo") stage_a = NodePath("../ScreenA/SubViewport/StageA") diff --git a/Scenes/energy_label.tscn b/Scenes/energy_label.tscn index a35c3c2..8c3ff00 100644 --- a/Scenes/energy_label.tscn +++ b/Scenes/energy_label.tscn @@ -32,7 +32,8 @@ text = "0" label_settings = SubResource("LabelSettings_6srxx") [node name="LimitationLabel" type="Label" parent="." unique_id=369878157] -offset_right = 40.0 +offset_left = 84.0 +offset_right = 124.0 offset_bottom = 23.0 text = "/0" label_settings = SubResource("LabelSettings_46qr4") diff --git a/Scripts/audio.gd b/Scripts/audio.gd index 07fb44c..5b8a990 100644 --- a/Scripts/audio.gd +++ b/Scripts/audio.gd @@ -66,6 +66,9 @@ enum BGM { @export var sfx_pool_size := 8 @export var bgm_fade_out_time := 0.3125 +# sfx queue +var queued_sfx: Array[int] = [] + # the audio collection var _sfx_streams: Dictionary = {} var _bgm_playlists: Dictionary = {} @@ -131,6 +134,7 @@ func set_bgm(bgm: BGM) -> void: func play_sfx(sfx: SFX) -> AudioStreamPlayer: + queued_sfx.append(sfx as int) var stream := _sfx_streams.get(SFX.find_key(sfx)) as AudioStream if stream == null: return @@ -213,6 +217,8 @@ func set_phase_bgm(phase: int) -> void: set_bgm(BGM.GAMEPLAY_PHASE_4) 5: set_bgm(BGM.GAMEPLAY_PHASE_5) + _: + set_bgm(BGM.NONE) func _play_random_bgm_track(player: AudioStreamPlayer) -> void: diff --git a/Scripts/demo_renderer.gd b/Scripts/demo_renderer.gd index 68dabb9..75277ae 100644 --- a/Scripts/demo_renderer.gd +++ b/Scripts/demo_renderer.gd @@ -31,11 +31,13 @@ var _player_a: Node2D var _player_b: Node2D var _screens: Array = [] var _countdown_triggered: bool = false +var _current_phase: int = -2 var _phase_duration: Array = [] var _max_phase: int = 0 func _ready() -> void: + Audio.process_mode = Node.PROCESS_MODE_ALWAYS var game_data := GameData.new() _phase_duration = game_data.data.get("game_manager", {}).get("phase_duration", []) _max_phase = game_data.data.get("game_manager", {}).get("max_phase", _phase_duration.size()) @@ -81,6 +83,7 @@ func _ready() -> void: "prev_player": {}, "proxy": null, "loaded_skin_id": "", + "loaded_health_skin_id": "", "energy_label": screen_a_energy, "energy_value": 0, "health_root": screen_a_health, @@ -97,6 +100,7 @@ func _ready() -> void: "prev_player": {}, "proxy": null, "loaded_skin_id": "", + "loaded_health_skin_id": "", "energy_label": screen_b_energy, "energy_value": 0, "health_root": screen_b_health, @@ -122,11 +126,15 @@ func _identify_as_demo(nm: Node) -> void: func _on_demo_state_received(combined: Dictionary) -> void: var elapsed: float = combined.get("elapsed_time", 0.0) _update_time_display(elapsed) - _update_phase_display(combined.get("current_phase", 0)) + var new_phase: int = _compute_phase(elapsed) + if new_phase != _current_phase: + _current_phase = new_phase + _update_phase_display(_current_phase) if not _countdown_triggered and elapsed < 0.0: _countdown_triggered = true if pregame_countdown and pregame_countdown.has_method("play_countdown"): + Audio.play_sfx(Audio.SFX.PREGAME_COUNTDOWN) pregame_countdown.play_countdown() var screens: Array = combined.get("screens", []) @@ -174,6 +182,11 @@ func _apply_screen(screen: Dictionary, screen_data: Dictionary) -> void: _update_energy_hud(screen, energy, max_energy) _update_health_hud(screen, skin_id, max_health) _refresh_health_display(screen, health) + var queued_sfx = screen_data.get("queued_sfx", []) + for sfx_id in queued_sfx: + var sfx: Audio.SFX = sfx_id as Audio.SFX + if sfx != Audio.SFX.PREGAME_COUNTDOWN: + Audio.play_sfx(sfx) ## Recursively disables game logic callbacks on [param node] and its children. @@ -192,9 +205,12 @@ func _update_phase_display(phase: int) -> void: if not phase_label: return phase_label.text = "Phase %d" % phase + Audio.set_phase_bgm(phase) func _compute_phase(time: float) -> int: + if time <= 0: + return -1 for i in range(_max_phase): if time >= _phase_duration[i]: time -= _phase_duration[i] @@ -461,7 +477,8 @@ func _update_health_hud(screen: Dictionary, skin_id: String, max_health: int) -> return var need_rebuild: bool = ( - skin_id != screen.get("loaded_skin_id", "") or health_root.get_child_count() != max_health + skin_id != screen.get("loaded_health_skin_id", "") + or health_root.get_child_count() != max_health ) if not need_rebuild: if screen["health_icons"].is_empty(): @@ -469,6 +486,7 @@ func _update_health_hud(screen: Dictionary, skin_id: String, max_health: int) -> if child is TextureRect: screen["health_icons"].append(child) return + screen["loaded_health_skin_id"] = skin_id # Clear old icons for icon in screen["health_icons"]: diff --git a/Scripts/demo_result_screen.gd b/Scripts/demo_result_screen.gd index 443d715..a9434e4 100644 --- a/Scripts/demo_result_screen.gd +++ b/Scripts/demo_result_screen.gd @@ -173,6 +173,7 @@ func show_demo_results( health_icon.modulate.a = 1.0 health_icon_b.modulate.a = 1.0 + Audio.stop_all_sfx() Audio.set_bgm(Audio.BGM.RESULT_SCREEN) _fade_in(3.0) diff --git a/Scripts/game_manager.gd b/Scripts/game_manager.gd index acff99f..6f69c2c 100644 --- a/Scripts/game_manager.gd +++ b/Scripts/game_manager.gd @@ -489,7 +489,6 @@ func finish_game(state: int = 0, authoritative_stats: Dictionary = {}) -> void: "distance_traveled": player.distance_traveled, "survival_time": survival_time, "remaining_health": health, - "trap_count": authoritative_stats.get("trap_count", 0), }, state ) diff --git a/Scripts/network/state_serializer.gd b/Scripts/network/state_serializer.gd index 4dffc0f..008e0e9 100644 --- a/Scripts/network/state_serializer.gd +++ b/Scripts/network/state_serializer.gd @@ -61,6 +61,8 @@ func _collect_state() -> Dictionary: var player_node: Node = ( game_manager.player if game_manager and "player" in game_manager else null ) + var queued_sfx := Audio.queued_sfx if Audio else [] + Audio.queued_sfx = [] return { "peer_id": multiplayer.get_unique_id(), "tick": Engine.get_physics_frames(), @@ -68,6 +70,7 @@ func _collect_state() -> Dictionary: "max_energy_cap": _collect_max_energy_cap(), "traps": _serialize_traps(), "energy_balls": _serialize_energy_balls(), + "queued_sfx": queued_sfx } @@ -78,7 +81,7 @@ func _serialize_player(p: Node) -> Dictionary: var energy := 0 var ball_count := 0 - var total_energy_spent := 0 + var total_energy_spent = game_manager.total_energy_spent if game_manager else 0 if game_manager: energy = game_manager.get("energy_amount") if "energy_amount" in game_manager else 0 ball_count = ( diff --git a/Scripts/result_screen.gd b/Scripts/result_screen.gd index aabb112..24206fa 100644 --- a/Scripts/result_screen.gd +++ b/Scripts/result_screen.gd @@ -42,10 +42,10 @@ func show_results(results: Dictionary, state: int) -> void: ] var opponent_energy_balls := int(results.get("opponent_energy_balls", -1)) - if opponent_energy_balls >= 0: - # This row is multiplayer-only; single-player leaves opponent_energy_balls at -1. - names.insert(3, "Opponent Energy Balls") - values.insert(3, str(opponent_energy_balls)) + # if opponent_energy_balls >= 0: + # # This row is multiplayer-only; single-player leaves opponent_energy_balls at -1. + # names.insert(3, "Opponent Energy Balls") + # values.insert(3, str(opponent_energy_balls)) if state == 0: title_label.text = "RESULT"