跳转到内容

插件与资源

一个 Estella 游戏就是由插件组合成的 App。每个子系统——物理、音频、瓦片地图、 粒子、UI 等等——都是一个插件,它注册自己的系统,并把运行时 API 暴露为一个资源

在系统里,把你需要的资源列进参数数组;回调会按同样的顺序收到它:

import { defineSystem, Res, Audio } from 'esengine';
defineSystem([Res(Audio)], (audio) => {
audio.playSFX('assets/hit.wav');
});

每个子系统的命令式 API 都用同一种方式取用:

子系统 资源 指南
输入 Res(Input) 输入
音频 Res(Audio) 音频
资源 Res(Assets) 资源
瓦片地图 Res(Tilemaps) 瓦片地图
粒子 Res(Particle) 粒子
后处理 Res(PostProcess) 后处理
场景 Res(SceneManager) 场景
补间 Res(Tween) 动画
帧动画 Res(SpriteAnimation) 动画
动画机 Res(AnimatorController) 动画
计时器 Res(TimerRes) 脚本
时间轴 Res(Timeline) 时间轴
预制体 Res(Prefabs) 预制体
导航 / AI Res(Nav) 游戏 AI
本地化 Res(Localization) 本地化
相机视图 Res(CameraView) 相机
UI 事件 Res(UIEvents) UI
物理 Res(Physics) —— 来自 esengine/physics 物理
Spine Res(Spine) —— 来自 esengine/spine Spine

物理和 Spine 是可选 side-module,按需加载,因此它们的 API 放在子路径上以保持基础 包精简;其余都在主 esengine 包里。上表的基础子系统都随标准 App 附带——无需接线。

有些子系统还按同一范式发布事件资源——内容是本帧事件、当帧读取的资源: Res(PhysicsEvents)(碰撞接触)、Res(SpineEvents)(动画事件)、 Res(UIEvents)(控件的点击与输入)。


Res(X) 是读取;当系统要替换或改动资源的状态时用 ResMut(X)——与组件上的 Mut 是同一契约。

  • 组件是逐实体的数据。你(在编辑器里或用 Commands)把它挂到实体上,用 Query 遍历它。
  • 资源是逐 App 的单例——共享状态与子系统 API——用 Res 读取。

子系统 API 作用于某个实体,而这个实体来自一个 Query(或一次 spawn)。这是你在各专题 里会反复看到的写法:

import { defineSystem, Query, Res, SpriteAnimator, Tween, TweenTarget } from 'esengine';
defineSystem([Query(SpriteAnimator), Res(Tween)], (q, tween) => {
for (const [entity] of q) {
tween.to(entity, TweenTarget.PositionX, 0, 100, 1.0, {});
}
});

要在系统里创建实体并挂组件,取一个 Commands():

import { defineSystem, Commands, Transform, Sprite } from 'esengine';
defineSystem([Commands()], (cmds) => {
cmds.spawn()
.insert(Transform, { position: { x: 0, y: 0, z: 0 } })
.insert(Sprite, { size: { x: 32, y: 32 } });
});