mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 12:33:30 +08:00
- 调整Core模块导航链接结构,从overview页面改为根路径 - 重构Core模块侧边栏,将原有的6个主要类别扩展为15个详细分类 - 精简Game模块侧边栏,保留场景管理和游戏设置两个主要功能 - 更新Godot集成模块侧边栏,新增协程、信号、存储等功能分类 - 修改源码生成器模块命名,将枚举扩展重命名为枚举生成器 - 新增抽象接口侧边栏,包含Core和Game抽象接口文档 - 调整教程模块顺序,新增入门教程和Godot集成教程分类 - 移除独立的API参考导航项,将其整合到相应模块中 - 修正生成器API文档链接路径错误问题
10 KiB
10 KiB
场景管理
GFramework.Game 模块提供的场景管理功能,实现游戏场景的加载、切换和状态管理
概述
GFramework.Game 提供了统一的场景管理系统,支持场景的异步加载、切换动画、状态保持等功能。通过场景管理,您可以优雅地处理游戏中的各种场景转换,如主菜单、游戏界面、设置菜单等。
核心特性
- 异步加载:支持后台异步加载场景,避免卡顿
- 场景切换动画:内置淡入淡出等切换效果
- 状态保持:场景切换时保持必要的游戏状态
- 场景栈:支持场景叠加(如弹出菜单)
- 资源管理:自动管理场景资源的加载和卸载
基本用法
定义场景
using GFramework.Game.scene;
public class GameScene : GameSceneBase
{
protected override void OnLoad()
{
// 场景加载时的初始化
}
protected override void OnUnload()
{
// 场景卸载时的清理
}
public override void OnEnter()
{
// 进入场景
}
public override void OnExit()
{
// 退出场景
}
}
场景管理器
using GFramework.Game.scene;
[ContextAware]
public partial class SceneManager : Node
{
private ISceneManager _sceneManager;
public override void _Ready()
{
_sceneManager = Context.GetSystem<ISceneManager>();
// 初始化场景管理器
_sceneManager.Initialize();
}
public async Task SwitchToGameScene()
{
await _sceneManager.SwitchSceneAsync<GameScene>();
}
}
场景加载
同步加载
适用于小场景的快速切换:
public void LoadMainMenu()
{
_sceneManager.SwitchScene<MainMenuScene>();
}
异步加载
大场景建议使用异步加载:
public async Task LoadGameLevel(string levelName)
{
// 显示加载界面
loadingUI.Show();
try
{
// 异步加载场景
await _sceneManager.SwitchSceneAsync<GameLevelScene>(scene =>
{
// 可以在这里传递场景参数
var gameScene = scene as GameLevelScene;
gameScene.LevelName = levelName;
});
GD.Print("场景加载完成");
}
catch (Exception ex)
{
GD.PrintErr($"场景加载失败: {ex.Message}");
loadingUI.ShowError();
}
finally
{
loadingUI.Hide();
}
}
加载进度
监听加载进度:
public async Task LoadSceneWithProgress<TScene>() where TScene : IScene
{
loadingUI.Show();
var progress = new Progress<float>(value =>
{
loadingUI.UpdateProgress(value * 100);
});
await _sceneManager.SwitchSceneAsync<TScene>(progress: progress);
loadingUI.Hide();
}
场景切换动画
内置切换效果
public async Task SwitchWithFade()
{
// 使用淡入淡出效果
await _sceneManager.SwitchSceneAsync<GameScene>(
transition: new FadeTransition(
duration: 0.5f,
fadeColor: Colors.Black
)
);
}
public async Task SlideTransition()
{
// 使用滑动效果
await _sceneManager.SwitchSceneAsync<GameScene>(
transition: new SlideTransition(
direction: Vector2.Left,
duration: 0.3f
)
);
}
自定义切换动画
public class CustomTransition : ISceneTransition
{
public float Duration { get; } = 1.0f;
public async Task PlayAsync(Node fromScene, Node toScene)
{
// 自定义动画逻辑
var tween = CreateTween();
// 旧场景缩小消失
tween.TweenProperty(fromScene, "scale", Vector2.Zero, Duration / 2)
.SetTrans(Tween.TransitionType.BackIn);
await ToSignal(tween, Tween.SignalName.Finished);
fromScene.Visible = false;
toScene.Visible = true;
toScene.Scale = Vector2.Zero;
// 新场景放大出现
tween = CreateTween();
tween.TweenProperty(toScene, "scale", Vector2.One, Duration / 2)
.SetTrans(Tween.TransitionType.BackOut);
await ToSignal(tween, Tween.SignalName.Finished);
}
}
场景栈
推送场景
将新场景推入栈中:
public void PushPauseMenu()
{
_sceneManager.PushScene<PauseMenuScene>();
}
弹出场景
弹出栈顶场景:
public void PopScene()
{
_sceneManager.PopScene();
}
示例:带返回的导航
public async Task NavigateToSettings()
{
// 保存当前场景引用
var previousScene = _sceneManager.CurrentScene;
// 推入设置场景
await _sceneManager.PushSceneAsync<SettingsScene>();
// 设置场景有返回按钮
await _sceneManager.PushSceneAsync<ConfirmDialog>(
data: new ConfirmData
{
Message = "是否保存设置?",
OnConfirm = () => _sceneManager.PopScene(), // 不保存,直接返回
OnCancel = () =>
{
// 保存设置后返回
SaveSettings();
_sceneManager.PopScene();
}
}
);
}
场景状态管理
保存状态
public class GameScene : GameSceneBase
{
private GameState _state;
protected override void OnLoad()
{
// 从存档加载状态
_state = LoadGameState();
}
protected override void OnUnload()
{
// 保存状态
SaveGameState(_state);
}
public override void OnExit()
{
// 清理工作
Cleanup();
}
}
跨场景数据传递
// 传递数据到新场景
await _sceneManager.SwitchSceneAsync<GameScene>(data: new GameData
{
Level = 5,
Difficulty = Difficulty.Hard,
ContinueToken = saveToken
});
// 在目标场景中接收数据
public class GameScene : GameSceneBase
{
public override void OnEnter(object data)
{
var gameData = data as GameData;
InitializeLevel(gameData.Level, gameData.Difficulty);
}
}
预加载策略
预加载资源
public void PreloadCommonResources()
{
_sceneManager.PreloadScene<MainMenuScene>();
_sceneManager.PreloadScene<GameLevelScene>(count: 3);
}
预加载配置
var config = new ScenePreloadConfig
{
PreloadCount = 5,
Priority = ResourceLoader.CacheMode.Cache,
Timeout = 30.0f
};
_sceneManager.ConfigurePreload(config);
资源管理
自动卸载
// 配置自动卸载策略
var unloadConfig = new SceneUnloadConfig
{
UnloadDelay = 30.0f, // 30秒后卸载
KeepReferences = true, // 保持引用
ForceUnloadOnMemoryPressure = true // 内存紧张时强制卸载
};
_sceneManager.ConfigureUnload(unloadConfig);
手动卸载
// 卸载指定场景
_sceneManager.UnloadScene<MainMenuScene>();
// 卸载所有场景
_sceneManager.UnloadAllScenes();
最佳实践
1. 场景设计原则
// 推荐:每个场景职责单一
public class MainMenuScene : GameSceneBase { /* 主菜单 */ }
public class SettingsScene : GameSceneBase { /* 设置菜单 */ }
public class GameHUDScene : GameSceneBase { /* 游戏HUD */ }
// 避免:场景职责过多
public class MegaScene : GameSceneBase
{
/* 包含菜单、设置、HUD、存档管理... 不要这样设计 */
}
2. 场景切换优化
// 推荐:使用异步加载
public async Task LoadGame()
{
loadingUI.Show("正在加载游戏...");
await _sceneManager.SwitchSceneAsync<GameScene>();
}
// 避免:同步加载大场景
public void LoadGame()
{
// 这会导致游戏卡顿
_sceneManager.SwitchScene<GameScene>();
}
3. 内存管理
public class GameScene : GameSceneBase
{
private Texture2D[] _largeTextures;
protected override void OnLoad()
{
// 加载资源
_largeTextures = LoadLargeTextures();
}
protected override void OnUnload()
{
// 及时释放大资源
foreach (var texture in _largeTextures)
{
texture.Dispose();
}
_largeTextures = null;
}
}
4. 错误处理
public async Task SafeLoadScene<TScene>() where TScene : IScene
{
try
{
await _sceneManager.SwitchSceneAsync<TScene>();
}
catch (SceneNotFoundException)
{
Logger.Error($"场景 {typeof(TScene)} 未找到");
// 回退到默认场景
await _sceneManager.SwitchSceneAsync<FallbackScene>();
}
catch (ResourceLoadException ex)
{
Logger.Error($"资源加载失败: {ex.Message}");
await ShowRetryDialog();
}
}
与其他模块集成
与 Game 模块集成
public class GameLevelScene : GameSceneBase
{
private GameManager _gameManager;
public override void OnEnter()
{
// 初始化游戏管理器
_gameManager = Context.GetSystem<GameManager>();
_gameManager.StartGame();
}
public override void OnExit()
{
_gameManager.EndGame();
}
}
与存档系统集成
public class GameScene : GameSceneBase
{
private ISaveSystem _saveSystem;
protected override void OnLoad()
{
_saveSystem = Context.GetUtility<ISaveSystem>();
// 检查是否有自动存档
if (_saveSystem.HasAutoSave())
{
var dialog = Context.GetSystem<IDialogSystem>();
await dialog.ShowAsync("发现自动存档,是否继续?",
onConfirm: () => LoadAutoSave(),
onCancel: () => StartNewGame()
);
}
}
private void LoadAutoSave()
{
var saveData = _saveSystem.LoadAutoSave();
RestoreGameState(saveData);
}
public override void OnExit()
{
// 自动保存
_saveSystem.SaveAutoSave(CreateSaveData());
}
}
相关文档: