系统
系统包含游戏逻辑。它们通过参数声明需要的数据,ESEngine 自动注入。系统自动操作场景中所有匹配的实体。
定义系统
import { defineSystem, Res, Time, Query, Mut, LocalTransform, Velocity } from 'esengine';
const movementSystem = defineSystem( [Res(Time), Query(Mut(LocalTransform), Velocity)], (time, query) => { for (const [entity, transform, velocity] of query) { transform.position.x += velocity.linear.x * time.delta; transform.position.y += velocity.linear.y * time.delta; } });此系统自动处理场景中所有同时拥有 LocalTransform 和 Velocity 组件的实体。
defineSystem 接受两个参数:
- 参数列表 —
Query、Res、ResMut或Commands描述符的数组 - 函数 — 按相同顺序接收解析后的参数
注册系统
使用顶层函数注册系统:
import { addSystem, addStartupSystem, addSystemToSchedule, Schedule } from 'esengine';
addStartupSystem(setupSystem); // Schedule.StartupaddSystem(movementSystem); // Schedule.UpdateaddSystemToSchedule(Schedule.FixedUpdate, physicsSystem);Schedule 类型
| Schedule | 运行时机 |
|---|---|
Startup | 启动时运行一次 |
First | 每帧最先运行 |
PreUpdate | 每帧 Update 之前 |
Update | 每帧运行(主要游戏逻辑) |
PostUpdate | 每帧 Update 之后 |
Last | 每帧最后运行 |
FixedPreUpdate | 固定间隔,FixedUpdate 之前 |
FixedUpdate | 固定间隔(物理) |
FixedPostUpdate | 固定间隔,FixedUpdate 之后 |
系统参数
Commands
在运行时创建、修改和销毁实体:
import { Commands, Sprite, LocalTransform } from 'esengine';
defineSystem([Commands()], (cmds) => { // 创建新实体并添加组件(可链式调用) const bullet = cmds.spawn() .insert(LocalTransform, { position: { x: 0, y: 0, z: 0 } }) .insert(Sprite, { size: { x: 8, y: 8 } }) .id();
// 修改已有实体 cmds.entity(bullet) .insert(Velocity, { linear: { x: 100, y: 0 } }) .remove(Sprite);
// 销毁实体 cmds.despawn(bullet);
// 插入资源 cmds.insertResource(Score, { value: 0 });});Commands API
| 方法 | 返回值 | 说明 |
|---|---|---|
cmds.spawn() | EntityCommands | 创建新实体,返回构建器 |
cmds.entity(entity) | EntityCommands | 获取已有实体的构建器 |
cmds.despawn(entity) | Commands | 将实体加入销毁队列 |
cmds.insertResource(res, value) | Commands | 插入或覆盖资源 |
EntityCommands API
spawn() 和 entity() 返回 EntityCommands 构建器,所有方法可链式调用:
| 方法 | 返回值 | 说明 |
|---|---|---|
.insert(component, data?) | this | 添加或更新组件 |
.remove(component) | this | 移除组件 |
.id() | Entity | 获取实体 ID |
Query
遍历具有特定组件的实体:
import { Query, Mut, LocalTransform, Sprite } from 'esengine';
defineSystem([Query(Mut(LocalTransform), Sprite)], (query) => { for (const [entity, transform, sprite] of query) { transform.position.x += 1; }});详见查询。
Res(只读资源)
import { Res, Time } from 'esengine';
defineSystem([Res(Time)], (time) => { console.log(`Delta: ${time.delta}s`);});ResMut(可变资源)
import { ResMut } from 'esengine';
defineSystem([ResMut(GameState)], (state) => { state.value.score += 10;});详见资源。
组合参数
defineSystem( [Commands(), Res(Time), Res(Input), Query(Mut(LocalTransform), Velocity)], (cmds, time, input, query) => { // 所有参数都可用 });示例:玩家移动
定义 Speed 组件,在编辑器中挂载到玩家实体上,然后编写系统:
import { defineComponent } from 'esengine';export const Speed = defineComponent('Speed', { value: 200 });import { defineSystem, addSystem, Res, Time, Input, Query, Mut, LocalTransform } from 'esengine';import { Speed } from '../components/Speed';
addSystem(defineSystem( [Res(Time), Res(Input), Query(Mut(LocalTransform), Speed)], (time, input, query) => { for (const [entity, transform, speed] of query) { if (input.isKeyDown('KeyD')) { transform.position.x += speed.value * time.delta; } if (input.isKeyDown('KeyA')) { transform.position.x -= speed.value * time.delta; } } }));