mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(setting): 重构设置系统以支持数据和应用器分离
- 将SettingsModel内部存储分离为_dataSettings和_applicators两个字典 - 添加IDataSettings接口用于标识纯数据设置 - 修改Get方法为GetData以明确区分数据获取 - 添加RegisterApplicator和GetApplicator方法管理可应用设置 - 更新TryGet方法支持从数据和应用器中查找设置 - 扩展SettingsPersistence支持批量保存和加载所有设置数据 - 将AudioBusMap重命名为AudioBusMapSettings并实现ISettingsData接口 - 修改Godot音频和图形设置适配新的接口变更 - [skip ci]
This commit is contained in:
parent
516a9e2281
commit
442e8e7088
@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// 音频设置类,用于管理游戏中的音频配置
|
||||
/// </summary>
|
||||
public class AudioSettings : ISettingsSection
|
||||
public class AudioSettings : ISettingsData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置主音量,控制所有音频的总体音量
|
||||
|
||||
@ -3,7 +3,7 @@ namespace GFramework.Game.Abstractions.setting;
|
||||
/// <summary>
|
||||
/// 图形设置类,用于管理游戏的图形相关配置
|
||||
/// </summary>
|
||||
public class GraphicsSettings : ISettingsSection
|
||||
public class GraphicsSettings : ISettingsData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置是否启用全屏模式
|
||||
|
||||
6
GFramework.Game.Abstractions/setting/ISettingsData.cs
Normal file
6
GFramework.Game.Abstractions/setting/ISettingsData.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace GFramework.Game.Abstractions.setting;
|
||||
|
||||
/// <summary>
|
||||
/// 设置数据接口 - 纯数据,可自动创建
|
||||
/// </summary>
|
||||
public interface ISettingsData : ISettingsSection;
|
||||
@ -10,11 +10,11 @@ namespace GFramework.Game.Abstractions.setting;
|
||||
public interface ISettingsModel : IModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取指定类型的设置节实例
|
||||
/// 获取或创建数据设置(自动创建)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节的类型,必须是class、实现ISettingsSection接口且具有无参构造函数</typeparam>
|
||||
/// <returns>指定类型的设置节实例</returns>
|
||||
T Get<T>() where T : class, ISettingsSection, new();
|
||||
/// <typeparam name="T">设置数据的类型,必须继承自class、ISettingsData且具有无参构造函数</typeparam>
|
||||
/// <returns>指定类型的设置数据实例</returns>
|
||||
T GetData<T>() where T : class, ISettingsData, new();
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取指定类型的设置节实例
|
||||
@ -24,6 +24,13 @@ public interface ISettingsModel : IModel
|
||||
/// <returns>如果找到指定类型的设置节则返回true,否则返回false</returns>
|
||||
bool TryGet(Type type, out ISettingsSection section);
|
||||
|
||||
/// <summary>
|
||||
/// 获取已注册的可应用设置
|
||||
/// </summary>
|
||||
/// <typeparam name="T">可应用设置的类型,必须继承自class和IApplyAbleSettings</typeparam>
|
||||
/// <returns>指定类型的可应用设置实例,如果不存在则返回null</returns>
|
||||
T? GetApplicator<T>() where T : class, IApplyAbleSettings;
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有设置节的集合
|
||||
/// </summary>
|
||||
@ -31,8 +38,9 @@ public interface ISettingsModel : IModel
|
||||
IEnumerable<ISettingsSection> All();
|
||||
|
||||
/// <summary>
|
||||
/// 注册一个可应用的设置对象
|
||||
/// 注册可应用设置(必须手动注册)
|
||||
/// </summary>
|
||||
/// <param name="applyAble">要注册的可应用设置对象</param>
|
||||
void Register(IApplyAbleSettings applyAble);
|
||||
/// <typeparam name="T">可应用设置的类型,必须继承自class和IApplyAbleSettings</typeparam>
|
||||
/// <param name="applicator">要注册的可应用设置实例</param>
|
||||
void RegisterApplicator<T>(T applicator) where T : class, IApplyAbleSettings;
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GFramework.Game.Abstractions.setting;
|
||||
|
||||
@ -9,31 +11,32 @@ namespace GFramework.Game.Abstractions.setting;
|
||||
public interface ISettingsPersistence
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步加载指定类型的设置节
|
||||
/// 异步加载指定类型的设置数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口并具有无参构造函数</typeparam>
|
||||
/// <returns>返回加载的设置节实例</returns>
|
||||
Task<T> LoadAsync<T>() where T : class, ISettingsSection, new();
|
||||
Task<T> LoadAsync<T>() where T : class, ISettingsData, new();
|
||||
|
||||
/// <summary>
|
||||
/// 异步保存指定的设置节
|
||||
/// 异步保存指定的设置数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <param name="section">要保存的设置节实例</param>
|
||||
/// <returns>异步操作任务</returns>
|
||||
Task SaveAsync<T>(T section) where T : class, ISettingsSection;
|
||||
Task SaveAsync<T>(T section) where T : class, ISettingsData;
|
||||
|
||||
/// <summary>
|
||||
/// 异步检查指定类型的设置节是否存在
|
||||
/// 异步检查指定类型的设置数据是否存在
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <returns>如果设置节存在则返回true,否则返回false</returns>
|
||||
Task<bool> ExistsAsync<T>() where T : class, ISettingsSection;
|
||||
Task<bool> ExistsAsync<T>() where T : class, ISettingsData;
|
||||
|
||||
/// <summary>
|
||||
/// 异步删除指定类型的设置节
|
||||
/// 异步删除指定类型的设置数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <returns>异步操作任务</returns>
|
||||
Task DeleteAsync<T>() where T : class, ISettingsSection;
|
||||
Task DeleteAsync<T>() where T : class, ISettingsData;
|
||||
|
||||
/// <summary>
|
||||
/// 保存所有设置数据
|
||||
/// </summary>
|
||||
Task SaveAllAsync(IEnumerable<ISettingsData> allData);
|
||||
|
||||
/// <summary>
|
||||
/// 加载所有已知类型的设置数据
|
||||
/// </summary>
|
||||
Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes);
|
||||
}
|
||||
@ -8,53 +8,87 @@ namespace GFramework.Game.setting;
|
||||
/// </summary>
|
||||
public class SettingsModel : AbstractModel, ISettingsModel
|
||||
{
|
||||
private readonly Dictionary<Type, ISettingsSection> _sections = new();
|
||||
private readonly Dictionary<Type, IApplyAbleSettings> _applicators = new();
|
||||
private readonly Dictionary<Type, ISettingsData> _dataSettings = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的设置部分实例,如果不存在则创建新的实例
|
||||
/// 获取或创建数据设置
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置部分的类型,必须实现ISettingsSection接口并具有无参构造函数</typeparam>
|
||||
/// <returns>指定类型的设置部分实例</returns>
|
||||
public T Get<T>() where T : class, ISettingsSection, new()
|
||||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口并具有无参构造函数</typeparam>
|
||||
/// <returns>指定类型的设置数据实例</returns>
|
||||
public T GetData<T>() where T : class, ISettingsData, new()
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
// 尝试从字典中获取已存在的设置部分实例
|
||||
if (_sections.TryGetValue(type, out var existing))
|
||||
// 尝试从现有字典中获取已存在的设置数据
|
||||
if (_dataSettings.TryGetValue(type, out var existing))
|
||||
return (T)existing;
|
||||
|
||||
// 创建新的设置部分实例并存储到字典中
|
||||
// 创建新的设置数据实例并存储到字典中
|
||||
var created = new T();
|
||||
_sections[type] = created;
|
||||
_dataSettings[type] = created;
|
||||
return created;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取指定类型的设置部分实例
|
||||
/// 注册可应用设置
|
||||
/// </summary>
|
||||
/// <param name="type">设置部分的类型</param>
|
||||
/// <param name="section">输出参数,如果找到则返回对应的设置部分实例,否则为null</param>
|
||||
/// <returns>如果找到指定类型的设置部分则返回true,否则返回false</returns>
|
||||
public bool TryGet(Type type, out ISettingsSection section)
|
||||
=> _sections.TryGetValue(type, out section!);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有设置部分的集合
|
||||
/// </summary>
|
||||
/// <returns>包含所有设置部分的可枚举集合</returns>
|
||||
public IEnumerable<ISettingsSection> All()
|
||||
=> _sections.Values;
|
||||
|
||||
/// <summary>
|
||||
/// 注册一个可应用的设置对象到管理器中
|
||||
/// </summary>
|
||||
/// <param name="applyAble">要注册的可应用设置对象</param>
|
||||
public void Register(IApplyAbleSettings applyAble)
|
||||
/// <typeparam name="T">可应用设置类型,必须实现IApplyAbleSettings接口</typeparam>
|
||||
/// <param name="applicator">要注册的可应用设置实例</param>
|
||||
public void RegisterApplicator<T>(T applicator) where T : class, IApplyAbleSettings
|
||||
{
|
||||
// 获取传入对象的类型信息
|
||||
var type = applyAble.GetType();
|
||||
// 尝试将类型和对象添加到线程安全的字典中
|
||||
_sections.TryAdd(type, applyAble);
|
||||
var type = typeof(T);
|
||||
_applicators[type] = applicator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取已注册的可应用设置
|
||||
/// </summary>
|
||||
/// <typeparam name="T">可应用设置类型,必须实现IApplyAbleSettings接口</typeparam>
|
||||
/// <returns>找到的可应用设置实例,如果未找到则返回null</returns>
|
||||
public T? GetApplicator<T>() where T : class, IApplyAbleSettings
|
||||
{
|
||||
var type = typeof(T);
|
||||
return _applicators.TryGetValue(type, out var applicator)
|
||||
? (T)applicator
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取指定类型的设置节
|
||||
/// </summary>
|
||||
/// <param name="type">要查找的设置类型</param>
|
||||
/// <param name="section">输出参数,找到的设置节实例</param>
|
||||
/// <returns>如果找到设置节则返回true,否则返回false</returns>
|
||||
public bool TryGet(Type type, out ISettingsSection section)
|
||||
{
|
||||
// 首先在数据设置字典中查找
|
||||
if (_dataSettings.TryGetValue(type, out var data))
|
||||
{
|
||||
section = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 然后在应用器字典中查找
|
||||
if (_applicators.TryGetValue(type, out var applicator))
|
||||
{
|
||||
section = applicator;
|
||||
return true;
|
||||
}
|
||||
|
||||
section = null!;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有设置节的集合
|
||||
/// </summary>
|
||||
/// <returns>包含所有设置节的可枚举集合</returns>
|
||||
public IEnumerable<ISettingsSection> All()
|
||||
{
|
||||
// 合并数据设置和应用器设置的所有值
|
||||
return _dataSettings.Values
|
||||
.Concat(_applicators.Values.Cast<ISettingsSection>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -13,11 +13,11 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
|
||||
private IStorage _storage = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载指定类型的设置节数据
|
||||
/// 异步加载指定类型的设置数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <returns>如果存在则返回已保存的设置数据,否则返回新创建的默认设置实例</returns>
|
||||
public async Task<T> LoadAsync<T>() where T : class, ISettingsSection, new()
|
||||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||||
/// <returns>如果存在则返回存储的设置数据,否则返回新创建的实例</returns>
|
||||
public async Task<T> LoadAsync<T>() where T : class, ISettingsData, new()
|
||||
{
|
||||
var key = GetKey<T>();
|
||||
|
||||
@ -30,32 +30,32 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步保存设置节数据到存储中
|
||||
/// 异步保存设置数据到存储中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <param name="section">要保存的设置节实例</param>
|
||||
public async Task SaveAsync<T>(T section) where T : class, ISettingsSection
|
||||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||||
/// <param name="section">要保存的设置数据实例</param>
|
||||
public async Task SaveAsync<T>(T section) where T : class, ISettingsData
|
||||
{
|
||||
var key = GetKey<T>();
|
||||
await _storage.WriteAsync(key, section);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步检查指定类型的设置节是否存在
|
||||
/// 检查指定类型的设置数据是否存在
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
/// <returns>如果设置节存在返回true,否则返回false</returns>
|
||||
public async Task<bool> ExistsAsync<T>() where T : class, ISettingsSection
|
||||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||||
/// <returns>如果存在返回true,否则返回false</returns>
|
||||
public async Task<bool> ExistsAsync<T>() where T : class, ISettingsData
|
||||
{
|
||||
var key = GetKey<T>();
|
||||
return await _storage.ExistsAsync(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步删除指定类型的设置节数据
|
||||
/// 异步删除指定类型的设置数据
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型,必须实现ISettingsSection接口</typeparam>
|
||||
public async Task DeleteAsync<T>() where T : class, ISettingsSection
|
||||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||||
public async Task DeleteAsync<T>() where T : class, ISettingsData
|
||||
{
|
||||
var key = GetKey<T>();
|
||||
_storage.Delete(key);
|
||||
@ -63,18 +63,66 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,获取存储服务实例
|
||||
/// 异步保存所有设置数据到存储中
|
||||
/// </summary>
|
||||
/// <param name="allData">包含所有设置数据的可枚举集合</param>
|
||||
public async Task SaveAllAsync(IEnumerable<ISettingsData> allData)
|
||||
{
|
||||
foreach (var data in allData)
|
||||
{
|
||||
var type = data.GetType();
|
||||
var key = GetKey(type);
|
||||
await _storage.WriteAsync(key, data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载所有已知类型的设置数据
|
||||
/// </summary>
|
||||
/// <param name="knownTypes">已知设置数据类型的集合</param>
|
||||
/// <returns>类型与对应设置数据的字典映射</returns>
|
||||
public async Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes)
|
||||
{
|
||||
var result = new Dictionary<Type, ISettingsData>();
|
||||
|
||||
foreach (var type in knownTypes)
|
||||
{
|
||||
var key = GetKey(type);
|
||||
|
||||
if (!await _storage.ExistsAsync(key)) continue;
|
||||
// 使用反射调用泛型方法
|
||||
var method = typeof(IStorage)
|
||||
.GetMethod(nameof(IStorage.ReadAsync))!
|
||||
.MakeGenericMethod(type);
|
||||
|
||||
var task = (Task)method.Invoke(_storage, [key])!;
|
||||
await task;
|
||||
|
||||
var loaded = (ISettingsData)((dynamic)task).Result;
|
||||
result[type] = loaded;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override void OnInit()
|
||||
{
|
||||
_storage = this.GetUtility<IStorage>()!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取设置节对应的存储键名
|
||||
/// 获取指定类型的存储键名
|
||||
/// </summary>
|
||||
/// <typeparam name="T">设置节类型</typeparam>
|
||||
/// <returns>格式为"Settings_类型名称"的键名字符串</returns>
|
||||
private static string GetKey<T>() where T : ISettingsSection
|
||||
=> $"Settings_{typeof(T).Name}";
|
||||
/// <typeparam name="T">设置数据类型</typeparam>
|
||||
/// <returns>格式为"Settings_类型名称"的键名</returns>
|
||||
private static string GetKey<T>() where T : ISettingsData
|
||||
=> GetKey(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的存储键名
|
||||
/// </summary>
|
||||
/// <param name="type">设置数据类型</param>
|
||||
/// <returns>格式为"Settings_类型名称"的键名</returns>
|
||||
private static string GetKey(Type type)
|
||||
=> $"Settings_{type.Name}";
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
namespace GFramework.Godot.setting;
|
||||
|
||||
/// <summary>
|
||||
/// 音频总线映射配置类,用于定义音频系统中不同类型的音频总线名称
|
||||
/// </summary>
|
||||
public sealed class AudioBusMap
|
||||
{
|
||||
/// <summary>
|
||||
/// 主音频总线名称,默认值为"Master"
|
||||
/// </summary>
|
||||
public string Master { get; init; } = "Master";
|
||||
|
||||
/// <summary>
|
||||
/// 背景音乐音频总线名称,默认值为"BGM"
|
||||
/// </summary>
|
||||
public string Bgm { get; init; } = "BGM";
|
||||
|
||||
/// <summary>
|
||||
/// 音效音频总线名称,默认值为"SFX"
|
||||
/// </summary>
|
||||
public string Sfx { get; init; } = "SFX";
|
||||
}
|
||||
28
GFramework.Godot/setting/AudioBusMapSettings.cs
Normal file
28
GFramework.Godot/setting/AudioBusMapSettings.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using GFramework.Game.Abstractions.setting;
|
||||
|
||||
namespace GFramework.Godot.setting;
|
||||
|
||||
/// <summary>
|
||||
/// 音频总线映射设置
|
||||
/// 定义了游戏中不同音频类型的总线名称配置
|
||||
/// </summary>
|
||||
public class AudioBusMapSettings : ISettingsData
|
||||
{
|
||||
/// <summary>
|
||||
/// 主音频总线名称
|
||||
/// 默认值为"Master"
|
||||
/// </summary>
|
||||
public string Master { get; set; } = "Master";
|
||||
|
||||
/// <summary>
|
||||
/// 背景音乐总线名称
|
||||
/// 默认值为"BGM"
|
||||
/// </summary>
|
||||
public string Bgm { get; set; } = "BGM";
|
||||
|
||||
/// <summary>
|
||||
/// 音效总线名称
|
||||
/// 默认值为"SFX"
|
||||
/// </summary>
|
||||
public string Sfx { get; set; } = "SFX";
|
||||
}
|
||||
@ -6,9 +6,10 @@ namespace GFramework.Godot.setting;
|
||||
/// <summary>
|
||||
/// Godot音频设置实现类,用于应用音频配置到Godot音频系统
|
||||
/// </summary>
|
||||
/// <param name="settings">音频设置对象,包含主音量、背景音乐音量和音效音量</param>
|
||||
/// <param name="busMap">音频总线映射对象,定义了不同音频类型的总线名称</param>
|
||||
public class GodotAudioSettings(AudioSettings settings, AudioBusMap busMap) : IApplyAbleSettings
|
||||
/// <param name="audioSettings">音频设置对象,包含主音量、背景音乐音量和音效音量</param>
|
||||
/// <param name="audioBusMapSettings">音频总线映射对象,定义了不同音频类型的总线名称</param>
|
||||
public class GodotAudioSettings(AudioSettings audioSettings, AudioBusMapSettings audioBusMapSettings)
|
||||
: IApplyAbleSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用音频设置到Godot音频系统
|
||||
@ -16,9 +17,9 @@ public class GodotAudioSettings(AudioSettings settings, AudioBusMap busMap) : IA
|
||||
/// <returns>表示异步操作的任务</returns>
|
||||
public Task Apply()
|
||||
{
|
||||
SetBus(busMap.Master, settings.MasterVolume);
|
||||
SetBus(busMap.Bgm, settings.BgmVolume);
|
||||
SetBus(busMap.Sfx, settings.SfxVolume);
|
||||
SetBus(audioBusMapSettings.Master, audioSettings.MasterVolume);
|
||||
SetBus(audioBusMapSettings.Bgm, audioSettings.BgmVolume);
|
||||
SetBus(audioBusMapSettings.Sfx, audioSettings.SfxVolume);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@ -4,34 +4,34 @@ using Godot;
|
||||
namespace GFramework.Godot.setting;
|
||||
|
||||
/// <summary>
|
||||
/// Godot图形设置类,继承自GraphicsSettings并实现IApplyAbleSettings接口
|
||||
/// 用于管理游戏的图形显示设置,包括分辨率、全屏模式等
|
||||
/// Godot图形设置应用器
|
||||
/// </summary>
|
||||
public class GodotGraphicsSettings : GraphicsSettings, IApplyAbleSettings
|
||||
/// <param name="settings">图形设置配置对象</param>
|
||||
public class GodotGraphicsSettings(GraphicsSettings settings) : IApplyAbleSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步应用当前图形设置到游戏窗口
|
||||
/// 该方法会根据设置的分辨率、全屏状态等参数调整Godot窗口的显示属性
|
||||
/// 应用图形设置到Godot引擎
|
||||
/// </summary>
|
||||
/// <returns>表示异步操作的任务</returns>
|
||||
/// <returns>异步任务</returns>
|
||||
public async Task Apply()
|
||||
{
|
||||
var size = new Vector2I(ResolutionWidth, ResolutionHeight);
|
||||
// 创建分辨率向量
|
||||
var size = new Vector2I(settings.ResolutionWidth, settings.ResolutionHeight);
|
||||
|
||||
// 直接调用DisplayServer API,不使用异步或延迟
|
||||
// 1. 设置边框标志
|
||||
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, Fullscreen);
|
||||
// 设置窗口边框状态
|
||||
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, settings.Fullscreen);
|
||||
|
||||
// 2. 设置窗口模式
|
||||
// 设置窗口模式(全屏或窗口化)
|
||||
DisplayServer.WindowSetMode(
|
||||
Fullscreen ? DisplayServer.WindowMode.ExclusiveFullscreen : DisplayServer.WindowMode.Windowed
|
||||
settings.Fullscreen
|
||||
? DisplayServer.WindowMode.ExclusiveFullscreen
|
||||
: DisplayServer.WindowMode.Windowed
|
||||
);
|
||||
|
||||
// 3. 窗口化下设置尺寸和位置
|
||||
if (!Fullscreen)
|
||||
// 非全屏模式下设置窗口大小和居中位置
|
||||
if (!settings.Fullscreen)
|
||||
{
|
||||
DisplayServer.WindowSetSize(size);
|
||||
// 居中窗口
|
||||
var screen = DisplayServer.GetPrimaryScreen();
|
||||
var screenSize = DisplayServer.ScreenGetSize(screen);
|
||||
var pos = (screenSize - size) / 2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user