初始化
在本章中,您将会学习到:
- 什么是初始化模式
- 如何编写初始化实体
初始化模式
对于一个关卡来说,计算出一些全局变量并且供其它实体使用是很普遍的。
举个例子,舞台区域可能会随着屏幕的宽高比的变化而变化,显然如果我们在每次需要时都去计算一次是很不可取的。因此,我们可以在关卡开始前只计算一次,并将其存储在如 LevelData
的全局区块中即可。
我们创建初始化模式是为了实现这样一个目的: 有且仅有一个 Initialization
实体会在第一个被生成并且在合适的时机完成初始化工作,其它实体只会在 Initialization
实体销毁后生成。
让我们先初始化一个 Initialization
原型:
class Initialization: public Archetype {
public:
static constexpr const char* name = "My Initialization";
};
// ...
#ifdef play
using namespace playData;
+ #include"play/Initialization.cpp"
#elif tutorial
// ...
// ...
#ifdef play
buffer data, configuration;
build<
// Replace with your archetypes here
- Archetype
+ Initialization
>(configuration, data);
// ...
生成逻辑
对于我们的 Initialization
实体来说,它的生成逻辑很简单: 我们只需要确保它是第一个立即生成的即可。
为了保证它是第一个生成的,我们只需要保证它的 spawnOrder
回调函数的返回值小于其他实体的即可。
在此例中,我们使用 0
来当作它的返回值。
class Initialization: public Archetype {
// ...
SonolusApi spawnOrder() { return 0; }
// ...
};
初始化负载
初始化负载可以被放在实体生命周期的任何时期,特别是在 preprocess
和 updateSequential
回调函数中。
就目前而言,我们并没有任何初始化负载需要在 updateSequential
回调函数中执行。
preprocess
回调函数通常被用在关卡开始前,设置变换,游玩 UI,得分机制,生命机制等。我们需要编写设置菜单 UI 的代码便于我们能够退出开发关卡,下面是使用示例:
class Initialization: public Archetype {
// ...
SonolusApi preprocess() {
FUNCBEGIN
let menuWidth = 0.15 * ui.menuConfiguration.scale;
let menuHeight = 0.15 * ui.menuConfiguration.scale;
let menuX = screen.r - 0.05;
let menuY = screen.t - 0.05;
ui.menu.set(
menuX, menuY, // 菜单按钮位置
1, 1, // 菜单按钮锚点坐标
menuWidth, menuHeight, // 菜单按钮大小
0, // 旋转角度
ui.menuConfiguration.alpha, // 透明度
HorizontalAlign.Center, // 对齐方式
true // 是否需要背景
);
return VOID;
}
// ...
};
销毁
销毁 Initialization
实体与销毁其他实体是一样的: 只需要将 EntityDespawn
区块上的第 0
个值设置为 true
,这个实体就会在当前帧结束后自动销毁。
在此例中,我们只需要在 updateSequential
回调函数中编写即可。
class Initialization: public Archetype {
// ...
SonolusApi updateSequential() {
FUNCBEGIN
EntityDespawn.set(0, true);
return VOID;
}
// ...
};