using Newtonsoft.Json; namespace CMSGame { /// /// 游戏设置持久化节点 /// /// 在游戏开始时载入用户设置,并在游戏关闭时保存用户设置。 /// public partial class GameSettingsNode : Node { protected Dictionary CurrentSettings = new(); protected Dictionary PreviousSettings = new(); protected Dictionary SettingsPaths = new(); public BattleSettings BattleSettings => GetSettings(); public VideoSettings VideoSettings => GetSettings(); public AudioSettings AudioSettings => GetSettings(); public GameSettingsNode() { RegisterAllSettings(); MakeDirectories(); LoadAllSettings(); ApplyVideoSettings(); } 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 (!PreviousSettings.ContainsKey(settingsType) || PreviousSettings[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) { PreviousSettings[settingsType] = (GameSettings)settings; CurrentSettings[settingsType] = (GameSettings)settings with { }; } } 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); } public void ApplyVideoSettings() { if (VideoSettings.UseFullScreen) { DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen); } else { DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed); } } } }