From e2861b69d7bd228715ad2affc4b626050c3ce031 Mon Sep 17 00:00:00 2001 From: dgflash Date: Fri, 15 Apr 2022 10:46:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=84=9F=E8=B0=A2=20Hess=20=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20ecs=20=E6=A1=86=E6=9E=B6=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=E4=BA=8B=E4=BB=B6=E5=9C=A8?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=A4=9A=E5=AE=9E=E4=BD=93=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=B0=86=E6=89=B9=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=E7=A7=BB?= =?UTF-8?q?=E5=88=B0=E6=A1=86=E6=9E=B6=E5=B1=82=E5=AE=9E=E7=8E=B0=EF=BC=8C?= =?UTF-8?q?=E5=87=8F=E5=B0=8F=E4=B8=9A=E5=8A=A1=E5=B1=82=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +++ assets/main.scene | 2 +- assets/script/core/libs/ECS.ts | 81 ++++++++++---- .../script/game/account/bll/AccountNetData.ts | 74 ++++++------- .../script/game/common/ecs/position/MoveTo.ts | 104 +++++++++--------- assets/script/game/role/bll/RoleChangeJob.ts | 16 ++- assets/script/game/role/bll/RoleUpgrade.ts | 34 +++--- 7 files changed, 186 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index cf2a44b..895f8a5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ + # oops-framework #### 介绍 oops-framework 基于 Cocos Creato 3.x 开发的一款游戏框架 @@ -81,3 +87,12 @@ oops-framework 基于 Cocos Creato 3.x 开发的一款游戏框架 打开项目请用Cocos Creator v3.4.2 以上版本 #### 学习交流QQ群:798575969 + +#### 贡献榜 +| 时间 | 开发者 | 贡献内容 | +| ---------- | -------- | ------------------------------------------------------------------------------------------- | +| 2022-04.15 | Hess | 建议优化 ecs 框架所有生命周期事件在处理多实体时,将批处理逻辑移到框架层实现,减小业务代码量 | +| 2021-10-13 | laret | 修复 Dialog 类型的 UI 不能连续触发 | +| 2021-10-20 | dogegg | 支持添加 cc.Component 到 ecs 实体对象中 | +| 2022-02-18 | 匿名好友 | 修复 TimerManager 时间管理对象,在游戏最小化切到最大化时,定时间器不触发完成事件的问题 | + diff --git a/assets/main.scene b/assets/main.scene index 328aaea..a252e0c 100644 --- a/assets/main.scene +++ b/assets/main.scene @@ -227,7 +227,7 @@ "_priority": 1073741824, "_fov": 45, "_fovAxis": 0, - "_orthoHeight": 391.032967032967, + "_orthoHeight": 394.00651465798046, "_near": 1, "_far": 2000, "_color": { diff --git a/assets/script/core/libs/ECS.ts b/assets/script/core/libs/ECS.ts index af94a06..bbb07d7 100644 --- a/assets/script/core/libs/ECS.ts +++ b/assets/script/core/libs/ECS.ts @@ -527,6 +527,7 @@ export module ecs { } this.mask.set(compTid); + //@ts-ignore this[tmpCtor.compName] = ctor; this.compTid2Ctor.set(compTid, tmpCtor); ctor.ent = this; @@ -589,12 +590,14 @@ export module ecs { compName = ctor.compName; if (this.mask.has(componentTypeId)) { hasComp = true; + //@ts-ignore let comp = this[ctor.compName] as IComp; + //@ts-ignore comp.ent = null; if (isRecycle) { comp.reset(); if (comp.canRecycle) { - compPools.get(componentTypeId).push(comp); + compPools.get(componentTypeId)!.push(comp); } } else { @@ -604,6 +607,7 @@ export module ecs { } if (hasComp) { + //@ts-ignore this[compName] = null; this.mask.delete(componentTypeId); this.compTid2Ctor.delete(componentTypeId); @@ -703,6 +707,8 @@ export module ecs { } } + //#region Matcher + abstract class BaseOf { protected mask = new Mask(); public indices: number[] = []; @@ -918,6 +924,7 @@ export module ecs { return newMatcher; } } + //#endregion //#region System /** @@ -927,21 +934,28 @@ export module ecs { * 当实体从当前System移除,下次再次符合条件进入System也会执行上述流程。 */ export interface IEntityEnterSystem { - entityEnter(entities: E[]): void; + entityEnter(entity: E): void; } /** * 如果需要监听实体从当前System移除,需要实现这个接口。 */ export interface IEntityRemoveSystem { - entityRemove(entities: E[]): void; + entityRemove(entity: E): void; } /** * 第一次执行update */ export interface ISystemFirstUpdate { - firstUpdate(entities: E[]): void; + firstUpdate(entity: E): void; + } + + /** + * 执行update + */ + export interface ISystemUpdate { + update(entity: E): void; } export abstract class ComblockSystem { @@ -998,17 +1012,32 @@ export module ecs { return this.group.count > 0; } + /** + * 先执行entityEnter,最后执行firstUpdate + * @param dt + * @returns + */ private updateOnce(dt: number) { if (this.group.count === 0) { return; } + this.dt = dt; + // 处理刚进来的实体 if (this.enteredEntities!.size > 0) { - (this as unknown as IEntityEnterSystem).entityEnter(Array.from(this.enteredEntities!.values()) as E[]); + var entities = this.enteredEntities!.values(); + for (let entity of entities) { + (this as unknown as IEntityEnterSystem).entityEnter(entity); + } this.enteredEntities!.clear(); } - (this as unknown as ISystemFirstUpdate).firstUpdate(this.group.matchEntities); + + // 只执行firstUpdate + for (let entity of this.group.matchEntities) { + (this as unknown as ISystemFirstUpdate).firstUpdate(entity); + } + this.execute = this.tmpExecute!; this.execute(dt); this.tmpExecute = null; @@ -1020,37 +1049,51 @@ export module ecs { * @returns */ private execute0(dt: number): void { - if (this.group.count === 0) { - return; - } + if (this.group.count === 0) return; + this.dt = dt; - this.update(this.group.matchEntities); + + // 执行update + for (let entity of this.group.matchEntities) { + this.update(entity); + } } /** - * 先执行entityRemove,再执行entityEnter,最后执行update。 + * 先执行entityRemove,再执行entityEnter,最后执行update * @param dt * @returns */ private execute1(dt: number): void { if (this.removedEntities!.size > 0) { if (this.hasEntityRemove) { - (this as unknown as IEntityRemoveSystem).entityRemove(Array.from(this.removedEntities!.values()) as E[]); + var entities = this.removedEntities!.values(); + for (let entity of entities) { + (this as unknown as IEntityRemoveSystem).entityRemove(entity); + } } this.removedEntities!.clear(); } - if (this.group.count === 0) { - return; - } + + if (this.group.count === 0) return; + this.dt = dt; + // 处理刚进来的实体 if (this.enteredEntities!.size > 0) { if (this.hasEntityEnter) { - (this as unknown as IEntityEnterSystem).entityEnter(Array.from(this.enteredEntities!.values()) as E[]); + var entities = this.enteredEntities!.values(); + for (let entity of entities) { + (this as unknown as IEntityEnterSystem).entityEnter(entity); + } } this.enteredEntities!.clear(); } - this.update(this.group.matchEntities as E[]); + + // 执行update + for (let entity of this.group.matchEntities) { + this.update(entity); + } } /** @@ -1059,8 +1102,8 @@ export module ecs { * 根据提供的组件过滤实体。 */ abstract filter(): IMatcher; - // abstract update(entities: E[]): void; - update(entities: E[]) { }; // 避免不需要用update时写一些多余的代码 + + update(entity: E) { }; // 避免不需要用update时写一些多余的代码 } /** diff --git a/assets/script/game/account/bll/AccountNetData.ts b/assets/script/game/account/bll/AccountNetData.ts index 5f87f3e..56ddc7b 100644 --- a/assets/script/game/account/bll/AccountNetData.ts +++ b/assets/script/game/account/bll/AccountNetData.ts @@ -2,7 +2,7 @@ * @Author: dgflash * @Date: 2021-11-23 15:51:15 * @LastEditors: dgflash - * @LastEditTime: 2022-03-10 10:21:27 + * @LastEditTime: 2022-04-15 09:47:36 */ import { v3 } from "cc"; @@ -28,44 +28,42 @@ export class AccountNetDataSystem extends ecs.ComblockSystem implements ecs.IEnt return ecs.allOf(AccountNetDataComp, AccountModelComp); } - entityEnter(entities: Account[]): void { - for (let e of entities) { - var params: any = { - playerId: netConfig.dbid, - sessionKey: netConfig.sessionKey, - } - - let onComplete = { - target: this, - callback: (data: any) => { - // 设置本地存储的用户标识(用于下次登录不输入帐号) - this.setLocalStorage(data.id); - - // 创建玩家角色对象 - this.createRole(e, data); - - // 玩家登录成功事件 - Message.dispatchEvent(GameEvent.LoginSuccess); - } - } - // 请求登录游戏获取角色数据 - // netChannel.game.req("LoginAction", "loadPlayer", params, onComplete); - - // 离线测试代码开始 - var data = { - id: 1, - name: "Oops", - power: 10, - agile: 10, - physical: 10, - lv: 1, - jobId: 1 - } - onComplete.callback(data); - // 离线测试代码结束 - - e.remove(AccountNetDataComp); + entityEnter(e: Account): void { + var params: any = { + playerId: netConfig.dbid, + sessionKey: netConfig.sessionKey, } + + let onComplete = { + target: this, + callback: (data: any) => { + // 设置本地存储的用户标识(用于下次登录不输入帐号) + this.setLocalStorage(data.id); + + // 创建玩家角色对象 + this.createRole(e, data); + + // 玩家登录成功事件 + Message.dispatchEvent(GameEvent.LoginSuccess); + } + } + // 请求登录游戏获取角色数据 + // netChannel.game.req("LoginAction", "loadPlayer", params, onComplete); + + // 离线测试代码开始 + var data = { + id: 1, + name: "Oops", + power: 10, + agile: 10, + physical: 10, + lv: 1, + jobId: 1 + } + onComplete.callback(data); + // 离线测试代码结束 + + e.remove(AccountNetDataComp); } /** 创建角色对象(自定义逻辑) */ diff --git a/assets/script/game/common/ecs/position/MoveTo.ts b/assets/script/game/common/ecs/position/MoveTo.ts index 7a9568b..c951912 100644 --- a/assets/script/game/common/ecs/position/MoveTo.ts +++ b/assets/script/game/common/ecs/position/MoveTo.ts @@ -2,7 +2,7 @@ * @Author: dgflash * @Date: 2021-08-11 16:41:12 * @LastEditors: dgflash - * @LastEditTime: 2022-01-27 11:33:31 + * @LastEditTime: 2022-04-15 10:01:35 */ import { Node, Vec3 } from "cc"; import { Timer } from "../../../../core/common/manager/TimerManager"; @@ -63,73 +63,67 @@ export class MoveToSystem extends ecs.ComblockSystem implements ecs. return ecs.allOf(MoveToComp); } - entityEnter(entities: ecs.Entity[]): void { - for (let e of entities) { - e.add(VariableMoveToComponent); - } + entityEnter(e: ecs.Entity): void { + e.add(VariableMoveToComponent); } - entityRemove(entities: ecs.Entity[]): void { - for (let e of entities) { - e.remove(VariableMoveToComponent); - } + entityRemove(e: ecs.Entity): void { + e.remove(VariableMoveToComponent); } - update(entities: ecs.Entity[]) { - for (let e of entities) { - let move = e.get(MoveToComp); - let mtv = e.get(VariableMoveToComponent); - let end: Vec3; + update(e: ecs.Entity) { + let move = e.get(MoveToComp); + let mtv = e.get(VariableMoveToComponent); + let end: Vec3; - console.assert(move.speed > 0, "移动速度必须要大于零"); + console.assert(move.speed > 0, "移动速度必须要大于零"); - if (move.target instanceof Node) { - end = move.ns == Node.NodeSpace.WORLD ? move.target.worldPosition : move.target.position; - } - else { - end = move.target as Vec3; + if (move.target instanceof Node) { + end = move.ns == Node.NodeSpace.WORLD ? move.target.worldPosition : move.target.position; + } + else { + end = move.target as Vec3; + } + + // 目标移动后,重计算移动方向与移动到目标点的速度 + if (mtv.end == null || !mtv.end.strictEquals(end)) { + let target = end.clone(); + if (move.offsetVector) { + target = target.add(move.offsetVector); // 这里的问题 } - // 目标移动后,重计算移动方向与移动到目标点的速度 - if (mtv.end == null || !mtv.end.strictEquals(end)) { - let target = end.clone(); - if (move.offsetVector) { - target = target.add(move.offsetVector); // 这里的问题 - } + // 移动方向与移动数度 + let start = move.ns == Node.NodeSpace.WORLD ? move.node.worldPosition : move.node.position; + move.velocity = Vec3Util.sub(target, start).normalize(); - // 移动方向与移动数度 - let start = move.ns == Node.NodeSpace.WORLD ? move.node.worldPosition : move.node.position; - move.velocity = Vec3Util.sub(target, start).normalize(); + // 移动时间与目标偏位置计算 + let distance = Vec3.distance(start, target) - move.offset; - // 移动时间与目标偏位置计算 - let distance = Vec3.distance(start, target) - move.offset; - - move.onChange?.call(this); - - if (distance - move.offset <= 0) { - this.exit(e); - } - else { - mtv.timer.step = distance / move.speed; - mtv.end = end.clone(); - mtv.target = move.velocity.clone().multiplyScalar(distance).add(start); - } - } - - if (move.speed > 0) { - let trans = Vec3Util.mul(move.velocity, move.speed * this.dt); - move.node.translate(trans, Node.NodeSpace.LOCAL); - } - - // 移动完成事件 - if (mtv.timer.update(this.dt)) { - if (move.ns == Node.NodeSpace.WORLD) - move.node.worldPosition = mtv.target; - else - move.node.position = mtv.target; + move.onChange?.call(this); + if (distance - move.offset <= 0) { this.exit(e); } + else { + mtv.timer.step = distance / move.speed; + mtv.end = end.clone(); + mtv.target = move.velocity.clone().multiplyScalar(distance).add(start); + } + } + + if (move.speed > 0) { + let trans = Vec3Util.mul(move.velocity, move.speed * this.dt); + move.node.translate(trans, Node.NodeSpace.LOCAL); + } + + // 移动完成事件 + if (mtv.timer.update(this.dt)) { + if (move.ns == Node.NodeSpace.WORLD) + move.node.worldPosition = mtv.target; + else + move.node.position = mtv.target; + + this.exit(e); } } diff --git a/assets/script/game/role/bll/RoleChangeJob.ts b/assets/script/game/role/bll/RoleChangeJob.ts index 5863917..4aac585 100644 --- a/assets/script/game/role/bll/RoleChangeJob.ts +++ b/assets/script/game/role/bll/RoleChangeJob.ts @@ -2,7 +2,7 @@ * @Author: dgflash * @Date: 2022-01-25 17:49:26 * @LastEditors: dgflash - * @LastEditTime: 2022-03-10 13:47:35 + * @LastEditTime: 2022-04-15 09:37:39 */ import { Message } from "../../../core/common/event/MessageManager"; @@ -38,15 +38,13 @@ export class RoleChangeJobSystem extends ecs.ComblockSystem implements ecs.IEnti return ecs.allOf(RoleChangeJobComp, RoleModelJobComp); } - entityEnter(entities: Role[]): void { - for (let e of entities) { - // 数值更新 - e.RoleModelJob.id = e.RoleChangeJob.jobId; + entityEnter(e: Role): void { + // 数值更新 + e.RoleModelJob.id = e.RoleChangeJob.jobId; - // 转职事件,通知视图层逻辑刷新界面效果,实现两层逻辑分离 - Message.dispatchEvent(RoleEvent.ChangeJob); + // 转职事件,通知视图层逻辑刷新界面效果,实现两层逻辑分离 + Message.dispatchEvent(RoleEvent.ChangeJob); - e.remove(RoleChangeJobComp); - } + e.remove(RoleChangeJobComp); } } \ No newline at end of file diff --git a/assets/script/game/role/bll/RoleUpgrade.ts b/assets/script/game/role/bll/RoleUpgrade.ts index 04c786d..f6fd48b 100644 --- a/assets/script/game/role/bll/RoleUpgrade.ts +++ b/assets/script/game/role/bll/RoleUpgrade.ts @@ -21,27 +21,25 @@ export class RoleUpgradeSystem extends ecs.ComblockSystem implements ecs.IEntity return ecs.allOf(RoleUpgradeComp, RoleModelLevelComp); } - entityEnter(entities: Role[]): void { - for (let e of entities) { - let rm = e.RoleModel; - let rlm = e.RoleModelLevel; - let ru = e.RoleUpgrade; + entityEnter(e: Role): void { + let rm = e.RoleModel; + let rlm = e.RoleModelLevel; + let ru = e.RoleUpgrade; - if (ru.lv == 0) - rlm.vm.lv++; // 提升一级 - else - rlm.vm.lv = ru.lv; // 设置等级 + if (ru.lv == 0) + rlm.vm.lv++; // 提升一级 + else + rlm.vm.lv = ru.lv; // 设置等级 - // 当前等级配置 - rlm.rtluCurrent.init(rlm.vm.lv); - // 等级附加属性 - rm.attributes.get(RoleAttributeType.hp).level = rlm.rtluCurrent.hp; + // 当前等级配置 + rlm.rtluCurrent.init(rlm.vm.lv); + // 等级附加属性 + rm.attributes.get(RoleAttributeType.hp).level = rlm.rtluCurrent.hp; - // 下个等级配置 - rlm.rtluNext.init(rlm.vm.lv + 1); - rlm.vm.expNext = rlm.rtluNext.needexp; + // 下个等级配置 + rlm.rtluNext.init(rlm.vm.lv + 1); + rlm.vm.expNext = rlm.rtluNext.needexp; - e.remove(RoleUpgradeComp); - } + e.remove(RoleUpgradeComp); } } \ No newline at end of file