feat: Introduce comprehensive settings management with UI for video, audio, and remappable controls.

This commit is contained in:
Yogi Wiguna
2026-03-10 17:04:01 +08:00
parent c895e466b5
commit d53e4601e4
5 changed files with 382 additions and 58 deletions
+4
View File
@@ -69,24 +69,28 @@ move_north={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
] ]
} }
move_south={ move_south={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
] ]
} }
move_west={ move_west={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
] ]
} }
move_east={ move_east={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
] ]
} }
move_northeast={ move_northeast={
+228 -46
View File
@@ -37,6 +37,23 @@ corner_radius_bottom_left = 10
font_size = 24 font_size = 24
font_color = Color(0.9, 0.9, 0.9, 1) font_color = Color(0.9, 0.9, 0.9, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_section_header"]
content_margin_left = 15.0
content_margin_top = 5.0
content_margin_right = 15.0
content_margin_bottom = 5.0
bg_color = Color(0.2, 0.5, 0.8, 0.3)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="LabelSettings" id="LabelSettings_section"]
font_size = 18
font_color = Color(0.4, 0.9, 1, 1)
outline_size = 2
outline_color = Color(0, 0, 0, 1)
[node name="SettingsMenu" type="CanvasLayer" unique_id=1319114632] [node name="SettingsMenu" type="CanvasLayer" unique_id=1319114632]
layer = 100 layer = 100
script = ExtResource("1_script") script = ExtResource("1_script")
@@ -140,6 +157,62 @@ label_settings = SubResource("LabelSettings_heading")
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
[node name="Resolution" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox" unique_id=100000100]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/Resolution" unique_id=100000101]
layout_mode = 2
size_flags_horizontal = 3
text = "Resolution"
label_settings = SubResource("LabelSettings_heading")
[node name="ResolutionBtn" type="OptionButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/Resolution" unique_id=100000102]
unique_name_in_owner = true
custom_minimum_size = Vector2(240, 40)
layout_mode = 2
[node name="MSAA" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox" unique_id=100000103]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/MSAA" unique_id=100000104]
layout_mode = 2
size_flags_horizontal = 3
text = "Anti-Aliasing (MSAA)"
label_settings = SubResource("LabelSettings_heading")
[node name="MSAABtn" type="OptionButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/MSAA" unique_id=100000105]
unique_name_in_owner = true
custom_minimum_size = Vector2(240, 40)
layout_mode = 2
[node name="Shadows" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox" unique_id=100000106]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/Shadows" unique_id=100000107]
layout_mode = 2
size_flags_horizontal = 3
text = "Shadow Quality"
label_settings = SubResource("LabelSettings_heading")
[node name="ShadowBtn" type="OptionButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/Shadows" unique_id=100000108]
unique_name_in_owner = true
custom_minimum_size = Vector2(240, 40)
layout_mode = 2
[node name="FPSCap" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox" unique_id=100000109]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/FPSCap" unique_id=100000110]
layout_mode = 2
size_flags_horizontal = 3
text = "Max FPS Cap"
label_settings = SubResource("LabelSettings_heading")
[node name="FPSCapBtn" type="OptionButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Video/VBox/FPSCap" unique_id=100000111]
unique_name_in_owner = true
custom_minimum_size = Vector2(240, 40)
layout_mode = 2
[node name="Audio" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer" unique_id=1585166620] [node name="Audio" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer" unique_id=1585166620]
visible = false visible = false
layout_mode = 2 layout_mode = 2
@@ -199,123 +272,232 @@ metadata/_tab_index = 2
[node name="VBox" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls" unique_id=1592525164] [node name="VBox" type="VBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls" unique_id=1592525164]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
theme_override_constants/separation = 10 theme_override_constants/separation = 15
[node name="P1" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=2065564199] [node name="ControllerToggleContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000001]
layout_mode = 2 layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P1" unique_id=85468293] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/ControllerToggleContainer" unique_id=100000002]
layout_mode = 2
size_flags_horizontal = 3
text = "ENABLE CONTROLLER (JOYSTICK)"
label_settings = SubResource("LabelSettings_heading")
[node name="UseControllerBtn" type="CheckButton" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/ControllerToggleContainer" unique_id=100000003]
unique_name_in_owner = true
layout_mode = 2
[node name="MovementSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000004]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MovementSection" unique_id=100000005]
layout_mode = 2
text = "MOVEMENT CONTROL"
label_settings = SubResource("LabelSettings_section")
[node name="MoveGrid" type="GridContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000006]
layout_mode = 2
theme_override_constants/h_separation = 20
theme_override_constants/v_separation = 10
columns = 2
[node name="UpLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000007]
layout_mode = 2
size_flags_horizontal = 3
text = "Move Up"
label_settings = SubResource("LabelSettings_heading")
[node name="MoveUpBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000008]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "W"
[node name="DownLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000009]
layout_mode = 2
size_flags_horizontal = 3
text = "Move Down"
label_settings = SubResource("LabelSettings_heading")
[node name="MoveDownBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000010]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "S"
[node name="LeftLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000011]
layout_mode = 2
size_flags_horizontal = 3
text = "Move Left"
label_settings = SubResource("LabelSettings_heading")
[node name="MoveLeftBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000012]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "A"
[node name="RightLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000013]
layout_mode = 2
size_flags_horizontal = 3
text = "Move Right"
label_settings = SubResource("LabelSettings_heading")
[node name="MoveRightBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/MoveGrid" unique_id=100000014]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "D"
[node name="PowerUpSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000015]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpSection" unique_id=100000016]
layout_mode = 2
text = "POWER UP CONTROL"
label_settings = SubResource("LabelSettings_section")
[node name="PowerUpGrid" type="GridContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000017]
layout_mode = 2
theme_override_constants/h_separation = 20
theme_override_constants/v_separation = 10
columns = 2
[node name="P1Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000018]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "PowerUp 1 (Speed)" text = "PowerUp 1 (Speed)"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="Powerup1Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P1" unique_id=643351652] [node name="Powerup1Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000019]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "1" text = "1"
[node name="P2" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=1529813635] [node name="P2Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000020]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P2" unique_id=1645306219]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "PowerUp 2 (Freeze)" text = "PowerUp 2 (Freeze/Ghost)"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="Powerup2Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P2" unique_id=937262208] [node name="Powerup2Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000021]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "2" text = "2"
[node name="P3" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=69920143] [node name="P3Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000022]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P3" unique_id=448782584]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "PowerUp 3 (Wall)" text = "PowerUp 3 (Wall)"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="Powerup3Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P3" unique_id=1817070904] [node name="Powerup3Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000023]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "3" text = "3"
[node name="P4" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=559680686] [node name="P4Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000024]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P4" unique_id=1049586584]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "PowerUp 4 (Ghost)" text = "PowerUp 4 (Ghost)"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="Powerup4Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/P4" unique_id=1027617123] [node name="Powerup4Btn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerUpGrid" unique_id=100000025]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "4" text = "4"
[node name="Attack" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=1722218076] [node name="PowerBarSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000026]
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/Attack" unique_id=1040943113] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerBarSection" unique_id=100000027]
layout_mode = 2
text = "POWER BAR CONTROL"
label_settings = SubResource("LabelSettings_section")
[node name="PowerBarGrid" type="GridContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000028]
layout_mode = 2
theme_override_constants/h_separation = 20
theme_override_constants/v_separation = 10
columns = 2
[node name="AttackLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerBarGrid" unique_id=100000029]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "Attack Mode" text = "Attack Mode"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="AttackModeBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/Attack" unique_id=1913469674] [node name="AttackModeBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerBarGrid" unique_id=100000030]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "Q" text = "Q"
[node name="Grab" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=951480662] [node name="SpawnBoostLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerBarGrid" unique_id=100000031]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/Grab" unique_id=1050214223]
layout_mode = 2
size_flags_horizontal = 3
text = "Grab"
label_settings = SubResource("LabelSettings_heading")
[node name="GrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/Grab" unique_id=1307913086]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "Space"
[node name="SpawnBoost" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=1495993475]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/SpawnBoost" unique_id=1933746399]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "Spawn Boost" text = "Spawn Boost"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="SpawnBoostBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/SpawnBoost" unique_id=1836762532] [node name="SpawnBoostBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/PowerBarGrid" unique_id=100000032]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
text = "E" text = "E"
[node name="TektonGrab" type="HBoxContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=263116515] [node name="OtherSection" type="PanelContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000033]
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section_header")
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/TektonGrab" unique_id=1041049284] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherSection" unique_id=100000034]
layout_mode = 2
text = "INTERACTION CONTROL"
label_settings = SubResource("LabelSettings_section")
[node name="OtherGrid" type="GridContainer" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox" unique_id=100000035]
layout_mode = 2
theme_override_constants/h_separation = 20
theme_override_constants/v_separation = 10
columns = 2
[node name="GrabLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000036]
layout_mode = 2
size_flags_horizontal = 3
text = "Grab Item"
label_settings = SubResource("LabelSettings_heading")
[node name="GrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000037]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "Space"
[node name="PutLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000038]
layout_mode = 2
size_flags_horizontal = 3
text = "Put Item"
label_settings = SubResource("LabelSettings_heading")
[node name="PutBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000039]
unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
text = "R"
[node name="TektonGrabLabel" type="Label" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000040]
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
text = "Grab Tekton" text = "Grab Tekton"
label_settings = SubResource("LabelSettings_heading") label_settings = SubResource("LabelSettings_heading")
[node name="TektonGrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/TektonGrab" unique_id=1884439337] [node name="TektonGrabBtn" type="Button" parent="PanelContainer/VBoxContainer/ContentSection/TabContainer/Controls/VBox/OtherGrid" unique_id=100000041]
unique_name_in_owner = true unique_name_in_owner = true
custom_minimum_size = Vector2(150, 40) custom_minimum_size = Vector2(150, 40)
layout_mode = 2 layout_mode = 2
+16 -6
View File
@@ -18,12 +18,22 @@ func _process(delta):
if TurnManager.turn_based_mode: if TurnManager.turn_based_mode:
return return
# Continuous movement input
var move_vec = Vector2i.ZERO var move_vec = Vector2i.ZERO
if Input.is_action_pressed("move_north"): move_vec.y -= 1 # 1. Controller / Joystick Movement
if Input.is_action_pressed("move_south"): move_vec.y += 1 if SettingsManager and SettingsManager.settings.controls.get("use_controller", false):
if Input.is_action_pressed("move_east"): move_vec.x += 1 var joystick_vec = Input.get_vector("move_west", "move_east", "move_north", "move_south")
if Input.is_action_pressed("move_west"): move_vec.x -= 1 if joystick_vec.length() > 0.3: # Deadzone
if abs(joystick_vec.x) > abs(joystick_vec.y):
move_vec.x = 1 if joystick_vec.x > 0 else -1
else:
move_vec.y = 1 if joystick_vec.y > 0 else -1
# 2. Keyboard Movement (Fallback)
if move_vec == Vector2i.ZERO:
if Input.is_action_pressed("move_north"): move_vec.y -= 1
if Input.is_action_pressed("move_south"): move_vec.y += 1
if Input.is_action_pressed("move_east"): move_vec.x += 1
if Input.is_action_pressed("move_west"): move_vec.x -= 1
# Fallback for explicit diagonal actions (if mapped) # Fallback for explicit diagonal actions (if mapped)
if move_vec == Vector2i.ZERO: if move_vec == Vector2i.ZERO:
@@ -33,7 +43,7 @@ func _process(delta):
elif Input.is_action_pressed("move_northwest"): move_vec = Vector2i(-1, -1) elif Input.is_action_pressed("move_northwest"): move_vec = Vector2i(-1, -1)
# Action inputs (still momentary) # 3. Action inputs (momentary)
if Input.is_action_just_pressed("action_grab"): if Input.is_action_just_pressed("action_grab"):
player.grab_item(player.current_position) player.grab_item(player.current_position)
elif Input.is_action_just_pressed("action_put"): elif Input.is_action_just_pressed("action_put"):
+69 -5
View File
@@ -5,12 +5,24 @@ extends Node
const SETTINGS_FILE = "user://game_settings.cfg" const SETTINGS_FILE = "user://game_settings.cfg"
const RESOLUTIONS = [
Vector2i(1024, 576),
Vector2i(1280, 720),
Vector2i(1366, 768),
Vector2i(1600, 900),
Vector2i(1920, 1080),
Vector2i(2560, 1440)
]
# Default values # Default values
var settings = { var settings = {
"video": { "video": {
"fullscreen": true, "fullscreen": true,
"vsync": true, "vsync": true,
"resolution_idx": 1 "resolution_idx": 1,
"msaa": 0, # 0: Disabled, 1: 2x, 2: 4x, 3: 8x
"shadow_quality": 2, # 0: Low, 1: Med, 2: High, 3: Ultra
"fps_cap": 2 # 0: Unlimited, 1: 30, 2: 60, 3: 120, 4: 144
}, },
"audio": { "audio": {
"master_volume": 0.8, "master_volume": 0.8,
@@ -18,15 +30,24 @@ var settings = {
"sfx_volume": 0.9 "sfx_volume": 0.9
}, },
"controls": { "controls": {
"use_controller": false,
# Movement (Keybinds are typically fixed to WASD/Arrows in Input Map, but we show them)
"move_up": KEY_W,
"move_down": KEY_S,
"move_left": KEY_A,
"move_right": KEY_D,
# Actions
"grab": KEY_SPACE,
"put": KEY_R,
"tekton_grab": KEY_G,
# Power-Up Controls
"powerup_1": KEY_1, "powerup_1": KEY_1,
"powerup_2": KEY_2, "powerup_2": KEY_2,
"powerup_3": KEY_3, "powerup_3": KEY_3,
"powerup_4": KEY_4, "powerup_4": KEY_4,
"grab": KEY_SPACE, # Power Bar Controls / Special
"put": KEY_R,
"attack_mode": KEY_Q, "attack_mode": KEY_Q,
"spawn_boost": KEY_E, "spawn_boost": KEY_E
"tekton_grab": KEY_G
} }
} }
@@ -63,16 +84,59 @@ func apply_all_settings():
func apply_video_settings(): func apply_video_settings():
var video = settings.video var video = settings.video
if video.fullscreen: if video.fullscreen:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
else: else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
# Apply resolution size when windowed
var res_idx = video.resolution_idx
if res_idx >= 0 and res_idx < RESOLUTIONS.size():
var target_res = RESOLUTIONS[res_idx]
DisplayServer.window_set_size(target_res)
# Center window after resize
var screen = DisplayServer.window_get_current_screen()
var screen_rect = DisplayServer.screen_get_usable_rect(screen)
var window_size = DisplayServer.window_get_size()
DisplayServer.window_set_position(screen_rect.position + (screen_rect.size - window_size) / 2)
if video.vsync: if video.vsync:
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED) DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)
else: else:
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED) DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
# Apply MSAA
var viewport = get_viewport()
match video.msaa:
0: viewport.msaa_3d = Viewport.MSAA_DISABLED
1: viewport.msaa_3d = Viewport.MSAA_2X
2: viewport.msaa_3d = Viewport.MSAA_4X
3: viewport.msaa_3d = Viewport.MSAA_8X
# Apply FPS Cap
match video.fps_cap:
0: Engine.max_fps = 0
1: Engine.max_fps = 30
2: Engine.max_fps = 60
3: Engine.max_fps = 120
4: Engine.max_fps = 144
# Apply Shadow Quality (Simplified for Forward+)
match video.shadow_quality:
0: # Low
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_LOW)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_LOW)
1: # Medium
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_MEDIUM)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_MEDIUM)
2: # High
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_HIGH)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_HIGH)
3: # Ultra
RenderingServer.directional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_ULTRA)
RenderingServer.positional_soft_shadow_filter_set_quality(RenderingServer.SHADOW_QUALITY_SOFT_ULTRA)
func apply_audio_settings(): func apply_audio_settings():
var audio = settings.audio var audio = settings.audio
set_bus_volume("Master", audio.master_volume) set_bus_volume("Master", audio.master_volume)
+65 -1
View File
@@ -8,6 +8,10 @@ extends CanvasLayer
# Video Controls # Video Controls
@onready var fullscreen_toggle = %FullscreenToggle @onready var fullscreen_toggle = %FullscreenToggle
@onready var vsync_toggle = %VSyncToggle @onready var vsync_toggle = %VSyncToggle
@onready var resolution_btn = %ResolutionBtn
@onready var msaa_btn = %MSAABtn
@onready var shadow_btn = %ShadowBtn
@onready var fps_btn = %FPSCapBtn
# Audio Controls # Audio Controls
@onready var master_slider = %MasterSlider @onready var master_slider = %MasterSlider
@@ -15,6 +19,7 @@ extends CanvasLayer
@onready var sfx_slider = %SFXSlider @onready var sfx_slider = %SFXSlider
# Controls (Keybinds) # Controls (Keybinds)
@onready var use_controller_btn = %UseControllerBtn
@onready var SettingsManager = get_node_or_null("/root/SettingsManager") @onready var SettingsManager = get_node_or_null("/root/SettingsManager")
var listening_action: String = "" # Set when waiting for a keypress var listening_action: String = "" # Set when waiting for a keypress
@@ -37,31 +42,76 @@ func _load_ui_values():
fullscreen_toggle.button_pressed = s.video.fullscreen fullscreen_toggle.button_pressed = s.video.fullscreen
vsync_toggle.button_pressed = s.video.vsync vsync_toggle.button_pressed = s.video.vsync
# Populate Resolution dropdown if not already populated
if resolution_btn.item_count == 0:
for i in range(SettingsManager.RESOLUTIONS.size()):
var res = SettingsManager.RESOLUTIONS[i]
resolution_btn.add_item("%dx%d" % [res.x, res.y])
resolution_btn.selected = s.video.resolution_idx
# MSAA
if msaa_btn.item_count == 0:
msaa_btn.add_item("Disabled")
msaa_btn.add_item("2x")
msaa_btn.add_item("4x")
msaa_btn.add_item("8x")
msaa_btn.selected = s.video.msaa
# Shadows
if shadow_btn.item_count == 0:
shadow_btn.add_item("Low")
shadow_btn.add_item("Medium")
shadow_btn.add_item("High")
shadow_btn.add_item("Ultra")
shadow_btn.selected = s.video.shadow_quality
# FPS Cap
if fps_btn.item_count == 0:
fps_btn.add_item("Unlimited")
fps_btn.add_item("30 FPS")
fps_btn.add_item("60 FPS")
fps_btn.add_item("120 FPS")
fps_btn.add_item("144 FPS")
fps_btn.selected = s.video.fps_cap
# Audio # Audio
master_slider.value = s.audio.master_volume master_slider.value = s.audio.master_volume
music_slider.value = s.audio.music_volume music_slider.value = s.audio.music_volume
sfx_slider.value = s.audio.sfx_volume sfx_slider.value = s.audio.sfx_volume
# Controls # Controls
use_controller_btn.button_pressed = s.controls.get("use_controller", false)
_update_all_key_labels() _update_all_key_labels()
func _connect_signals(): func _connect_signals():
# Video # Video
fullscreen_toggle.toggled.connect(_on_video_setting_changed) fullscreen_toggle.toggled.connect(_on_video_setting_changed)
vsync_toggle.toggled.connect(_on_video_setting_changed) vsync_toggle.toggled.connect(_on_video_setting_changed)
resolution_btn.item_selected.connect(_on_resolution_selected)
msaa_btn.item_selected.connect(_on_video_property_changed.bind("msaa"))
shadow_btn.item_selected.connect(_on_video_property_changed.bind("shadow_quality"))
fps_btn.item_selected.connect(_on_video_property_changed.bind("fps_cap"))
# Audio # Audio
master_slider.value_changed.connect(_on_audio_setting_changed.bind("master_volume")) master_slider.value_changed.connect(_on_audio_setting_changed.bind("master_volume"))
music_slider.value_changed.connect(_on_audio_setting_changed.bind("music_volume")) music_slider.value_changed.connect(_on_audio_setting_changed.bind("music_volume"))
sfx_slider.value_changed.connect(_on_audio_setting_changed.bind("sfx_volume")) sfx_slider.value_changed.connect(_on_audio_setting_changed.bind("sfx_volume"))
# Controls
use_controller_btn.toggled.connect(_on_control_setting_changed.bind("use_controller"))
# Close # Close
close_button.pressed.connect(func(): visible = false) close_button.pressed.connect(func(): visible = false)
# Connect remapping buttons # Connect remapping buttons (exclude non-keybinds like use_controller)
for action_name in SettingsManager.settings.controls.keys(): for action_name in SettingsManager.settings.controls.keys():
if action_name == "use_controller":
continue
var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn") var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn")
if btn: if btn:
if btn.pressed.is_connected(_on_remap_button_pressed):
btn.pressed.disconnect(_on_remap_button_pressed)
btn.pressed.connect(_on_remap_button_pressed.bind(action_name)) btn.pressed.connect(_on_remap_button_pressed.bind(action_name))
func _on_video_setting_changed(_unused = false): func _on_video_setting_changed(_unused = false):
@@ -70,11 +120,25 @@ func _on_video_setting_changed(_unused = false):
SettingsManager.save_settings() SettingsManager.save_settings()
SettingsManager.apply_video_settings() SettingsManager.apply_video_settings()
func _on_resolution_selected(idx: int):
SettingsManager.settings.video.resolution_idx = idx
SettingsManager.save_settings()
SettingsManager.apply_video_settings()
func _on_video_property_changed(idx: int, property_name: String):
SettingsManager.settings.video[property_name] = idx
SettingsManager.save_settings()
SettingsManager.apply_video_settings()
func _on_audio_setting_changed(key: String, value: float): func _on_audio_setting_changed(key: String, value: float):
SettingsManager.settings.audio[key] = value SettingsManager.settings.audio[key] = value
SettingsManager.save_settings() SettingsManager.save_settings()
SettingsManager.apply_audio_settings() SettingsManager.apply_audio_settings()
func _on_control_setting_changed(value: bool, key: String):
SettingsManager.settings.controls[key] = value
SettingsManager.save_settings()
func _on_remap_button_pressed(action_name: String): func _on_remap_button_pressed(action_name: String):
listening_action = action_name listening_action = action_name
var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn") var btn = get_node_or_null("%" + action_name.to_pascal_case() + "Btn")