@cc-component/cc-core 1.2.9 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/core/interface/App.ts +3 -0
- package/assets/core/interface/Interface.ts +1 -1
- package/assets/core/lib/ecs/.ecs.md +1 -0
- package/assets/core/lib/ecs/ECS.ts +329 -0
- package/assets/core/{home/BaseBoxView.ts.meta → lib/ecs/ECS.ts.meta} +1 -1
- package/assets/core/lib/ecs/ECSComp.ts +35 -0
- package/assets/core/{home/DouYinShow.ts.meta → lib/ecs/ECSComp.ts.meta} +1 -1
- package/assets/core/lib/ecs/ECSEntity.ts +302 -0
- package/assets/core/lib/ecs/ECSEntity.ts.meta +9 -0
- package/assets/core/lib/ecs/ECSGroup.ts +83 -0
- package/assets/core/lib/ecs/ECSGroup.ts.meta +9 -0
- package/assets/core/lib/ecs/ECSMask.ts +57 -0
- package/assets/core/lib/ecs/ECSMask.ts.meta +9 -0
- package/assets/core/lib/ecs/ECSMatcher.ts +215 -0
- package/assets/core/lib/ecs/ECSMatcher.ts.meta +9 -0
- package/assets/core/lib/ecs/ECSModel.ts +82 -0
- package/assets/core/lib/ecs/ECSModel.ts.meta +9 -0
- package/assets/core/lib/ecs/ECSSystem.ts +221 -0
- package/assets/core/lib/ecs/ECSSystem.ts.meta +9 -0
- package/assets/core/lib/ecs/IECS.ts.meta +9 -0
- package/assets/core/lib/ecs.meta +9 -0
- package/package.json +1 -1
- package/assets/core/home/BaseBoxView.ts +0 -57
- package/assets/core/home/DouYinShow.ts +0 -27
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: dgflash
|
|
3
|
+
* @Date: 2022-05-12 14:18:44
|
|
4
|
+
* @LastEditors: dgflash
|
|
5
|
+
* @LastEditTime: 2022-09-05 16:37:10
|
|
6
|
+
*/
|
|
7
|
+
import { ecs } from "./ECS";
|
|
8
|
+
import { ECSEntity } from "./ECSEntity";
|
|
9
|
+
import { ECSGroup } from "./ECSGroup";
|
|
10
|
+
|
|
11
|
+
type CompAddOrRemove = (entity: ecs.Entity) => void;
|
|
12
|
+
|
|
13
|
+
/** 组件类型 */
|
|
14
|
+
export type CompType<T> = CompCtor<T> | number;
|
|
15
|
+
|
|
16
|
+
/** 实体构造器接口 */
|
|
17
|
+
export interface EntityCtor<T> {
|
|
18
|
+
new(): T;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 组件构造器接口 */
|
|
22
|
+
export interface CompCtor<T> {
|
|
23
|
+
new(): T;
|
|
24
|
+
/** 组件编号 */
|
|
25
|
+
tid: number;
|
|
26
|
+
/** 组件名 */
|
|
27
|
+
compName: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** ECS框架内部数据 */
|
|
31
|
+
export class ECSModel {
|
|
32
|
+
/** 实体自增id */
|
|
33
|
+
static eid = 1;
|
|
34
|
+
/** 实体造函数 */
|
|
35
|
+
static entityCtors: Map<EntityCtor<any>, string> = new Map();
|
|
36
|
+
/** 实体对象缓存池 */
|
|
37
|
+
static entityPool: Map<string, ECSEntity[]> = new Map();
|
|
38
|
+
/** 通过实体id查找实体对象 */
|
|
39
|
+
static eid2Entity: Map<number, ECSEntity> = new Map();
|
|
40
|
+
|
|
41
|
+
/** 组件类型id */
|
|
42
|
+
static compTid = 0;
|
|
43
|
+
/** 组件缓存池 */
|
|
44
|
+
static compPools: Map<number, ecs.IComp[]> = new Map();
|
|
45
|
+
/** 组件构造函数,用于ecs.register注册时,记录不同类型的组件 */
|
|
46
|
+
static compCtors: (CompCtor<any> | number)[] = [];
|
|
47
|
+
/**
|
|
48
|
+
* 每个组件的添加和删除的动作都要派送到“关心”它们的group上。goup对当前拥有或者之前(删除前)拥有该组件的实体进行组件规则判断。判断该实体是否满足group
|
|
49
|
+
* 所期望的组件组合。
|
|
50
|
+
*/
|
|
51
|
+
static compAddOrRemove: Map<number, CompAddOrRemove[]> = new Map();
|
|
52
|
+
|
|
53
|
+
/** 编号获取组件 */
|
|
54
|
+
static tid2comp: Map<number, ecs.IComp> = new Map();
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 缓存的group
|
|
58
|
+
*
|
|
59
|
+
* key是组件的筛选规则,一个筛选规则对应一个group
|
|
60
|
+
*/
|
|
61
|
+
static groups: Map<number, ECSGroup> = new Map();
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 创建group,每个group只关心对应组件的添加和删除
|
|
65
|
+
* @param matcher 实体筛选器
|
|
66
|
+
*/
|
|
67
|
+
static createGroup<E extends ECSEntity = ECSEntity>(matcher: ecs.IMatcher): ECSGroup<E> {
|
|
68
|
+
let group = ECSModel.groups.get(matcher.mid);
|
|
69
|
+
if (!group) {
|
|
70
|
+
group = new ECSGroup(matcher);
|
|
71
|
+
ECSModel.groups.set(matcher.mid, group);
|
|
72
|
+
let careComponentTypeIds = matcher.indices;
|
|
73
|
+
for (let i = 0; i < careComponentTypeIds.length; i++) {
|
|
74
|
+
ECSModel.compAddOrRemove.get(careComponentTypeIds[i])!.push(group.onComponentAddOrRemove.bind(group));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return group as unknown as ECSGroup<E>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** 系统组件 */
|
|
81
|
+
static systems: Map<string, ecs.System> = new Map<string, ecs.System>();
|
|
82
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { ecs } from "./ECS";
|
|
2
|
+
import { ECSEntity } from "./ECSEntity";
|
|
3
|
+
import { ECSGroup } from "./ECSGroup";
|
|
4
|
+
import { ECSModel } from "./ECSModel";
|
|
5
|
+
|
|
6
|
+
/** 继承此类实现具体业务逻辑的系统 */
|
|
7
|
+
export abstract class ECSComblockSystem<E extends ECSEntity = ECSEntity> {
|
|
8
|
+
static s: boolean = true;
|
|
9
|
+
|
|
10
|
+
protected group: ECSGroup<E>;
|
|
11
|
+
protected dt: number = 0;
|
|
12
|
+
|
|
13
|
+
private enteredEntities: Map<number, E> = null!;
|
|
14
|
+
private removedEntities: Map<number, E> = null!;
|
|
15
|
+
|
|
16
|
+
private hasEntityEnter: boolean = false;
|
|
17
|
+
private hasEntityRemove: boolean = false;
|
|
18
|
+
private hasUpdate: boolean = false;
|
|
19
|
+
|
|
20
|
+
private tmpExecute: ((dt: number) => void) | null = null;
|
|
21
|
+
private execute!: (dt: number) => void;
|
|
22
|
+
|
|
23
|
+
/** 构造函数 */
|
|
24
|
+
constructor() {
|
|
25
|
+
let hasOwnProperty = Object.hasOwnProperty;
|
|
26
|
+
let prototype = Object.getPrototypeOf(this);
|
|
27
|
+
let hasEntityEnter = hasOwnProperty.call(prototype, 'entityEnter');
|
|
28
|
+
let hasEntityRemove = hasOwnProperty.call(prototype, 'entityRemove');
|
|
29
|
+
let hasFirstUpdate = hasOwnProperty.call(prototype, 'firstUpdate');
|
|
30
|
+
let hasUpdate = hasOwnProperty.call(prototype, 'update');
|
|
31
|
+
|
|
32
|
+
this.hasEntityEnter = hasEntityEnter;
|
|
33
|
+
this.hasEntityRemove = hasEntityRemove;
|
|
34
|
+
this.hasUpdate = hasUpdate;
|
|
35
|
+
|
|
36
|
+
if (hasEntityEnter || hasEntityRemove) {
|
|
37
|
+
this.enteredEntities = new Map<number, E>();
|
|
38
|
+
this.removedEntities = new Map<number, E>();
|
|
39
|
+
|
|
40
|
+
this.execute = this.execute1;
|
|
41
|
+
this.group = ECSModel.createGroup(this.filter());
|
|
42
|
+
this.group.watchEntityEnterAndRemove(this.enteredEntities, this.removedEntities);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.execute = this.execute0;
|
|
46
|
+
this.group = ECSModel.createGroup(this.filter());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (hasFirstUpdate) {
|
|
50
|
+
this.tmpExecute = this.execute;
|
|
51
|
+
this.execute = this.updateOnce;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 系统实始化 */
|
|
56
|
+
init(): void {
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 系统释放事件 */
|
|
61
|
+
onDestroy(): void {
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** 是否存在实体 */
|
|
66
|
+
hasEntity(): boolean {
|
|
67
|
+
return this.group.count > 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 先执行entityEnter,最后执行firstUpdate
|
|
72
|
+
* @param dt
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
private updateOnce(dt: number) {
|
|
76
|
+
if (this.group.count === 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.dt = dt;
|
|
81
|
+
|
|
82
|
+
// 处理刚进来的实体
|
|
83
|
+
if (this.enteredEntities.size > 0) {
|
|
84
|
+
var entities = this.enteredEntities.values();
|
|
85
|
+
for (let entity of entities) {
|
|
86
|
+
(this as unknown as ecs.IEntityEnterSystem).entityEnter(entity);
|
|
87
|
+
}
|
|
88
|
+
this.enteredEntities.clear();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 只执行firstUpdate
|
|
92
|
+
for (let entity of this.group.matchEntities) {
|
|
93
|
+
(this as unknown as ecs.ISystemFirstUpdate).firstUpdate(entity);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.execute = this.tmpExecute!;
|
|
97
|
+
this.execute(dt);
|
|
98
|
+
this.tmpExecute = null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 只执行update
|
|
103
|
+
* @param dt
|
|
104
|
+
* @returns
|
|
105
|
+
*/
|
|
106
|
+
private execute0(dt: number): void {
|
|
107
|
+
if (this.group.count === 0) return;
|
|
108
|
+
|
|
109
|
+
this.dt = dt;
|
|
110
|
+
|
|
111
|
+
// 执行update
|
|
112
|
+
if (this.hasUpdate) {
|
|
113
|
+
for (let entity of this.group.matchEntities) {
|
|
114
|
+
(this as unknown as ecs.ISystemUpdate).update(entity);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 先执行entityRemove,再执行entityEnter,最后执行update
|
|
121
|
+
* @param dt
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
private execute1(dt: number): void {
|
|
125
|
+
let entities;
|
|
126
|
+
if (this.removedEntities.size > 0) {
|
|
127
|
+
if (this.hasEntityRemove) {
|
|
128
|
+
entities = this.removedEntities.values();
|
|
129
|
+
for (let entity of entities) {
|
|
130
|
+
(this as unknown as ecs.IEntityRemoveSystem).entityRemove(entity);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
this.removedEntities.clear();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (this.group.count === 0) return;
|
|
137
|
+
|
|
138
|
+
this.dt = dt;
|
|
139
|
+
|
|
140
|
+
// 处理刚进来的实体
|
|
141
|
+
if (this.enteredEntities!.size > 0) {
|
|
142
|
+
if (this.hasEntityEnter) {
|
|
143
|
+
entities = this.enteredEntities!.values();
|
|
144
|
+
for (let entity of entities) {
|
|
145
|
+
(this as unknown as ecs.IEntityEnterSystem).entityEnter(entity);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
this.enteredEntities!.clear();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 执行update
|
|
152
|
+
if (this.hasUpdate) {
|
|
153
|
+
for (let entity of this.group.matchEntities) {
|
|
154
|
+
(this as unknown as ecs.ISystemUpdate).update(entity);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 实体过滤规则
|
|
161
|
+
*
|
|
162
|
+
* 根据提供的组件过滤实体。
|
|
163
|
+
*/
|
|
164
|
+
abstract filter(): ecs.IMatcher;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** 根System,对游戏中的System遍历从这里开始,一个System组合中只能有一个RootSystem,可以有多个并行的RootSystem */
|
|
168
|
+
export class ECSRootSystem {
|
|
169
|
+
private executeSystemFlows: ECSComblockSystem[] = [];
|
|
170
|
+
private systemCnt: number = 0;
|
|
171
|
+
|
|
172
|
+
add(system: ECSSystem | ECSComblockSystem) {
|
|
173
|
+
if (system instanceof ECSSystem) {
|
|
174
|
+
// 将嵌套的System都“摊平”,放在根System中进行遍历,减少execute的频繁进入退出。
|
|
175
|
+
Array.prototype.push.apply(this.executeSystemFlows, system.comblockSystems);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
this.executeSystemFlows.push(system as ECSComblockSystem);
|
|
179
|
+
}
|
|
180
|
+
this.systemCnt = this.executeSystemFlows.length;
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
init() {
|
|
185
|
+
// 自动注册系统组件
|
|
186
|
+
ECSModel.systems.forEach(sys => this.add(sys));
|
|
187
|
+
|
|
188
|
+
// 初始化组件
|
|
189
|
+
this.executeSystemFlows.forEach(sys => sys.init());
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
execute(dt: number) {
|
|
193
|
+
for (let i = 0; i < this.systemCnt; i++) {
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
this.executeSystemFlows[i].execute(dt);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
clear() {
|
|
200
|
+
this.executeSystemFlows.forEach(sys => sys.onDestroy());
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** 系统组合器,用于将多个相同功能模块的系统逻辑上放在一起,系统也可以嵌套系统 */
|
|
205
|
+
export class ECSSystem {
|
|
206
|
+
private _comblockSystems: ECSComblockSystem[] = [];
|
|
207
|
+
get comblockSystems() {
|
|
208
|
+
return this._comblockSystems;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
add(system: ECSSystem | ECSComblockSystem) {
|
|
212
|
+
if (system instanceof ECSSystem) {
|
|
213
|
+
Array.prototype.push.apply(this._comblockSystems, system._comblockSystems);
|
|
214
|
+
system._comblockSystems.length = 0;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this._comblockSystems.push(system as ECSComblockSystem);
|
|
218
|
+
}
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
}
|
package/package.json
CHANGED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { _decorator, Component, Node, Size, UITransform, v2, Vec2 } from 'cc';
|
|
2
|
-
const { ccclass, property } = _decorator;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@ccclass('BaseBoxView')
|
|
6
|
-
export class BaseBoxView extends Component {
|
|
7
|
-
box_size: any = { width: 100, height: 100 };//获取碰撞盒大小
|
|
8
|
-
box_node: Node;
|
|
9
|
-
box_center: Node;
|
|
10
|
-
box_node_ut: UITransform;
|
|
11
|
-
|
|
12
|
-
ut: UITransform;
|
|
13
|
-
|
|
14
|
-
protected onLoad(): void {
|
|
15
|
-
this.ut = this.node.getComponent(UITransform);
|
|
16
|
-
if (this.box_node) {
|
|
17
|
-
this.box_node_ut = this.box_node.getComponent(UITransform);
|
|
18
|
-
this.node.BoxView = this;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
UpdateBox(target: Node) {
|
|
24
|
-
// const data = CommonModule.Get_MapCenter().map_view.GetMapModel(0, 0)
|
|
25
|
-
// target = data.node;
|
|
26
|
-
// if (this.box_node) {
|
|
27
|
-
// this.box_node.scale = target.scale;
|
|
28
|
-
// const targetUT = target.getComponent(UITransform);
|
|
29
|
-
// this.box_node_ut.anchorPoint = v2(0.5, 0);
|
|
30
|
-
// this.box_node_ut.contentSize = new Size(targetUT.contentSize.width, targetUT.contentSize.height);
|
|
31
|
-
// this.box_size.width = this.box_node_ut.width;
|
|
32
|
-
// this.box_size.height = this.box_node_ut.height;
|
|
33
|
-
// }
|
|
34
|
-
}
|
|
35
|
-
// Collision(target_enemy: BoxView) {
|
|
36
|
-
// const box1 = this.GetBox(this);
|
|
37
|
-
// const box2 = this.GetBox(this.target_enemy);
|
|
38
|
-
|
|
39
|
-
// const ok = App.Collision(box1, box2);
|
|
40
|
-
// // Logger.debug("碰撞了吗?", ok, this.node.name)
|
|
41
|
-
// return ok
|
|
42
|
-
// }
|
|
43
|
-
|
|
44
|
-
public GetBox() {
|
|
45
|
-
const player = this;
|
|
46
|
-
const node = this.box_node;
|
|
47
|
-
const width = this.box_size.width;
|
|
48
|
-
const height = this.box_size.height;
|
|
49
|
-
const x = node.worldPosition.x - width * 0.5;
|
|
50
|
-
const y = node.worldPosition.y - height * 0.5;
|
|
51
|
-
return {
|
|
52
|
-
x1: x, y1: y,
|
|
53
|
-
x2: x + player.box_size.width, y2: y + player.box_size.height
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { _decorator, CCBoolean, Component, Node } from 'cc';
|
|
2
|
-
import { BYTEDANCE } from 'cc/env';
|
|
3
|
-
const { ccclass, property } = _decorator;
|
|
4
|
-
|
|
5
|
-
@ccclass('DouYinShow')
|
|
6
|
-
export class DouYinShow extends Component {
|
|
7
|
-
|
|
8
|
-
@property({})
|
|
9
|
-
isTip = false;
|
|
10
|
-
protected onLoad(): void {
|
|
11
|
-
if (BYTEDANCE) {
|
|
12
|
-
if (!App.IsDouYin() && !this.isTip) {
|
|
13
|
-
this.node.active = false;
|
|
14
|
-
} else {
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
start() {
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
update(deltaTime: number) {
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|