diff --git a/Autoloads/GameSettings.cs b/Autoloads/GameSettings.cs
index 063ce93..dca3356 100644
--- a/Autoloads/GameSettings.cs
+++ b/Autoloads/GameSettings.cs
@@ -1,118 +1,16 @@
-using Newtonsoft.Json;
-
namespace CMSGame
{
- ///
- /// 游戏设置持久化
- ///
- public partial class GameSettings : Node
- {
- protected Dictionary CurrentSettings = new();
-
- protected Dictionary OriginalSettings = new();
-
- protected Dictionary SettingsPaths = new();
-
- public BattleSettings BattleSettings => GetSettings();
-
- public VideoSettings VideoSettings => GetSettings();
-
- public AudioSettings AudioSettings => GetSettings();
-
- public GameSettings()
- {
- RegisterAllSettings();
- }
-
- public override void _Ready()
- {
- MakeDirectories();
- LoadAllSettings();
- }
-
- protected void RegisterAllSettings()
- {
- RegisterSettings("BattleSettings.json");
- RegisterSettings("VideoSettings.json");
- RegisterSettings("AudioSettings.json");
- }
-
- protected void RegisterSettings(string filename) where TSettings : SettingsBase, new()
- {
- var defaultSettings = new TSettings();
- CurrentSettings.Add(typeof(TSettings), defaultSettings);
- SettingsPaths.Add(typeof(TSettings), new GodotPath($"user://Settings/{filename}"));
- }
-
- protected void LoadAllSettings()
- {
- foreach (var settingsType in SettingsPaths.Keys)
- {
- LoadSettings(settingsType);
- }
- }
-
- public override void _ExitTree()
- {
- foreach (var settingsType in SettingsPaths.Keys)
- {
- if (!OriginalSettings.ContainsKey(settingsType) || OriginalSettings[settingsType] != CurrentSettings[settingsType])
- {
- SaveSettings(settingsType);
- }
- }
- }
-
- private static void MakeDirectories()
- {
- DirAccess.MakeDirRecursiveAbsolute("user://Settings/");
- }
-
- private void LoadSettings(Type settingsType)
- {
- string settingsText = ReadFileAsString(SettingsPaths[settingsType]);
- var settings = JsonConvert.DeserializeObject(settingsText, settingsType);
- if (settings != null)
- {
- OriginalSettings[settingsType] = (SettingsBase)settings;
- CurrentSettings[settingsType] = (SettingsBase)settings;
- }
- }
-
- public TSettings GetSettings() where TSettings : SettingsBase, new()
- {
- return (TSettings)CurrentSettings[typeof(TSettings)];
- }
-
- private static string ReadFileAsString(string path)
- {
- if (FileAccess.FileExists(path))
- {
- using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
- return file.GetAsText();
- }
- return "null";
- }
-
- private void SaveSettings(Type settingsType)
- {
- string settingsText = JsonConvert.SerializeObject(CurrentSettings[settingsType]);
- using var file = FileAccess.Open(SettingsPaths[settingsType], FileAccess.ModeFlags.Write);
- file.StoreString(settingsText);
- }
- }
-
- public record class SettingsBase
+ public record class GameSettings
{
}
- public record class BattleSettings : SettingsBase
+ public record class BattleSettings : GameSettings
{ }
- public record class VideoSettings : SettingsBase
+ public record class VideoSettings : GameSettings
{ }
- public record class AudioSettings : SettingsBase
+ public record class AudioSettings : GameSettings
{
///
/// 音乐音量
diff --git a/Autoloads/GameSettingsNode.cs b/Autoloads/GameSettingsNode.cs
new file mode 100644
index 0000000..bc581e2
--- /dev/null
+++ b/Autoloads/GameSettingsNode.cs
@@ -0,0 +1,106 @@
+using Newtonsoft.Json;
+
+namespace CMSGame
+{
+ ///
+ /// 游戏设置持久化节点
+ ///
+ /// 在游戏开始时载入用户设置,并在游戏关闭时保存用户设置。
+ ///
+ public partial class GameSettingsNode : Node
+ {
+ protected Dictionary CurrentSettings = new();
+
+ protected Dictionary OriginalSettings = new();
+
+ protected Dictionary SettingsPaths = new();
+
+ public BattleSettings BattleSettings => GetSettings();
+
+ public VideoSettings VideoSettings => GetSettings();
+
+ public AudioSettings AudioSettings => GetSettings();
+
+ public GameSettingsNode()
+ {
+ RegisterAllSettings();
+ }
+
+ public override void _Ready()
+ {
+ MakeDirectories();
+ LoadAllSettings();
+ }
+
+ protected void RegisterAllSettings()
+ {
+ RegisterSettings("BattleSettings.json");
+ RegisterSettings("VideoSettings.json");
+ RegisterSettings("AudioSettings.json");
+ }
+
+ protected void RegisterSettings(string filename) where TSettings : GameSettings, new()
+ {
+ var defaultSettings = new TSettings();
+ CurrentSettings.Add(typeof(TSettings), defaultSettings);
+ SettingsPaths.Add(typeof(TSettings), new GodotPath($"user://Settings/{filename}"));
+ }
+
+ protected void LoadAllSettings()
+ {
+ foreach (var settingsType in SettingsPaths.Keys)
+ {
+ LoadSettings(settingsType);
+ }
+ }
+
+ public override void _ExitTree()
+ {
+ foreach (var settingsType in SettingsPaths.Keys)
+ {
+ if (!OriginalSettings.ContainsKey(settingsType) || OriginalSettings[settingsType] != CurrentSettings[settingsType])
+ {
+ SaveSettings(settingsType);
+ }
+ }
+ }
+
+ private static void MakeDirectories()
+ {
+ DirAccess.MakeDirRecursiveAbsolute("user://Settings/");
+ }
+
+ private void LoadSettings(Type settingsType)
+ {
+ string settingsText = ReadFileAsString(SettingsPaths[settingsType]);
+ var settings = JsonConvert.DeserializeObject(settingsText, settingsType);
+ if (settings != null)
+ {
+ OriginalSettings[settingsType] = (GameSettings)settings;
+ CurrentSettings[settingsType] = (GameSettings)settings;
+ }
+ }
+
+ public TSettings GetSettings() where TSettings : GameSettings, new()
+ {
+ return (TSettings)CurrentSettings[typeof(TSettings)];
+ }
+
+ private static string ReadFileAsString(string path)
+ {
+ if (FileAccess.FileExists(path))
+ {
+ using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
+ return file.GetAsText();
+ }
+ return "null";
+ }
+
+ private void SaveSettings(Type settingsType)
+ {
+ string settingsText = JsonConvert.SerializeObject(CurrentSettings[settingsType]);
+ using var file = FileAccess.Open(SettingsPaths[settingsType], FileAccess.ModeFlags.Write);
+ file.StoreString(settingsText);
+ }
+ }
+}
diff --git a/Components/Settings/AudioSettingsMenu.cs b/Components/Settings/AudioSettingsMenu.cs
index 2789ee9..661f292 100644
--- a/Components/Settings/AudioSettingsMenu.cs
+++ b/Components/Settings/AudioSettingsMenu.cs
@@ -2,7 +2,7 @@ namespace CMSGame
{
public partial class AudioSettingsMenu : VBoxContainer
{
- public GameSettings? GameSettings;
+ public GameSettingsNode? Settings;
public HSlider? MasterVolumeSlider;
@@ -12,7 +12,7 @@ namespace CMSGame
public override void _Ready()
{
- this.GetAutoloadNode(ref GameSettings, nameof(GameSettings));
+ this.GetAutoloadNode(ref Settings, nameof(GameSettingsNode));
MasterVolumeSlider = this.GetUniqueNode(nameof(MasterVolumeSlider));
MusicVolumeSlider = this.GetUniqueNode(nameof(MusicVolumeSlider));
diff --git a/Components/Settings/SettingsMenu.cs b/Components/Settings/SettingsMenu.cs
index eb76b21..2421f55 100644
--- a/Components/Settings/SettingsMenu.cs
+++ b/Components/Settings/SettingsMenu.cs
@@ -2,11 +2,11 @@ namespace CMSGame
{
public partial class SettingsMenu : TabContainer
{
- public GameSettings? Settings;
+ public GameSettingsNode? Settings;
public override void _Ready()
{
- this.GetAutoloadNode(ref Settings, nameof(GameSettings));
+ this.GetAutoloadNode(ref Settings, nameof(GameSettingsNode));
}
}
}
diff --git a/Components/Settings/SettingsMenu.tscn b/Components/Settings/SettingsMenu.tscn
index 7532ad6..9ba9005 100644
--- a/Components/Settings/SettingsMenu.tscn
+++ b/Components/Settings/SettingsMenu.tscn
@@ -16,7 +16,6 @@ script = ExtResource("1_av57b")
[node name="BattleSettingsMenu" type="VBoxContainer" parent="."]
unique_name_in_owner = true
-visible = false
layout_mode = 2
script = ExtResource("2_xtjo5")
@@ -28,6 +27,7 @@ script = ExtResource("3_68iki")
[node name="AudioSettingsMenu" type="VBoxContainer" parent="."]
unique_name_in_owner = true
+visible = false
layout_mode = 2
script = ExtResource("4_ciy5h")
@@ -39,7 +39,8 @@ columns = 2
layout_mode = 2
text = "主音量"
-[node name="MasterVolumnSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
+[node name="MasterVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
+unique_name_in_owner = true
layout_mode = 2
max_value = 1.0
step = 0.01
@@ -49,7 +50,7 @@ value = 0.8
layout_mode = 2
text = "音乐音量"
-[node name="MusicVolumnSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
+[node name="MusicVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
@@ -61,7 +62,7 @@ value = 0.8
layout_mode = 2
text = "音效音量"
-[node name="SoundEffectVolumnSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
+[node name="SoundEffectVolumeSlider" type="HSlider" parent="AudioSettingsMenu/GridContainer"]
unique_name_in_owner = true
layout_mode = 2
max_value = 1.0
diff --git a/Components/Settings/SettingsMenuPopup.cs b/Components/Settings/SettingsMenuPopup.cs
index a383201..bff1404 100644
--- a/Components/Settings/SettingsMenuPopup.cs
+++ b/Components/Settings/SettingsMenuPopup.cs
@@ -2,7 +2,7 @@ namespace CMSGame
{
public partial class SettingsMenuPopup : Popup
{
- public void On_ConfirmButton_Pressed()
+ public void On_HidePopupButton_Pressed()
{
Hide();
}
diff --git a/Components/Settings/SettingsMenuPopup.tscn b/Components/Settings/SettingsMenuPopup.tscn
index a54444b..22e96ae 100644
--- a/Components/Settings/SettingsMenuPopup.tscn
+++ b/Components/Settings/SettingsMenuPopup.tscn
@@ -4,20 +4,24 @@
[ext_resource type="PackedScene" uid="uid://blk2uswpo2a7k" path="res://Components/Settings/SettingsMenu.tscn" id="2_qc1kk"]
[node name="SettingsMenuPopup" type="Popup"]
-size = Vector2i(172, 101)
+size = Vector2i(800, 485)
visible = true
script = ExtResource("1_it4yp")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
-offset_right = 40.0
-offset_bottom = 40.0
+offset_right = 800.0
+offset_bottom = 66.0
+alignment = 1
[node name="SettingsMenu" parent="VBoxContainer" instance=ExtResource("2_qc1kk")]
+custom_minimum_size = Vector2(800, 450)
layout_mode = 2
-[node name="ConfirmButton" type="Button" parent="VBoxContainer"]
+[node name="HidePopupButton" type="Button" parent="VBoxContainer"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(200, 0)
layout_mode = 2
-text = "保存并退出"
+size_flags_horizontal = 4
+text = "关闭"
-[connection signal="pressed" from="VBoxContainer/ConfirmButton" to="." method="On_ConfirmButton_Pressed"]
+[connection signal="pressed" from="VBoxContainer/HidePopupButton" to="." method="On_HidePopupButton_Pressed"]
diff --git a/Scenes/MainScene.cs b/Scenes/MainScene.cs
index 7548423..e8fcbf1 100644
--- a/Scenes/MainScene.cs
+++ b/Scenes/MainScene.cs
@@ -4,7 +4,7 @@ namespace CMSGame
{
public void On_SettingsPopupButton_Pressed()
{
- GetNode("%SettingsPopup").PopupCentered();
+ GetNode("%SettingsMenuPopup").PopupCentered();
}
public void On_QuitButton_Pressed()
diff --git a/Scenes/MainScene.tscn b/Scenes/MainScene.tscn
index b5fe19a..a6528c8 100644
--- a/Scenes/MainScene.tscn
+++ b/Scenes/MainScene.tscn
@@ -1,7 +1,8 @@
-[gd_scene load_steps=3 format=3 uid="uid://c3ovsoq6o7y3t"]
+[gd_scene load_steps=4 format=3 uid="uid://c3ovsoq6o7y3t"]
[ext_resource type="Script" path="res://Scenes/MainScene.cs" id="1_kso8c"]
[ext_resource type="Theme" uid="uid://cn55cr5w4yy3n" path="res://Themes/UI.tres" id="1_y72s3"]
+[ext_resource type="PackedScene" uid="uid://cslqihnfw0me2" path="res://Components/Settings/SettingsMenuPopup.tscn" id="3_1d7q7"]
[node name="MainScene" type="Control"]
layout_mode = 3
@@ -10,7 +11,6 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
-theme = ExtResource("1_y72s3")
script = ExtResource("1_kso8c")
[node name="BackgroundImage" type="Label" parent="."]
@@ -34,6 +34,7 @@ offset_top = -65.5
offset_right = 287.0
offset_bottom = 65.5
grow_vertical = 2
+theme = ExtResource("1_y72s3")
theme_override_constants/separation = 16
[node name="StartButton" type="Button" parent="StartMenu"]
@@ -48,6 +49,12 @@ text = "设置"
layout_mode = 2
text = "退出"
+[node name="SettingsMenuPopup" parent="." instance=ExtResource("3_1d7q7")]
+unique_name_in_owner = true
+title = "游戏设置"
+visible = false
+borderless = false
+
[connection signal="pressed" from="StartMenu/StartButton" to="." method="On_BattleDemo1Button_Pressed"]
[connection signal="pressed" from="StartMenu/SettingsButton" to="." method="On_SettingsPopupButton_Pressed"]
[connection signal="pressed" from="StartMenu/QuitButton" to="." method="On_QuitButton_Pressed"]
diff --git a/project.godot b/project.godot
index 0988869..25c2758 100644
--- a/project.godot
+++ b/project.godot
@@ -22,7 +22,7 @@ config/icon="res://icon.svg"
[autoload]
-GameSettings="*res://Autoloads/GameSettings.cs"
+GameSettingsNode="*res://Autoloads/GameSettingsNode.cs"
BackgroundMusicPlayer="*res://Autoloads/BackgroundMusicPlayer.tscn"
[display]