generated from krampus/template-godot4
Added practice mode
This commit is contained in:
parent
a5bbb098c0
commit
ddef4c8736
|
@ -31,6 +31,9 @@ DM_PLAYERS,Gfolfers
|
|||
DM_ADD_PLAYER,"Add a Gfolfer"
|
||||
DM_NAME_PLACEHOLDER,"Enter a name"
|
||||
,
|
||||
PRACTICE_HEADING,"Practice your GFOLFing"
|
||||
PRACTICE_MAP,"Select a Map"
|
||||
,
|
||||
PAUSE_HEADING,Paused
|
||||
PAUSE_RESUME,Resume
|
||||
PAUSE_SETTINGS,Settings
|
||||
|
|
|
|
@ -1,9 +1,11 @@
|
|||
[gd_resource type="Resource" script_class="Level" load_steps=3 format=3 uid="uid://cfsy1nlfo4inx"]
|
||||
[gd_resource type="Resource" script_class="Level" load_steps=4 format=3 uid="uid://cfsy1nlfo4inx"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://x2bqqlrnno28" path="res://levels/oneill/oneill.tscn" id="1_431yv"]
|
||||
[ext_resource type="Texture2D" uid="uid://dlq6b8frq21o2" path="res://levels/oneill/preview.jpg" id="1_n552e"]
|
||||
[ext_resource type="Script" path="res://src/world/level/level.gd" id="2_fnj1e"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_fnj1e")
|
||||
scene = ExtResource("1_431yv")
|
||||
level_name = "MAP_ONEILL"
|
||||
preview = ExtResource("1_n552e")
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dlq6b8frq21o2"
|
||||
path="res://.godot/imported/preview.jpg-15d3a679d46e9934ca032ccdfbdfe6af.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://levels/oneill/preview.jpg"
|
||||
dest_files=["res://.godot/imported/preview.jpg-15d3a679d46e9934ca032ccdfbdfe6af.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
|
@ -119,7 +119,6 @@ _data = {
|
|||
[node name="Game" type="Node" groups=["GameGroup"]]
|
||||
process_mode = 3
|
||||
script = ExtResource("1_4qa87")
|
||||
start_scene = "res://src/world/world.tscn"
|
||||
|
||||
[node name="RootControl" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
extends PanelContainer
|
||||
|
||||
const WORLD_SCENE_PATH := "res://src/world/world.tscn"
|
||||
|
||||
const RANDOM_PLAYER_COLORS := [
|
||||
Color.LIGHT_CORAL,
|
||||
Color.GOLDENROD,
|
||||
|
@ -54,7 +52,7 @@ func start() -> void:
|
|||
world.manager = RoundRobinManager.new()
|
||||
world.manager.players = player_list
|
||||
world.initial_level = level.scene
|
||||
game.queue_scene(WORLD_SCENE_PATH).then(init_world)
|
||||
game.queue_scene(World.SCENE).then(init_world)
|
||||
|
||||
|
||||
## Returns the `Level` selected by the user if there is one, or `null` if no level is selected.
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
extends PanelContainer
|
||||
|
||||
@export var practice_player: WorldPlayer
|
||||
|
||||
@onready var map_select: ItemList = %MapSelect
|
||||
|
||||
@onready var start_button: Button = %Start
|
||||
|
||||
@onready var game: Game = get_tree().get_first_node_in_group(Game.group)
|
||||
|
||||
|
||||
func play_chime() -> void:
|
||||
game.sfx.chime.play()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Populate map selection
|
||||
for level: Level in Level.catalog.levels:
|
||||
map_select.add_item(level.level_name, level.preview)
|
||||
|
||||
check_start_conditions()
|
||||
|
||||
|
||||
## Close menu without starting game.
|
||||
func cancel() -> void:
|
||||
queue_free()
|
||||
|
||||
|
||||
## Start with the current game configuration.
|
||||
func start() -> void:
|
||||
var manager := PracticeManager.new()
|
||||
manager.players = [practice_player]
|
||||
var level := selected_level()
|
||||
var init_world := func(world: World) -> void:
|
||||
world.manager = manager
|
||||
world.initial_level = level.scene
|
||||
game.queue_scene(World.SCENE).then(init_world)
|
||||
|
||||
|
||||
## Returns the `Level` selected by the user if there is one, or `null` if no level is selected.
|
||||
func selected_level() -> Level:
|
||||
var selections := map_select.get_selected_items()
|
||||
if selections:
|
||||
return Level.catalog.levels[selections[0]]
|
||||
return null
|
||||
|
||||
|
||||
func _can_start() -> bool:
|
||||
return selected_level() != null
|
||||
|
||||
|
||||
## Check if the game can be started with the current selection,
|
||||
## and set the start button status appropriately.
|
||||
func check_start_conditions() -> void:
|
||||
start_button.disabled = not _can_start()
|
|
@ -0,0 +1,197 @@
|
|||
[gd_scene load_steps=11 format=3 uid="uid://5soelwtn4v34"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/ui/menus/title_screen/practice_setup/practice_setup.gd" id="1_jgggo"]
|
||||
[ext_resource type="Resource" uid="uid://c1pnqsddvey3m" path="res://src/equipment/clubs/drivers/debug_driver.tres" id="2_47376"]
|
||||
[ext_resource type="Resource" uid="uid://ck17u5yn6k0bi" path="res://src/equipment/clubs/irons/debug_iron.tres" id="3_veaoo"]
|
||||
[ext_resource type="Resource" uid="uid://dagld0q5krapu" path="res://src/equipment/clubs/putters/debug_putter.tres" id="4_mixgr"]
|
||||
[ext_resource type="Script" path="res://src/player/world_player.gd" id="5_btf7p"]
|
||||
[ext_resource type="Resource" uid="uid://dthtc1no2c4wy" path="res://src/equipment/clubs/wedges/debug_wedge.tres" id="6_8yfm7"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_4ls7o"]
|
||||
script = ExtResource("5_btf7p")
|
||||
life = 100.0
|
||||
name = "Practice Gfolfer"
|
||||
color = Color(0.955, 0.7, 1, 1)
|
||||
driver = ExtResource("2_47376")
|
||||
iron = ExtResource("3_veaoo")
|
||||
wedge = ExtResource("6_8yfm7")
|
||||
putter = ExtResource("4_mixgr")
|
||||
_balls = {
|
||||
1: -1,
|
||||
2: -1,
|
||||
3: -1,
|
||||
4: -1,
|
||||
5: -1
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_x4wqc"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:disabled")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath(".:modulate")
|
||||
tracks/1/interp = 2
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_560ro"]
|
||||
resource_name = "fade_out"
|
||||
length = 0.6
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:modulate")
|
||||
tracks/0/interp = 2
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.0666667, 0.133333, 0.2, 0.266667, 0.333333, 0.4, 0.466667, 0.533333, 0.6),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0), Color(1, 1, 1, 0.5), Color(1, 1, 1, 0), Color(1, 1, 1, 0.25), Color(1, 1, 1, 0), Color(1, 1, 1, 0.125), Color(1, 1, 1, 0)]
|
||||
}
|
||||
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, 0.6),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"values": [{
|
||||
"args": [],
|
||||
"method": &"play_chime"
|
||||
}, {
|
||||
"args": [],
|
||||
"method": &"start"
|
||||
}]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath(".:disabled")
|
||||
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_s1eyj"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_x4wqc"),
|
||||
"fade_out": SubResource("Animation_560ro")
|
||||
}
|
||||
|
||||
[node name="PracticeSetup" type="PanelContainer"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_jgggo")
|
||||
practice_player = SubResource("Resource_4ls7o")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 32
|
||||
theme_override_constants/margin_top = 32
|
||||
theme_override_constants/margin_right = 32
|
||||
theme_override_constants/margin_bottom = 80
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"HeaderXLarge"
|
||||
text = "PRACTICE_HEADING"
|
||||
|
||||
[node name="MapSelectContainer" type="PanelContainer" parent="MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer/MapSelectContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 16
|
||||
theme_override_constants/margin_top = 16
|
||||
theme_override_constants/margin_right = 16
|
||||
theme_override_constants/margin_bottom = 16
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"HeaderLarge"
|
||||
text = "PRACTICE_MAP"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="MapSelect" type="ItemList" parent="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 130)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/v_separation = 32
|
||||
theme_override_constants/h_separation = 32
|
||||
max_columns = 8
|
||||
icon_mode = 0
|
||||
fixed_icon_size = Vector2i(64, 64)
|
||||
|
||||
[node name="SouthEast" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 8
|
||||
theme_override_constants/margin_left = 16
|
||||
theme_override_constants/margin_top = 16
|
||||
theme_override_constants/margin_right = 32
|
||||
theme_override_constants/margin_bottom = 16
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="SouthEast"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 16
|
||||
|
||||
[node name="Cancel" type="Button" parent="SouthEast/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"CancelButton"
|
||||
text = "UI_CANCEL"
|
||||
|
||||
[node name="Start" type="Button" parent="SouthEast/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"AlertButton"
|
||||
text = "UI_START"
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="SouthEast/HBoxContainer/Start"]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_s1eyj")
|
||||
}
|
||||
|
||||
[connection signal="item_selected" from="MarginContainer/VBoxContainer/MapSelectContainer/MarginContainer/VBoxContainer/MapSelect" to="." method="check_start_conditions" unbinds=1]
|
||||
[connection signal="pressed" from="SouthEast/HBoxContainer/Cancel" to="." method="cancel"]
|
||||
[connection signal="pressed" from="SouthEast/HBoxContainer/Start" to="SouthEast/HBoxContainer/Start/AnimationPlayer" method="play" binds= ["fade_out"]]
|
|
@ -5,6 +5,7 @@ const SCENE := "res://src/ui/menus/title_screen/title_screen.tscn"
|
|||
@export var title_crawl_scene: PackedScene
|
||||
@export var settings_scene: PackedScene
|
||||
@export var local_deathmatch_setup_scene: PackedScene
|
||||
@export var practice_setup_scene: PackedScene
|
||||
|
||||
@onready var menu: Control = %Menu
|
||||
@onready var settings_container: MarginContainer = %SettingsContainer
|
||||
|
@ -84,3 +85,10 @@ func _open_local_deathmatch_setup() -> void:
|
|||
deathmatch_setup_container.add_child(instance)
|
||||
instance.tree_exited.connect(_unhide)
|
||||
_hide()
|
||||
|
||||
|
||||
func _open_practice_setup() -> void:
|
||||
var instance: Control = practice_setup_scene.instantiate()
|
||||
deathmatch_setup_container.add_child(instance)
|
||||
instance.tree_exited.connect(_unhide)
|
||||
_hide()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=86 format=3 uid="uid://7fsgocmdas7i"]
|
||||
[gd_scene load_steps=87 format=3 uid="uid://7fsgocmdas7i"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/ui/menus/title_screen/title_screen.gd" id="1_2qtlb"]
|
||||
[ext_resource type="Texture2D" uid="uid://880x5n8j3b5l" path="res://assets/logo/title.png" id="1_pm82i"]
|
||||
|
@ -6,6 +6,7 @@
|
|||
[ext_resource type="Texture2D" uid="uid://clesl8lljs6of" path="res://assets/logo/subtitle.png" id="2_y0ulk"]
|
||||
[ext_resource type="PackedScene" uid="uid://ccx2u5oli6men" path="res://src/ui/menus/title_screen/deathmatch_setup/deathmatch_setup.tscn" id="3_bo4ty"]
|
||||
[ext_resource type="Material" uid="uid://dpsmjlhjpc7vs" path="res://assets/materials/basic_ball_material.tres" id="5_5q83g"]
|
||||
[ext_resource type="PackedScene" uid="uid://5soelwtn4v34" path="res://src/ui/menus/title_screen/practice_setup/practice_setup.tscn" id="5_hws1o"]
|
||||
[ext_resource type="PackedScene" uid="uid://cqu315hviu72n" path="res://src/ui/menus/title_screen/title_crawl.tscn" id="7_r26eu"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_ardux"]
|
||||
|
@ -1362,6 +1363,7 @@ script = ExtResource("1_2qtlb")
|
|||
title_crawl_scene = ExtResource("7_r26eu")
|
||||
settings_scene = ExtResource("2_g5q2v")
|
||||
local_deathmatch_setup_scene = ExtResource("3_bo4ty")
|
||||
practice_setup_scene = ExtResource("5_hws1o")
|
||||
|
||||
[node name="SceneRoot" type="Node3D" parent="."]
|
||||
|
||||
|
@ -1480,7 +1482,7 @@ grow_horizontal = 2
|
|||
grow_vertical = 2
|
||||
|
||||
[node name="PressStart" type="Label" parent="Menu"]
|
||||
modulate = Color(1, 1, 1, 0.850113)
|
||||
modulate = Color(1, 1, 1, 0.936746)
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
|
@ -1576,7 +1578,6 @@ text = "TITLE_ROGUELIKE"
|
|||
[node name="Practice" type="Button" parent="Menu/SingleplayerMenu"]
|
||||
layout_mode = 2
|
||||
theme_type_variation = &"PauseMenuButton"
|
||||
disabled = true
|
||||
text = "TITLE_PRACTICE"
|
||||
|
||||
[node name="Back" type="Button" parent="Menu/SingleplayerMenu"]
|
||||
|
@ -1743,6 +1744,7 @@ autostart = true
|
|||
[connection signal="pressed" from="Menu/MainMenu/MultiPlayer" to="." method="_to_multi_player"]
|
||||
[connection signal="pressed" from="Menu/MainMenu/Settings" to="." method="_open_settings"]
|
||||
[connection signal="pressed" from="Menu/MainMenu/Quit" to="Menu/MainMenu/Quit/AnimationPlayer" method="play" binds= ["fade_out"]]
|
||||
[connection signal="pressed" from="Menu/SingleplayerMenu/Practice" to="." method="_open_practice_setup"]
|
||||
[connection signal="pressed" from="Menu/SingleplayerMenu/Back" to="." method="_to_main_menu"]
|
||||
[connection signal="pressed" from="Menu/MultiplayerMenu/LocalMultiplayer" to="." method="_to_local_multi"]
|
||||
[connection signal="pressed" from="Menu/MultiplayerMenu/NetMultiplayer" to="." method="_to_network_multi"]
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
class_name PracticeManager extends PlayManager
|
||||
## A single player can just kind of chill out and vibe...
|
||||
|
||||
var player: WorldPlayer:
|
||||
get:
|
||||
return players[0]
|
||||
set(value):
|
||||
players[0] = value
|
||||
|
||||
|
||||
func on_initialization() -> void:
|
||||
# Set first player as active
|
||||
player.shot_setup.phase = ShotSetup.Phase.AIM
|
||||
|
||||
|
||||
func on_turn_finished(source: ShotSetup) -> void:
|
||||
player.shot_setup.queue_restart()
|
||||
turn_started.emit(player)
|
||||
|
||||
|
||||
func on_player_death(player: WorldPlayer) -> void:
|
||||
# TODO game over screen
|
||||
winner.emit(player)
|
|
@ -4,6 +4,8 @@ class_name World extends Node
|
|||
## A world contains player(s) and the active level, manages player states,
|
||||
## and transitions between active levels.
|
||||
|
||||
const SCENE := "res://src/world/world.tscn"
|
||||
|
||||
@export var initial_level: PackedScene
|
||||
|
||||
@export var manager: PlayManager
|
||||
|
|
Loading…
Reference in New Issue