diff --git a/src/game/game.gd b/src/game/game.gd index 8c92278..2d2aaf9 100644 --- a/src/game/game.gd +++ b/src/game/game.gd @@ -79,6 +79,9 @@ func _unload_content() -> void: func _finish_scene_load(instance: Node) -> void: + # Unpause in case the previous scene was paused. + get_tree().paused = false + content.add_child(instance) instance.reparent(content) diff --git a/src/ui/menus/pause_menu/pause_menu.gd b/src/ui/menus/pause_menu/pause_menu.gd index 6508510..08bcd5c 100644 --- a/src/ui/menus/pause_menu/pause_menu.gd +++ b/src/ui/menus/pause_menu/pause_menu.gd @@ -10,8 +10,7 @@ var _freeze_input := false @onready var end_game_confirm: CenterContainer = %EndGameConfirm @onready var settings_container: MarginContainer = %SettingsContainer -@onready var transition_animation: AnimationPlayer = %TransitionAnimation - +@onready var world: World = get_tree().get_first_node_in_group(World.group) @onready var game: Game = get_tree().get_first_node_in_group(Game.group) @@ -65,9 +64,5 @@ func cancel_end_game() -> void: end_game_confirm.hide() -func _return_to_title() -> void: - game.queue_scene(TitleScreen.SCENE) - - func confirm_end_game() -> void: - transition_animation.play("fade_to_black") + world.fade_to_title() diff --git a/src/ui/menus/pause_menu/pause_menu.tscn b/src/ui/menus/pause_menu/pause_menu.tscn index a6ebf7b..1e829af 100644 --- a/src/ui/menus/pause_menu/pause_menu.tscn +++ b/src/ui/menus/pause_menu/pause_menu.tscn @@ -1,84 +1,9 @@ -[gd_scene load_steps=7 format=3 uid="uid://byvjsvavbg5xe"] +[gd_scene load_steps=4 format=3 uid="uid://byvjsvavbg5xe"] [ext_resource type="FontFile" uid="uid://b6gxwgomstkgu" path="res://assets/fonts/Geo/Geo-Italic.ttf" id="1_4nw1f"] [ext_resource type="Script" path="res://src/ui/menus/pause_menu/pause_menu.gd" id="1_rd0j2"] [ext_resource type="PackedScene" uid="uid://d3eaqw2rdurct" path="res://src/ui/menus/settings_menu/settings_menu.tscn" id="2_kjr35"] -[sub_resource type="Animation" id="Animation_qmmn2"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("TransitionAnimation/TransitionShade:color") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Color(0, 0, 0, 0)] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("TransitionAnimation/TransitionShade:visible") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} - -[sub_resource type="Animation" id="Animation_rq4bw"] -resource_name = "fade_to_black" -length = 0.6 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("TransitionAnimation/TransitionShade:color") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.6), -"transitions": PackedFloat32Array(1.618, 1), -"update": 0, -"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)] -} -tracks/1/type = "method" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath(".") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0.6), -"transitions": PackedFloat32Array(1), -"values": [{ -"args": [], -"method": &"_return_to_title" -}] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("TransitionAnimation/TransitionShade:visible") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} - -[sub_resource type="AnimationLibrary" id="AnimationLibrary_7b7fo"] -_data = { -"RESET": SubResource("Animation_qmmn2"), -"fade_to_black": SubResource("Animation_rq4bw") -} - [node name="PauseMenu" type="Control"] process_mode = 3 layout_mode = 3 @@ -252,21 +177,6 @@ size_flags_horizontal = 3 theme_type_variation = &"AlertButton" text = "PAUSE_END" -[node name="TransitionAnimation" type="AnimationPlayer" parent="."] -unique_name_in_owner = true -libraries = { -"": SubResource("AnimationLibrary_7b7fo") -} - -[node name="TransitionShade" type="ColorRect" parent="TransitionAnimation"] -visible = false -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -color = Color(0, 0, 0, 0) - [connection signal="pressed" from="MarginContainer/MenuList/ResumeButton" to="." method="resume"] [connection signal="pressed" from="MarginContainer/MenuList/SettingsButton" to="." method="settings"] [connection signal="pressed" from="MarginContainer/MenuList/EndGameButton" to="." method="end_game"] diff --git a/src/ui/menus/title_screen/title_screen.gd b/src/ui/menus/title_screen/title_screen.gd index fd02f34..ceb8e4d 100644 --- a/src/ui/menus/title_screen/title_screen.gd +++ b/src/ui/menus/title_screen/title_screen.gd @@ -19,6 +19,10 @@ const SCENE := "res://src/ui/menus/title_screen/title_screen.tscn" @onready var game: Game = get_tree().get_first_node_in_group(Game.group) +func _ready() -> void: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + + func play_chime() -> void: game.sfx.chime.play() diff --git a/src/ui/menus/title_screen/title_screen.tscn b/src/ui/menus/title_screen/title_screen.tscn index 4257ba9..1e75ea7 100644 --- a/src/ui/menus/title_screen/title_screen.tscn +++ b/src/ui/menus/title_screen/title_screen.tscn @@ -18,6 +18,21 @@ ssil_intensity = 0.4 glow_enabled = true glow_intensity = 2.0 +[sub_resource type="Animation" id="Animation_vci0b"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(-0.785398, -3.14159, 0)] +} + [sub_resource type="Animation" id="Animation_bby3k"] resource_name = "rotate" length = 180.0 @@ -35,21 +50,6 @@ tracks/0/keys = { "values": [Vector3(-0.785398, 0, 0), Vector3(-0.785398, 6.28319, 0)] } -[sub_resource type="Animation" id="Animation_vci0b"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath(".:rotation") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector3(-0.785398, -3.14159, 0)] -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_g0lq7"] _data = { "RESET": SubResource("Animation_vci0b"), @@ -1372,7 +1372,7 @@ environment = SubResource("Environment_ardux") transform = Transform3D(-0.5, 0, 0.866025, 0, 1, 0, -0.866025, 0, -0.5, 0, 0, 0) [node name="DirectionalLight3D" type="DirectionalLight3D" parent="SceneRoot/LightRotationRoot"] -transform = Transform3D(-1, -6.18172e-08, 6.18172e-08, 0, 0.707107, 0.707107, -8.74228e-08, 0.707107, -0.707107, 0, 0, 0) +transform = Transform3D(-1, 1.79264e-06, -1.79264e-06, 0, 0.707107, 0.707107, 2.53518e-06, 0.707107, -0.707107, 0, 0, 0) light_color = Color(0.95, 1, 0.989167, 1) light_energy = 1.2 @@ -1480,7 +1480,7 @@ grow_horizontal = 2 grow_vertical = 2 [node name="PressStart" type="Label" parent="Menu"] -modulate = Color(1, 1, 1, 0.0282702) +modulate = Color(1, 1, 1, 0.850113) layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 diff --git a/src/ui/shot_hud/winner_alert.tscn b/src/ui/shot_hud/winner_alert.tscn index c4c6864..0e76086 100644 --- a/src/ui/shot_hud/winner_alert.tscn +++ b/src/ui/shot_hud/winner_alert.tscn @@ -169,7 +169,7 @@ tracks/7/type = "value" tracks/7/imported = false tracks/7/enabled = true tracks/7/path = NodePath("CaptionLabel:rotation") -tracks/7/interp = 1 +tracks/7/interp = 3 tracks/7/loop_wrap = true tracks/7/keys = { "times": PackedFloat32Array(0), @@ -216,8 +216,8 @@ tracks/10/keys = { [sub_resource type="Animation" id="Animation_f8nc2"] resource_name = "play" -length = 6.0 -loop_mode = 1 +length = 5.0 +loop_mode = 2 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -364,6 +364,20 @@ tracks/11/keys = { "update": 0, "values": [-0.5, 1.5] } +tracks/12/type = "method" +tracks/12/imported = false +tracks/12/enabled = true +tracks/12/path = NodePath(".") +tracks/12/interp = 1 +tracks/12/loop_wrap = true +tracks/12/keys = { +"times": PackedFloat32Array(5), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"queue_free" +}] +} [sub_resource type="AnimationLibrary" id="AnimationLibrary_x18w1"] _data = { diff --git a/src/ui/world_ui.gd b/src/ui/world_ui.gd index d3ce947..f38f692 100644 --- a/src/ui/world_ui.gd +++ b/src/ui/world_ui.gd @@ -1,11 +1,11 @@ class_name WorldUI extends Control ## Container & accessor for the world UI. -const DEATH_ALERT_SCENE := preload("res://src/ui/shot_hud/death_alert.tscn") - const DEMO_CAMERA_GROUP := "DemoCamera" -@export var pause_scene := preload("res://src/ui/menus/pause_menu/pause_menu.tscn") +@export var pause_scene: PackedScene +@export var death_alert_scene: PackedScene +@export var winner_alert_scene: PackedScene var _prev_camera: Camera3D var _pre_death_camera: Camera3D @@ -14,6 +14,8 @@ var _pre_death_camera: Camera3D @onready var effect_container: Control = %EffectContainer @onready var pause_container: Control = %PauseContainer +@onready var world: World = $".." + func _unhandled_key_input(event: InputEvent) -> void: if event.is_action_pressed("pause"): @@ -28,7 +30,7 @@ func add_player_hud(hud: ShotHUD) -> void: func play_death_sequence() -> void: _pre_death_camera = get_viewport().get_camera_3d() hud_container.hide() - var alert := DEATH_ALERT_SCENE.instantiate() + var alert := death_alert_scene.instantiate() alert.tree_exiting.connect(_finish_death_sequence) effect_container.add_child(alert) @@ -38,6 +40,17 @@ func _finish_death_sequence() -> void: _pre_death_camera.make_current() +func play_winner_sequence() -> void: + hud_container.hide() + var alert := winner_alert_scene.instantiate() + alert.tree_exiting.connect(_finish_winner_sequence) + effect_container.add_child(alert) + + +func _finish_winner_sequence() -> void: + world.fade_to_title() + + func pause() -> void: # Switch to demo cam, if there is one. var democams: Array[Node] = get_tree().get_nodes_in_group(DEMO_CAMERA_GROUP) diff --git a/src/world/play_manager/play_manager.gd b/src/world/play_manager/play_manager.gd index fe23a7c..e177689 100644 --- a/src/world/play_manager/play_manager.gd +++ b/src/world/play_manager/play_manager.gd @@ -5,6 +5,10 @@ class_name PlayManager extends Resource @warning_ignore("unused_signal") signal turn_started(player: WorldPlayer) +## Emitted when a player has won the game +@warning_ignore("unused_signal") +signal winner(player: WorldPlayer) + ## List of game player instances @export var players: Array[WorldPlayer] = [] diff --git a/src/world/play_manager/round_robin_manager.gd b/src/world/play_manager/round_robin_manager.gd index b66d404..b15417e 100644 --- a/src/world/play_manager/round_robin_manager.gd +++ b/src/world/play_manager/round_robin_manager.gd @@ -26,4 +26,4 @@ func on_player_death(player: WorldPlayer) -> void: func on_win_condition() -> void: - pass # TODO + winner.emit(players[0]) diff --git a/src/world/world.gd b/src/world/world.gd index 38f0c30..81011ee 100644 --- a/src/world/world.gd +++ b/src/world/world.gd @@ -15,6 +15,10 @@ var _spawns_available: Array[Node3D] = [] @onready var level: Node3D = %Level @onready var ui: WorldUI = %UI +@onready var world_transition: AnimationPlayer = %WorldTransition + +@onready var game: Game = get_tree().get_first_node_in_group(Game.group) + static var group := "WorldGroup" @@ -29,6 +33,8 @@ func _ready() -> void: if not manager.players: push_warning("Warning: Starting game world with no players!") + manager.winner.connect(_on_winner) + func _random_spawn() -> Node3D: # Get random spawn point @@ -48,6 +54,20 @@ func _spawn_player(player: WorldPlayer) -> void: spawn_point.add_sibling(shot_setup) +func _on_winner(_player: WorldPlayer) -> void: + get_tree().paused = true + ui.play_winner_sequence() + # TODO announce winner? + + +func fade_to_title() -> void: + world_transition.play("fade_to_title") + + +func _load_title() -> void: + game.queue_scene(TitleScreen.SCENE) + + ## Instantiate and mantle the given level scene. ## ## This will free any currently-loaded level! diff --git a/src/world/world.tscn b/src/world/world.tscn index 39c03c4..ca03c00 100644 --- a/src/world/world.tscn +++ b/src/world/world.tscn @@ -1,19 +1,109 @@ -[gd_scene load_steps=8 format=3 uid="uid://cwnwcd8kushl3"] +[gd_scene load_steps=16 format=3 uid="uid://cwnwcd8kushl3"] [ext_resource type="Script" path="res://src/world/world.gd" id="1_ybjyx"] [ext_resource type="Script" path="res://src/player/world_player.gd" id="2_e743i"] +[ext_resource type="PackedScene" uid="uid://bm2o3mex10v11" path="res://levels/debug_level/debug_level.tscn" id="2_hn84b"] [ext_resource type="Script" path="res://src/ui/world_ui.gd" id="2_imewa"] -[ext_resource type="PackedScene" uid="uid://x2bqqlrnno28" path="res://levels/oneill/oneill.tscn" id="2_w576d"] [ext_resource type="Resource" uid="uid://crock3revdn73" path="res://src/player/debug_player.tres" id="3_pyw81"] +[ext_resource type="Resource" uid="uid://c1pnqsddvey3m" path="res://src/equipment/clubs/drivers/debug_driver.tres" id="5_28hal"] [ext_resource type="Script" path="res://src/world/play_manager/round_robin_manager.gd" id="5_h6mje"] +[ext_resource type="PackedScene" uid="uid://byvjsvavbg5xe" path="res://src/ui/menus/pause_menu/pause_menu.tscn" id="7_0gd42"] +[ext_resource type="PackedScene" uid="uid://biokiug3e0ipk" path="res://src/ui/shot_hud/death_alert.tscn" id="8_fuyxc"] +[ext_resource type="PackedScene" uid="uid://dwyy7tt3nose1" path="res://src/ui/shot_hud/winner_alert.tscn" id="9_lln1k"] + +[sub_resource type="Resource" id="Resource_mbhdy"] +script = ExtResource("2_e743i") +life = 3.0 +name = "DeadGfolfer" +color = Color(1, 0.439216, 0.439216, 1) +driver = ExtResource("5_28hal") +_balls = { +1: -1, +2: -1 +} [sub_resource type="Resource" id="Resource_rdjhi"] script = ExtResource("5_h6mje") -players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81")]) +players = Array[ExtResource("2_e743i")]([ExtResource("3_pyw81"), SubResource("Resource_mbhdy")]) + +[sub_resource type="Animation" id="Animation_ihq1m"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(0, 0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="Animation" id="Animation_0v2so"] +resource_name = "fade_to_black" +length = 0.8 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:color") +tracks/0/interp = 2 +tracks/0/loop_wrap = false +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.8), +"transitions": PackedFloat32Array(0.618, 1), +"update": 0, +"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/2/type = "method" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("%UI/..") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0.8), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"_load_title" +}] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_s6tn7"] +_data = { +"RESET": SubResource("Animation_ihq1m"), +"fade_to_title": SubResource("Animation_0v2so") +} [node name="World" type="Node" groups=["WorldGroup"]] script = ExtResource("1_ybjyx") -initial_level = ExtResource("2_w576d") +initial_level = ExtResource("2_hn84b") manager = SubResource("Resource_rdjhi") [node name="Level" type="Node3D" parent="."] @@ -29,6 +119,9 @@ grow_horizontal = 2 grow_vertical = 2 mouse_filter = 1 script = ExtResource("2_imewa") +pause_scene = ExtResource("7_0gd42") +death_alert_scene = ExtResource("8_fuyxc") +winner_alert_scene = ExtResource("9_lln1k") [node name="HUDContainer" type="Control" parent="UI"] unique_name_in_owner = true @@ -59,3 +152,21 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 1 + +[node name="Blackout" type="ColorRect" parent="UI"] +process_mode = 3 +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 0) + +[node name="WorldTransition" type="AnimationPlayer" parent="UI/Blackout"] +unique_name_in_owner = true +libraries = { +"": SubResource("AnimationLibrary_s6tn7") +}