update readme
This commit is contained in:
@@ -12,7 +12,7 @@ ecs-framework 的目标是成为功能强大的框架。它为您构建游戏提
|
|||||||
## 交流群
|
## 交流群
|
||||||
点击链接加入群聊【ecs游戏框架交流】:https://jq.qq.com/?_wv=1027&k=29w1Nud6
|
点击链接加入群聊【ecs游戏框架交流】:https://jq.qq.com/?_wv=1027&k=29w1Nud6
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始 [进入文档](docs/getting_start.md)
|
||||||
- 初始化框架
|
- 初始化框架
|
||||||
```typescript
|
```typescript
|
||||||
es.Core.create();
|
es.Core.create();
|
||||||
|
|||||||
121
docs/create_entity_component.md
Normal file
121
docs/create_entity_component.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# 创建实体
|
||||||
|
|
||||||
|
实体必须依赖于场景,不能单独存在。创建实体方法由场景提供。
|
||||||
|
|
||||||
|
## 方式一
|
||||||
|
```typescript
|
||||||
|
// 通过全局快捷获取场景创建实体
|
||||||
|
const playerEntity = es.Core.scene.createEntity("player");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 方式二
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
// 通过场景内创建
|
||||||
|
const playerEntity = this.createEntity("player");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Transform
|
||||||
|
|
||||||
|
框架中提供的实体不同于其他框架实体,它更偏向于游戏使用,实体内含有`Transform`属性。可用于快速访问位置,旋转,缩放等。如果需要应用于游戏引擎,请再组件重写`onTransformChanged`监听这些属性的变化。
|
||||||
|
|
||||||
|
> 实体内包含对transform里位置、旋转、缩放的快捷tween方法。`tweenPositionTo`/`tweenLocalPositionTo`/`tweenScaleTo`/`tweenLocalScaleTo`/`tweenRotationDegreesTo`/`tweenLocalRotationDegreesTo`
|
||||||
|
|
||||||
|
### tag / setTag
|
||||||
|
|
||||||
|
实体还提供`tag`属性及`setTag`方法来快速设置实体的标记,可再场景中使用`findEntitiesWithTag`快速查询拥有该标记的实体或使用`findEntityWithTag`来查找第一个拥有该标记的实体,你可以把它当作组来使用。
|
||||||
|
|
||||||
|
### detachFromScene / attachToScene
|
||||||
|
当你不想实体与场景被销毁时一同被销毁。可先 `detachFromScene`,等待合适的时机再调用 `attachToScene` 放入新的场景。
|
||||||
|
|
||||||
|
|
||||||
|
# 创建组件
|
||||||
|
|
||||||
|
组件一般配合实体使用。组件需要继承 `es.Component` 来标识为组件,如果想让组件拥有每帧更新能力则额外继承`es.IUpdatable` 接口。在实现的`update`方法当中进行更新逻辑。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// es.IUpdatable接口为可选接口,如果不需要更新能力则不必继承
|
||||||
|
export class AComponent extends es.Component implements es.IUpdatable {
|
||||||
|
update() {
|
||||||
|
// 更新逻辑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 加入组件
|
||||||
|
|
||||||
|
组件必须挂载于实体上,不能单独存在,如果需要单独于场景的组件则参考 [es.SceneComponent](scene_component.md) 组件。
|
||||||
|
|
||||||
|
- 方式一:将现有的AComponent加入实体
|
||||||
|
```typescript
|
||||||
|
const aCom = playerEntity.addComponent(new AComponent());
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式二:在实体上直接创建组件
|
||||||
|
```typescript
|
||||||
|
const aCom = playerEntity.createComponent(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 获取组件
|
||||||
|
|
||||||
|
- 方式一: 根据类型获取找到满足条件的第一个组件
|
||||||
|
```typescript
|
||||||
|
// 不能保证已经加入场景
|
||||||
|
const aCom = playerEntity.getComponent(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 保证已经加入场景
|
||||||
|
const aCom = playerEntity.getComponentInScene(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式二: 尝试找到一个组件,返回是否找到组件标志,第二参数需要一个引用组件用于存储已找到的组件
|
||||||
|
```typescript
|
||||||
|
const outCom = new Ref<AComponent>();
|
||||||
|
const find = playerEntity.tryGetComponent(AComponent, outCom);
|
||||||
|
if (find) {
|
||||||
|
const aCom = outCom.value;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式三:获取该类型的组件,如果未找到则创建一个并返回
|
||||||
|
```typescript
|
||||||
|
const aCom = playerEntity.getOrCreateComponent(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式四:根据第二参数中的列表找到该类型的所有组件并返回
|
||||||
|
```typescript
|
||||||
|
const findArray: Component[] = [
|
||||||
|
new AComponent(),
|
||||||
|
new BComponent(),
|
||||||
|
new CComponent()
|
||||||
|
];
|
||||||
|
// findArray可不传,则在实体上寻找满足第一个条件的所有组件
|
||||||
|
const coms = playerEntity.getComponents(AComponent, findArray);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 组件是否存在
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const find = playerEntity.hasComponent(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 移除组件
|
||||||
|
|
||||||
|
- 方式一: 移除已实例组件
|
||||||
|
```typescript
|
||||||
|
playerEntity.removeComponent(aCom);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式二:移除满足类型的第一个组件
|
||||||
|
```typescript
|
||||||
|
playerEntity.removeComponentForType(AComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 方式三: 移除所有组件
|
||||||
|
```typescript
|
||||||
|
playerEntity.removeAllComponents();
|
||||||
|
```
|
||||||
68
docs/getting_start.md
Normal file
68
docs/getting_start.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# 如何开始
|
||||||
|
|
||||||
|
## 初始化框架
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 参数为false则开启debug模式
|
||||||
|
es.Core.create(false);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 分发帧事件
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 放置于引擎每帧更新处
|
||||||
|
// dt为可选参数,传入引擎的deltaTime代替框架内的es.Time.deltaTime
|
||||||
|
es.Core.emitter.emit(es.CoreEvents.frameUpdated, dt);
|
||||||
|
```
|
||||||
|
|
||||||
|
> 尽可能使用引擎的dt,以免再游戏暂停继续时由于dt导致的跳帧问题
|
||||||
|
|
||||||
|
> **您还需要一个默认的场景以使得游戏可以进行使用ecs框架以及物理类或tween系统**
|
||||||
|
|
||||||
|
## 创建场景类
|
||||||
|
|
||||||
|
场景类需要继承框架中的 `es.Scene`
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
/**
|
||||||
|
* 可重写方法,从contructor中调用这个函数
|
||||||
|
*/
|
||||||
|
initialize() {
|
||||||
|
console.log('initialize');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重写方法。当Core将这个场景设置为活动场景时调用
|
||||||
|
*/
|
||||||
|
onStart() {
|
||||||
|
console.log('onStart');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重写方法。当Core把这个场景从活动槽中移除时调用。
|
||||||
|
*/
|
||||||
|
unload() {
|
||||||
|
console.log('unload');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可重写方法。
|
||||||
|
*/
|
||||||
|
update() {
|
||||||
|
// 如果重写update方法 一定要调用该方法
|
||||||
|
// 不调用将导致实体无法加入/组件无法更新
|
||||||
|
super.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
要想激活该场景需要通过核心类 `Core` 来设置当前 `MainScene` 为使用的场景
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
es.Core.scene = new MainScene();
|
||||||
|
```
|
||||||
|
|
||||||
|
# 下一章节
|
||||||
|
- [创建实体与组件](create_entity_component.md)
|
||||||
|
- [创建系统](system.md)
|
||||||
71
docs/scene_component.md
Normal file
71
docs/scene_component.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# scene_component
|
||||||
|
这是一个场景组件的基类,如果您需要一个不在实体上的组件则继承它 `es.SceneComponent`。场景组件默认包含`update`/`onEnabled`/`onDisabled`/`onRemovedFromScene`,你可以对他们进行重载。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class ASceneComponent extends es.SceneComponent {
|
||||||
|
/**
|
||||||
|
* 在启用此SceneComponent时调用
|
||||||
|
*/
|
||||||
|
onEnabled() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当禁用此SceneComponent时调用
|
||||||
|
*/
|
||||||
|
onDisabled() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当该SceneComponent从场景中移除时调用
|
||||||
|
*/
|
||||||
|
onRemovedFromScene() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 场景组件需要添加至场景上, 通过场景中的 `addSceneComponent` 方法加入。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
const aSceneCom = this.addSceneComponent(new ASceneComponent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 如果想要获取该场景组件则通过`getSceneComponent`方法获取
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
const aSceneCom = this.getSceneComponent(ASceneComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 如果获取时发现没有可以自动创建则通过 `getOrCreateSceneComponent` 方法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
const aSceneCom = this.getOrCreateSceneComponent(ASceneComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 删除场景组件
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
this.removeSceneComponent(aSceneCom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
67
docs/system.md
Normal file
67
docs/system.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# system
|
||||||
|
系统是ecs的核心。你的游戏逻辑应该在这里进行处理,所有的实体及组件也会在这里进行集中处理。用于处理实体的系统叫做 `es.EntityProcessingSystem`。 你需要继承他并实现`processEntity(entity: Entity)`方法。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class ASystem extends es.EntityProcessingSystem {
|
||||||
|
processEntity(entity: Entity){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
系统也依赖于场景,如果想要系统被激活则需要使用场景中`addEntityProcessor`方法。系统被实例化需要传入一个`es.Matcher` 参数。
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
this.addEntityProcessor(new ASystem(es.Matcher.empty().all(AComponent)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Matcher
|
||||||
|
matcher是系统的匹配器,用于匹配满足条件的实体传入系统进行处理。如果想要一个空的匹配器则直接 `es.Matcher.empty()`
|
||||||
|
|
||||||
|
- all
|
||||||
|
同时拥有多个组件
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
es.Matcher.empty().all(AComponent, BComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
- one
|
||||||
|
拥有任意一个组件
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
es.Matcher.empty().one(AComponent, BComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
- exclude
|
||||||
|
拥有某些组件,并且不包含某些组件
|
||||||
|
```typescript
|
||||||
|
// 不包含CComponent或者DComponent
|
||||||
|
es.Matcher.empty().all(AComponent, BComponent).exclude(CComponent, DComponent);
|
||||||
|
|
||||||
|
// 不同时包含CComponent和DComponent
|
||||||
|
es.Matcher.empty().all(AComponent, BComponent).exclude(CComponent).exclude(DComponent);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 获取系统
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
const aSystem = this.getEntityProcessor(ASystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 移除系统
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class MainScene extends es.Scene {
|
||||||
|
onStart() {
|
||||||
|
this.removeEntityProcessor(aSystem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user