mirror of
https://gitee.com/dgflash/oops-framework.git
synced 2026-06-18 19:52:10 +08:00
最新版ECS模块开发模板DEMO
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 13:36:16
|
||||
*/
|
||||
import { game, setDisplayStats, _decorator } from 'cc';
|
||||
import { DEBUG } from 'cc/env';
|
||||
import { engine } from './core/Engine';
|
||||
import { LayerType, UIConfig } from './core/gui/layer/LayerManager';
|
||||
import { Root } from './core/Root';
|
||||
import { Demo } from './ecs/entity/Demo';
|
||||
import { RootSystem } from './ecs/RootSystem';
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
export enum UIID {
|
||||
UILoading = 0,
|
||||
@@ -38,6 +44,22 @@ export class Main extends Root {
|
||||
protected run() {
|
||||
engine.gui.init(UICF);
|
||||
engine.gui.open(UIID.UILoading);
|
||||
|
||||
this.ecs_demo();
|
||||
}
|
||||
|
||||
/** 通过ECS设计通用业务组件来复用 */
|
||||
private async ecs_demo() {
|
||||
Demo.load(() => {
|
||||
var a = new Demo();
|
||||
a.init(1);
|
||||
|
||||
// 模块业务逻辑
|
||||
a.login();
|
||||
|
||||
// 模块视图
|
||||
a.show(this.node);
|
||||
});
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-11 19:42:56
|
||||
*/
|
||||
import { Component, director, game, Game, log, Node, view, _decorator } from "cc";
|
||||
import { config } from "../game/config/Config";
|
||||
import { EngineMessage } from "./common/event/EngineMessage";
|
||||
@@ -28,7 +34,7 @@ export class Root extends Component {
|
||||
engine.init(this);
|
||||
|
||||
// 加载游戏配置
|
||||
config.init(this.run);
|
||||
config.init(this.run.bind(this));
|
||||
}
|
||||
|
||||
/** 加载完引擎配置文件后执行 */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-08-18 17:00:59
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-09-28 15:21:21
|
||||
* @LastEditTime: 2021-11-12 11:59:32
|
||||
*/
|
||||
|
||||
import { error, JsonAsset } from "cc";
|
||||
@@ -13,36 +13,23 @@ import { resLoader } from "../common/loader/ResLoader";
|
||||
|
||||
var data: Map<string, any> = new Map();
|
||||
export class JsonUtil {
|
||||
static getData(name: string): any {
|
||||
static get(name: string): any {
|
||||
if (data.has(name))
|
||||
return data.get(name);
|
||||
else
|
||||
return new Promise((resolve, reject) => {
|
||||
var url = GameConfig.getConfigPath(name);
|
||||
resLoader.load(url, JsonAsset, (err: Error | null, content: JsonAsset) => {
|
||||
if (err) {
|
||||
error(err.message);
|
||||
}
|
||||
data.set(name, content.json);
|
||||
resolve(content.json);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static get(name: string): any {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (data.has(name))
|
||||
resolve(data.get(name));
|
||||
else {
|
||||
var url = GameConfig.getConfigPath(name);
|
||||
resLoader.load(url, JsonAsset, (err: Error | null, content: JsonAsset) => {
|
||||
if (err) {
|
||||
error(err.message);
|
||||
}
|
||||
data.set(name, content.json);
|
||||
resolve(content.json);
|
||||
});
|
||||
}
|
||||
});
|
||||
static load(name: string, callback: Function): void {
|
||||
if (data.has(name))
|
||||
callback(data.get(name));
|
||||
else {
|
||||
var url = GameConfig.getConfigPath(name);
|
||||
resLoader.load(url, JsonAsset, (err: Error | null, content: JsonAsset) => {
|
||||
if (err) {
|
||||
error(err.message);
|
||||
}
|
||||
data.set(name, content.json);
|
||||
callback(content.json)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 10:41:50
|
||||
*/
|
||||
import { ecs } from "../core/libs/ECS";
|
||||
import { EcsDemoSystem } from "./system/EcsDemoSystem";
|
||||
|
||||
export class RootSystem extends ecs.RootSystem {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// this.add(new AutoCreateEnemySystem());
|
||||
// this.add(new AutoMoveToSystem());
|
||||
// this.add(new EcsMgobeSystem());
|
||||
// this.add(new EcsInputSystem());
|
||||
// this.add(new EcsRotationSystem());
|
||||
// this.add(new EcsPositionSystem());
|
||||
this.add(new EcsDemoSystem());
|
||||
}
|
||||
}
|
||||
|
||||
37
assets/script/ecs/component/CCComp.ts
Normal file
37
assets/script/ecs/component/CCComp.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 19:05:32
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 11:46:24
|
||||
*/
|
||||
|
||||
import { Component, _decorator } from "cc";
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* ECS结合Cocos Creator组件
|
||||
* 使用方法:
|
||||
* 1、ECS结合Cocos Creator组件可独立形成一个ECS的复杂视图实例对象
|
||||
* 2、对网络游戏,优先有数据对象,在才创建视图组件的流程,在释放视图组件时,不释放数据对象
|
||||
*/
|
||||
@ccclass('CCComp')
|
||||
export abstract class CCComp extends Component implements ecs.IComp {
|
||||
static tid: number = -1;
|
||||
static compName: string;
|
||||
|
||||
canRecycle!: boolean;
|
||||
ent!: ecs.Entity;
|
||||
|
||||
onLoad() {
|
||||
this.ent = ecs.createEntity();
|
||||
this.ent.add(this);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
this.ent.destroy();
|
||||
}
|
||||
|
||||
abstract reset(): void;
|
||||
}
|
||||
9
assets/script/ecs/component/CCComp.ts.meta
Normal file
9
assets/script/ecs/component/CCComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "1329d483-ea72-4225-a71c-7f7a235b0dac",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
17
assets/script/ecs/component/DemoBllLoginComp.ts
Normal file
17
assets/script/ecs/component/DemoBllLoginComp.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-12 10:47:04
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 11:18:56
|
||||
*/
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
|
||||
/** 登录组件 */
|
||||
@ecs.register('DemoBllLogin')
|
||||
export class DemoBllLoginComp extends ecs.Comp {
|
||||
playerId: number = -1;
|
||||
|
||||
reset() {
|
||||
this.playerId = -1;
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/component/DemoBllLoginComp.ts.meta
Normal file
9
assets/script/ecs/component/DemoBllLoginComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f4c96747-a764-4a4f-9161-63a68ee8aecb",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
35
assets/script/ecs/component/DemoModelTableComp.ts
Normal file
35
assets/script/ecs/component/DemoModelTableComp.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-12 10:02:31
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 10:47:38
|
||||
*/
|
||||
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
import { JsonUtil } from "../../core/utils/JsonUtil";
|
||||
|
||||
/** 静态数据表组件 */
|
||||
@ecs.register('DemoModelTable')
|
||||
export class DemoModelTableComp extends ecs.Comp {
|
||||
static TableName: string = "NetCode";
|
||||
|
||||
/** 静态数据表 */
|
||||
table: any;
|
||||
/** 静态表中一条数据 */
|
||||
data: any;
|
||||
|
||||
init(id: number) {
|
||||
var table = JsonUtil.get(DemoModelTableComp.TableName);
|
||||
this.data = table[id];
|
||||
}
|
||||
|
||||
get describe(): string {
|
||||
return this.data.describe;
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/component/DemoModelTableComp.ts.meta
Normal file
9
assets/script/ecs/component/DemoModelTableComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "8d0c16b0-b4ff-4324-9bc1-2d75c78e9db1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
41
assets/script/ecs/component/DemoViewComp.ts
Normal file
41
assets/script/ecs/component/DemoViewComp.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 17:52:54
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 11:29:20
|
||||
*/
|
||||
|
||||
import { _decorator } from "cc";
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
import { CCComp } from "./CCComp";
|
||||
import { DemoViewMovementComp } from "./DemoViewMovementComp";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* 视图层外观组件
|
||||
* 组件自身即是ECS组件,也是ECS实体,实体上可添加实现界面逻辑的ECS组件代码
|
||||
*/
|
||||
@ccclass('DemoViewComp')
|
||||
@ecs.register('DemoViewComp', false)
|
||||
export class DemoViewComp extends CCComp {
|
||||
@property({
|
||||
type: DemoViewMovementComp
|
||||
})
|
||||
movement: DemoViewMovementComp = null!;
|
||||
|
||||
onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
this.ent.add(this.movement);
|
||||
}
|
||||
|
||||
update(dt: number): void {
|
||||
this.movement.update(dt);
|
||||
this.node.position = this.movement.pos;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.movement = null!;
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/component/DemoViewComp.ts.meta
Normal file
9
assets/script/ecs/component/DemoViewComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "033c35f2-5cb9-44fc-8b3c-7eb86bb817f4",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
57
assets/script/ecs/component/DemoViewMovementComp.ts
Normal file
57
assets/script/ecs/component/DemoViewMovementComp.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 19:12:25
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 10:47:52
|
||||
*/
|
||||
import { toDegree, v3, Vec3, _decorator } from "cc";
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 视图逻辑组件 */
|
||||
@ccclass('DemoViewMovementComp')
|
||||
@ecs.register('DemoViewMovementComp')
|
||||
export class DemoViewMovementComp extends ecs.Comp {
|
||||
pos: Vec3 = v3();
|
||||
angle: number = 0;
|
||||
speed: number = 0;
|
||||
|
||||
@property
|
||||
acceleration: number = 0;
|
||||
|
||||
@property
|
||||
private _maxSpeed: number = 0;
|
||||
@property
|
||||
set maxSpeed(val: number) {
|
||||
this._maxSpeed = val;
|
||||
}
|
||||
get maxSpeed() {
|
||||
return this._maxSpeed;
|
||||
}
|
||||
|
||||
@property
|
||||
heading: Vec3 = v3();
|
||||
|
||||
@property
|
||||
targetHeading: Vec3 = v3();
|
||||
|
||||
reset() {
|
||||
|
||||
}
|
||||
|
||||
/** 只处理数据逻辑的直接写在ECS组件里 */
|
||||
update(dt: number) {
|
||||
if (!Vec3.equals(this.heading, this.targetHeading, 0.01)) {
|
||||
let outV3 = v3();
|
||||
Vec3.subtract(outV3, this.targetHeading, this.heading);
|
||||
outV3.multiplyScalar(0.025);
|
||||
this.heading.add(outV3);
|
||||
this.heading.normalize();
|
||||
this.angle = toDegree(Math.atan2(this.heading.y, this.heading.x)) - 90;
|
||||
}
|
||||
|
||||
this.speed = Math.min(this.speed + this.acceleration * dt, this._maxSpeed);
|
||||
|
||||
this.pos.add3f(this.heading.x * this.speed * dt, this.heading.y * this.speed * dt, 0);
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/component/DemoViewMovementComp.ts.meta
Normal file
9
assets/script/ecs/component/DemoViewMovementComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "8de4a716-cb33-4e3c-bff1-1a35d0d86b5d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
50
assets/script/ecs/entity/Demo.ts
Normal file
50
assets/script/ecs/entity/Demo.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 17:45:23
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 12:02:25
|
||||
*/
|
||||
|
||||
import { find, Node } from "cc";
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
import { JsonUtil } from "../../core/utils/JsonUtil";
|
||||
import { DemoBllLoginComp } from "../component/DemoBllLoginComp";
|
||||
import { DemoModelTableComp } from "../component/DemoModelTableComp";
|
||||
import { DemoViewComp } from "../component/DemoViewComp";
|
||||
|
||||
export class Demo extends ecs.Entity {
|
||||
DemoModelTable!: DemoModelTableComp;
|
||||
DemoBllLogin!: DemoBllLoginComp;
|
||||
DemoView!: DemoViewComp;
|
||||
|
||||
/** 加载模块相关资源 */
|
||||
static load(callback: Function) {
|
||||
// 模块静态数据
|
||||
JsonUtil.load(DemoModelTableComp.TableName, callback);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addComponents(DemoModelTableComp);
|
||||
}
|
||||
|
||||
/** 初始化数据 */
|
||||
init(id: number) {
|
||||
var mt = this.get(DemoModelTableComp);
|
||||
mt.init(id);
|
||||
console.log("静态数据", mt.describe);
|
||||
}
|
||||
|
||||
/** 显示视图 */
|
||||
show(parent: Node) {
|
||||
var d = find("gui/ecs_demo", parent)!;
|
||||
var dc = d.getComponent(DemoViewComp)!;
|
||||
this.add(dc);
|
||||
}
|
||||
|
||||
/** 登录逻辑 */
|
||||
login() {
|
||||
var dbl = this.add(DemoBllLoginComp);
|
||||
dbl.playerId = 123456789;
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/entity/Demo.ts.meta
Normal file
9
assets/script/ecs/entity/Demo.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "c28b2b5b-353e-4128-8a45-a3e57826aec9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
49
assets/script/ecs/system/DemoBllLoginSystem.ts
Normal file
49
assets/script/ecs/system/DemoBllLoginSystem.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
import { DemoBllLoginComp } from "../component/DemoBllLoginComp";
|
||||
import { Demo } from "../entity/Demo";
|
||||
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 18:11:13
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 11:49:52
|
||||
*/
|
||||
export class DemoBllLoginSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(DemoBllLoginComp);
|
||||
}
|
||||
|
||||
entityEnter(entities: Demo[]): void {
|
||||
for (let e of entities) {
|
||||
console.log("用户登录", e.DemoBllLogin.playerId);
|
||||
|
||||
// 获取到的玩过数据存储到对应的ECS组件中,提供其它组件使用
|
||||
this.requestLoadPlayer(e.DemoBllLogin.playerId)
|
||||
|
||||
e.remove(DemoBllLoginComp);
|
||||
}
|
||||
}
|
||||
|
||||
update(entities: ecs.Entity[]): void {
|
||||
|
||||
}
|
||||
|
||||
/** 请求角色登录游戏 */
|
||||
private requestLoadPlayer(playerId: number) {
|
||||
// var params: any = {
|
||||
// playerId: playerId,
|
||||
// serverId: netConfig.lastLoginServer.id,
|
||||
// gmUid: netConfig.dbid,
|
||||
// sessionKey: netConfig.sessionKey,
|
||||
// }
|
||||
|
||||
// var onComplete = {
|
||||
// target: this,
|
||||
// callback: (data: any) => {
|
||||
// console.log(data);
|
||||
// }
|
||||
// }
|
||||
|
||||
// netChannel.game.req("LoginAction", "loadPlayer", params, onComplete);
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/system/DemoBllLoginSystem.ts.meta
Normal file
9
assets/script/ecs/system/DemoBllLoginSystem.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "51cdc2fc-19ac-4211-8e44-378964e89ebf",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
15
assets/script/ecs/system/EcsDemoSystem.ts
Normal file
15
assets/script/ecs/system/EcsDemoSystem.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ecs } from "../../core/libs/ECS";
|
||||
import { DemoBllLoginSystem } from "./DemoBllLoginSystem";
|
||||
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 18:14:52
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-12 10:50:28
|
||||
*/
|
||||
export class EcsDemoSystem extends ecs.System {
|
||||
constructor() {
|
||||
super();
|
||||
this.add(new DemoBllLoginSystem());
|
||||
}
|
||||
}
|
||||
9
assets/script/ecs/system/EcsDemoSystem.ts.meta
Normal file
9
assets/script/ecs/system/EcsDemoSystem.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.22",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ad41f606-de52-4753-9792-8a23e65d615d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2021-11-04 17:33:25
|
||||
* @LastEditTime: 2021-11-12 10:16:59
|
||||
*/
|
||||
|
||||
import { Logger } from "../../core/common/log/Logger";
|
||||
@@ -18,6 +18,10 @@ export class GameConfig {
|
||||
return this._data["config"]["version"];
|
||||
}
|
||||
|
||||
public static getConfigPath(relative_path: string) {
|
||||
return "config/game/" + relative_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前客户端支持的语言类型
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user