168 lines
4.0 KiB
Markdown
168 lines
4.0 KiB
Markdown
# 04. 资源管理
|
||
|
||
Extra2D 提供了统一的资源管理系统,用于加载和管理游戏中的各种资源。
|
||
|
||
## 资源管理器
|
||
|
||
通过 `Application::instance().resources()` 访问资源管理器:
|
||
|
||
```cpp
|
||
auto& resources = Application::instance().resources();
|
||
```
|
||
|
||
## 支持的资源类型
|
||
|
||
| 资源类型 | 加载方法 | 说明 |
|
||
|---------|---------|------|
|
||
| 纹理 | `loadTexture()` | 图片文件 (PNG, JPG, etc.) |
|
||
| 字体 | `loadFont()` | TrueType 字体文件 |
|
||
| 音频 | `loadSound()` / `loadMusic()` | 音频文件 |
|
||
|
||
## 纹理加载
|
||
|
||
### 基本用法
|
||
|
||
```cpp
|
||
// 加载纹理
|
||
auto texture = resources.loadTexture("assets/images/player.png");
|
||
|
||
if (texture) {
|
||
// 创建精灵
|
||
auto sprite = Sprite::create(texture);
|
||
addChild(sprite);
|
||
}
|
||
```
|
||
|
||
### 纹理缓存
|
||
|
||
资源管理器会自动缓存已加载的纹理,多次加载同一文件会返回缓存的实例:
|
||
|
||
```cpp
|
||
// 第一次加载 - 从文件读取
|
||
auto tex1 = resources.loadTexture("assets/image.png");
|
||
|
||
// 第二次加载 - 返回缓存
|
||
auto tex2 = resources.loadTexture("assets/image.png");
|
||
|
||
// tex1 和 tex2 指向同一个纹理对象
|
||
```
|
||
|
||
## 字体加载
|
||
|
||
### 基本用法
|
||
|
||
```cpp
|
||
// 加载字体(指定字号)
|
||
auto font24 = resources.loadFont("assets/font.ttf", 24, true);
|
||
|
||
// 创建文本
|
||
auto text = Text::create("Hello World", font24);
|
||
addChild(text);
|
||
```
|
||
|
||
### 字体后备
|
||
|
||
支持设置后备字体,当主字体缺少某些字符时自动使用后备字体:
|
||
|
||
```cpp
|
||
// 加载主字体和后备字体
|
||
auto mainFont = resources.loadFont("assets/main.ttf", 24, true);
|
||
auto fallbackFont = resources.loadFont("assets/fallback.ttf", 24, true);
|
||
|
||
// 设置后备字体
|
||
mainFont->setFallback(fallbackFont);
|
||
```
|
||
|
||
## 资源路径
|
||
|
||
### 路径格式
|
||
|
||
```cpp
|
||
// 相对路径(相对于工作目录)
|
||
auto tex = resources.loadTexture("assets/images/player.png");
|
||
|
||
// Switch 平台使用 romfs
|
||
auto tex = resources.loadTexture("romfs:/images/player.png");
|
||
|
||
// SD 卡路径
|
||
auto tex = resources.loadTexture("sdmc:/switch/game/images/player.png");
|
||
```
|
||
|
||
### 路径辅助函数
|
||
|
||
```cpp
|
||
// 获取平台特定的资源路径
|
||
std::string path = ResourceManager::getPlatformPath("images/player.png");
|
||
// Windows: "assets/images/player.png"
|
||
// Switch: "romfs:/images/player.png"
|
||
```
|
||
|
||
## 资源释放
|
||
|
||
### 自动释放
|
||
|
||
资源使用智能指针管理,当没有引用时会自动释放:
|
||
|
||
```cpp
|
||
{
|
||
auto tex = resources.loadTexture("assets/temp.png");
|
||
// 使用纹理...
|
||
} // 超出作用域,如果没有其他引用,纹理自动释放
|
||
```
|
||
|
||
### 手动清理缓存
|
||
|
||
```cpp
|
||
// 清理未使用的资源
|
||
resources.cleanupUnused();
|
||
|
||
// 清空所有缓存(谨慎使用)
|
||
resources.clearCache();
|
||
```
|
||
|
||
## 完整示例
|
||
|
||
参考 `examples/push_box/StartScene.cpp`:
|
||
|
||
```cpp
|
||
void StartScene::onEnter() {
|
||
Scene::onEnter();
|
||
|
||
auto& app = Application::instance();
|
||
auto& resources = app.resources();
|
||
|
||
// 加载背景纹理
|
||
auto bgTex = resources.loadTexture("assets/images/start.jpg");
|
||
if (bgTex) {
|
||
auto background = Sprite::create(bgTex);
|
||
background->setAnchor(0.0f, 0.0f);
|
||
addChild(background);
|
||
}
|
||
|
||
// 加载音效图标纹理
|
||
auto soundOn = resources.loadTexture("assets/images/soundon.png");
|
||
auto soundOff = resources.loadTexture("assets/images/soundoff.png");
|
||
if (soundOn && soundOff) {
|
||
soundIcon_ = Sprite::create(g_SoundOpen ? soundOn : soundOff);
|
||
addChild(soundIcon_);
|
||
}
|
||
|
||
// 加载字体
|
||
font_ = resources.loadFont("assets/font.ttf", 28, true);
|
||
|
||
// 创建按钮...
|
||
}
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
1. **预加载资源** - 在场景 `onEnter()` 中加载所需资源
|
||
2. **检查资源有效性** - 始终检查加载结果是否为 nullptr
|
||
3. **复用资源** - 多次使用同一资源时保存指针,避免重复加载
|
||
4. **合理设置字号** - 字体加载时会生成对应字号的图集
|
||
|
||
## 下一步
|
||
|
||
- [05. 输入处理](./05_Input_Handling.md) - 学习输入处理
|
||
- [06. 碰撞检测](./06_Collision_Detection.md) - 学习碰撞检测系统
|