游戏初始化流程模板

This commit is contained in:
董刚
2022-01-24 15:17:56 +08:00
parent e2e413fd3e
commit e7f40da329
71 changed files with 989 additions and 925 deletions

View File

@@ -14,6 +14,7 @@
"__type__": "cc.Node",
"_name": "loading",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
@@ -232,7 +233,7 @@
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": -207.5,
"y": -247.5,
"z": 0
},
"_lrot": {
@@ -751,8 +752,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 960,
"height": 640
"width": 1280,
"height": 720
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -801,7 +802,7 @@
"fileId": "26ZokSfFxPFr+5cT88/8nR"
},
{
"__type__": "4b0f3PUwWlHlLZMPnsZ9MzF",
"__type__": "e316dKkHYpPVZlM8A2wB25/",
"_name": "",
"_objFlags": 0,
"node": {
@@ -815,7 +816,7 @@
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "53Ttwu661BaKo1Oa67ocks"
"fileId": "49OCCkOQJPVKZ/VACJynNb"
},
{
"__type__": "cc.PrefabInfo",

View File

@@ -21,11 +21,11 @@
"_active": true,
"_components": [],
"_prefab": {
"__id__": 111
"__id__": 104
},
"autoReleaseAssets": false,
"_globals": {
"__id__": 112
"__id__": 105
},
"_id": "ba0b085f-f8d5-40b0-9964-2fd25728d707"
},
@@ -47,7 +47,7 @@
"_active": true,
"_components": [
{
"__id__": 110
"__id__": 103
}
],
"_prefab": null,
@@ -3325,21 +3325,18 @@
"_children": [
{
"__id__": 95
},
{
"__id__": 97
}
],
"_active": true,
"_components": [
{
"__id__": 104
"__id__": 97
},
{
"__id__": 106
"__id__": 99
},
{
"__id__": 108
"__id__": 101
}
],
"_prefab": null,
@@ -3427,7 +3424,7 @@
"_priority": 1073741824,
"_fov": 45,
"_fovAxis": 0,
"_orthoHeight": 419.7772828507795,
"_orthoHeight": 360,
"_near": 1,
"_far": 2000,
"_color": {
@@ -3455,157 +3452,6 @@
"_targetTexture": null,
"_id": "91CjdhwCZBXZzNJCpJXp5K"
},
{
"__type__": "cc.Node",
"_name": "ecs_demo",
"_objFlags": 0,
"_parent": {
"__id__": 94
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 98
},
{
"__id__": 100
},
{
"__id__": 102
}
],
"_prefab": null,
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_layer": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": "f9u+JQgktBsbnSB/sqaPqs"
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 97
},
"_enabled": true,
"__prefab": {
"__id__": 99
},
"_contentSize": {
"__type__": "cc.Size",
"width": 92.28,
"height": 50.4
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": "52HZUUX8hBMZE984hr/tvx"
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "c68UOAlNhN171Umca6yVvF"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 97
},
"_enabled": true,
"__prefab": {
"__id__": 101
},
"_visFlags": 0,
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_string": "ecs_demo",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 20,
"_fontSize": 20,
"_fontFamily": "Arial",
"_lineHeight": 40,
"_overflow": 0,
"_enableWrapText": true,
"_font": null,
"_isSystemFontUsed": true,
"_isItalic": false,
"_isBold": false,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_id": "4ehG+3nZhMyLG1O7ljUOeU"
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "2frm37uaJHQr0AEEaYyM82"
},
{
"__type__": "033c3XyXLlE/Is8frhruBf0",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 97
},
"_enabled": true,
"__prefab": null,
"movement": {
"__id__": 103
},
"_id": "fakFE2p7BAeqFlPCvlFVr3"
},
{
"__type__": "DemoViewMovementComp",
"acceleration": 1,
"_maxSpeed": 100,
"heading": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"targetHeading": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
}
},
{
"__type__": "cc.UITransform",
"_name": "Canvas<UITransform>",
@@ -3615,7 +3461,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 105
"__id__": 98
},
"_contentSize": {
"__type__": "cc.Size",
@@ -3642,7 +3488,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 107
"__id__": 100
},
"_cameraComponent": {
"__id__": 96
@@ -3663,7 +3509,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 109
"__id__": 102
},
"_alignFlags": 45,
"_target": null,
@@ -3713,19 +3559,19 @@
{
"__type__": "cc.SceneGlobals",
"ambient": {
"__id__": 113
"__id__": 106
},
"shadows": {
"__id__": 114
"__id__": 107
},
"_skybox": {
"__id__": 115
"__id__": 108
},
"fog": {
"__id__": 116
"__id__": 109
},
"octree": {
"__id__": 117
"__id__": 110
}
},
{

View File

@@ -2,38 +2,23 @@
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2021-12-30 16:22:27
* @LastEditTime: 2022-01-24 14:27:59
*/
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 { ecs } from './core/libs/ECS';
import { Root } from './core/Root';
import { Demo } from './ecs/entity/Demo';
import { SingletonModuleComp } from './ecs/component/common/SingletonModuleComp';
import { Initialize } from './ecs/entity/Initialize';
import { RootSystem } from './ecs/RootSystem';
const { ccclass, property } = _decorator;
export enum UIID {
UILoading = 0,
Window = 1,
UILoading_Prompt = 2,
Demo = 3,
}
export var UICF: { [key: number]: UIConfig } = {
[UIID.UILoading]: { layer: LayerType.UI, prefab: "loading/prefab/loading" },
[UIID.UILoading_Prompt]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" },
[UIID.Demo]: { layer: LayerType.UI, prefab: "gui/prefab/demo" },
}
@ccclass('Main')
export class Main extends Root {
rootSystem!: RootSystem;
start() {
if (DEBUG)
setDisplayStats(true);
if (DEBUG) setDisplayStats(true);
game.frameRate = 60;
@@ -42,24 +27,9 @@ 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);
});
var module = ecs.getSingleton(SingletonModuleComp);
module.initialize = new Initialize();
module.initialize.open();
}
update(dt: number) {

View File

@@ -1,10 +1,10 @@
/*
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2021-11-04 17:32:16
* @LastEditors: H.Joeson
* @LastEditTime: 2021-12-28 18:22:25
*/
import { Camera, Component, ResolutionPolicy, UITransform, view, _decorator } from "cc";
import { Camera, Component, ResolutionPolicy, screen, UITransform, view, _decorator } from "cc";
import { Logger } from "../common/log/Logger";
const { ccclass, menu } = _decorator;
@@ -14,7 +14,10 @@ const { ccclass, menu } = _decorator;
export class GUI extends Component {
/** 界面层矩形信息组件 */
public transform!: UITransform;
/** 游戏二维摄像机 */
public camera!: Camera;
/** 是否为竖屏显示 */
public portrait!: boolean;
onLoad() {
this.init();
@@ -29,7 +32,7 @@ export class GUI extends Component {
public resize() {
let dr = view.getDesignResolutionSize();
var s = view.getFrameSize();
var s = screen.windowSize//view.getFrameSize();
var rw = s.width;
var rh = s.height;
var finalW = rw;
@@ -39,11 +42,13 @@ export class GUI extends Component {
// 如果更长,则用定高
finalH = dr.height;
finalW = finalH * rw / rh;
this.portrait = false;
}
else {
// 如果更短,则用定宽
finalW = dr.width;
finalH = finalW * rh / rw;
this.portrait = true;
}
// 手工修改canvas和设计分辨率这样反复调用也能生效。
@@ -54,4 +59,4 @@ export class GUI extends Component {
Logger.trace(dr, "设计尺寸");
Logger.trace(s, "屏幕尺寸");
}
}
}

View File

@@ -1,3 +1,9 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 11:21:32
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:24:07
*/
/*
* Gui模块常用类型定义
*/

View File

@@ -2,21 +2,24 @@
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2021-10-13 16:13:14
*/
/*
* 对话框层控制器
* 该层的节点将一次只显示一个,删除以后会自动从队列当中取一个弹窗,直到队列为空
* @LastEditTime: 2022-01-24 14:24:04
*/
import { Node } from "cc";
import { UICallbacks, ViewParams } from "./Defines";
import { UIConfig } from "./LayerManager";
import { LayerPopUp } from "./LayerPopup";
/*
* Dialog 层
* 该层的节点将一次只显示一个,删除以后会自动从队列当中取一个弹窗,直到队列为空
*/
export class LayerDialog extends LayerPopUp {
private queue: Array<ViewParams> = [];
private current!: ViewParams;
add(prefabPath: string, params?: any, callbacks?: UICallbacks): string {
add(config: UIConfig, params?: any, callbacks?: UICallbacks): string {
let prefabPath = config.prefab
var uuid = this.getUuid(prefabPath);
var viewParams = this.ui_nodes.get(uuid);
if (viewParams == null) {

View File

@@ -2,7 +2,8 @@
* 入口文件
*/
import { Node, warn, Widget } from "cc";
import { Camera, Node, warn, Widget } from "cc";
import { GUI } from "../GUI";
import { UICallbacks } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { LayerDialog } from "./LayerDialog";
@@ -12,10 +13,12 @@ import { LayerUI } from "./LayerUI";
import { UIMap } from "./UIMap";
export enum LayerType {
Game = "LayerGame",
UI = "LayerUI",
PopUp = "LayerPopUp",
Dialog = "LayerDialog",
Alert = "LayerAlert"
Alert = "LayerAlert",
Notify = "LayerNotify"
}
/** UI配置结构体 */
@@ -23,9 +26,14 @@ export interface UIConfig {
bundle?: string;
layer: LayerType;
prefab: string;
animation?: number;
}
export class LayerManager {
/** 界面根节点 */
public root!: Node;
/** 界面摄像机 */
public camera!: Camera;
/** 游戏界面特效层 */
public game!: Node;
/** 界面地图 */
@@ -44,6 +52,11 @@ export class LayerManager {
/** UI配置 */
private configs: { [key: number]: UIConfig } = {};
/** 是否为竖屏显示 */
public get portrait() {
return this.root.getComponent(GUI)!.portrait;
}
/**
* 初始化所有UI的配置对象
* @param configs 配置对象
@@ -87,16 +100,16 @@ export class LayerManager {
switch (config.layer) {
case LayerType.UI:
this.ui.add(config.prefab, uiArgs, callbacks);
this.ui.add(config, uiArgs, callbacks);
break;
case LayerType.PopUp:
this.popup.add(config.prefab, uiArgs, callbacks);
this.popup.add(config, uiArgs, callbacks);
break;
case LayerType.Dialog:
this.dialog.add(config.prefab, uiArgs, callbacks);
this.dialog.add(config, uiArgs, callbacks);
break;
case LayerType.Alert:
this.alert.add(config.prefab, uiArgs, callbacks);
this.alert.add(config, uiArgs, callbacks);
break;
}
}
@@ -172,7 +185,9 @@ export class LayerManager {
}
public constructor(root: Node) {
this.game = new Node("LayerGame");
this.root = root;
this.camera = this.root.getComponentInChildren(Camera)!;
this.game = new Node(LayerType.Game);
var widget: Widget = this.game.addComponent(Widget);
widget.isAlignLeft = widget.isAlignRight = widget.isAlignTop = widget.isAlignBottom = true;
widget.left = widget.right = widget.top = widget.bottom = 0;
@@ -183,7 +198,7 @@ export class LayerManager {
this.popup = new LayerPopUp(LayerType.PopUp);
this.dialog = new LayerDialog(LayerType.Dialog);
this.alert = new LayerDialog(LayerType.Alert);
this.notify = new LayerNotify("LayerNotify");
this.notify = new LayerNotify(LayerType.Notify);
root.addChild(this.game);
root.addChild(this.ui);

View File

@@ -1,12 +1,18 @@
/*
* Popup层调用add显示可以显示暗色背景弹框参数可以查看PopViewParams
* 允许同时弹出多个pop层
* @Date: 2021-11-24 16:08:36
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:18:46
*/
import { BlockInputEvents, Layers } from "cc";
import { PopViewParams } from "./Defines";
import { UIConfig } from "./LayerManager";
import { LayerUI } from "./LayerUI";
/*
* Popup层调用add显示可以显示暗色背景弹框参数可以查看PopViewParams
* 允许同时弹出多个窗口
*/
export class LayerPopUp extends LayerUI {
private black!: BlockInputEvents;
@@ -27,9 +33,9 @@ export class LayerPopUp extends LayerUI {
* @param params 传给组件onAdded、onRemoved方法的参数。
* @param popParams 弹出界面的设置定义详情见PopViewParams
*/
add(prefabPath: string, params: any, popParams?: PopViewParams): string {
add(config: UIConfig, params: any, popParams?: PopViewParams): string {
this.black.enabled = true;
return super.add(prefabPath, params, popParams);
return super.add(config, params, popParams);
}
remove(prefabPath: string, isDestroy: boolean): void {

View File

@@ -14,6 +14,7 @@ import { error, instantiate, isValid, Node, Prefab, warn, Widget } from "cc";
import { resLoader } from "../../common/loader/ResLoader";
import { UICallbacks, ViewParams } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { UIConfig } from "./LayerManager";
export class LayerUI extends Node {
protected ui_nodes: Map<string, ViewParams> = new Map<string, ViewParams>();
@@ -45,7 +46,8 @@ export class LayerUI extends Node {
* @param params 自定义参数
* @param callbacks 回调函数对象,可选
*/
add(prefabPath: string, params?: any, callbacks?: UICallbacks): string {
add(config: UIConfig, params?: any, callbacks?: UICallbacks): string {
let prefabPath = config.prefab
var uuid = this.getUuid(prefabPath);
var viewParams = this.ui_nodes.get(uuid);

View File

@@ -1,5 +1,12 @@
/*
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:06:38
*/
import { Node, tween, Vec3 } from "cc";
import { UIID } from "../../../Main";
import { UIID } from "../../../game/config/UIConfig";
import { engine } from "../../Engine";
import { PopViewParams } from "../layer/Defines";
@@ -11,16 +18,16 @@ class TipsManager {
engine.timer.unschedule(this._timeId);
this._timeId = "";
}
engine.gui.remove(UIID.UILoading_Prompt);
engine.gui.remove(UIID.Netinstable);
}
/** 打开网络不稳定提示 */
public netInstableOpen() {
if (!engine.gui.has(UIID.UILoading_Prompt)) {
engine.gui.open(UIID.UILoading_Prompt);
if (!engine.gui.has(UIID.Netinstable)) {
engine.gui.open(UIID.Netinstable);
}
}
public netInstableClose() {
engine.gui.remove(UIID.UILoading_Prompt);
engine.gui.remove(UIID.Netinstable);
}
/** 网络延时 */
public networkLatency(time: number) {
@@ -47,6 +54,36 @@ class TipsManager {
engine.gui.open(UIID.Window, operate, this.getPopCommonEffect());
}
public alert(content: string, cb?: Function, title?: string, okWord?: string) {
let operate: any = {
title: title ? title : 'common_prompt_title_sys',
content: content,
okWord: okWord ? okWord : 'common_prompt_ok',
okFunc: () => {
cb && cb();
},
needCancel: false
};
engine.gui.open(UIID.Window, operate, tips.getPopCommonEffect());
}
public confirm(content: string, cb: Function, okWord: string = "common_prompt_ok") {
let operate: any = {
title: 'common_prompt_title_sys',
content: content,
okWord: okWord,
cancelWord: 'common_prompt_cancal',
okFunc: () => {
cb && cb()
},
cancelFunc: () => {
},
needCancel: true
};
engine.gui.open(UIID.Window, operate, tips.getPopCommonEffect());
}
/** 弹窗动画 */
private getPopCommonEffect(callbacks?: PopViewParams) {
let newCallbacks: PopViewParams = {

View File

@@ -435,7 +435,7 @@ export module ecs {
add<T extends IComp>(ctor: CompCtor<T>, isReAdd?: boolean): T;
add<T extends IComp>(ctor: CompType<T>, isReAdd?: boolean): T;
add<T extends IComp>(ctor: CompType<T> | T, isReAdd: boolean = false): T | Entity {
console.log('typeof: ', typeof ctor);
// console.log('typeof: ', typeof ctor);
if (typeof ctor === 'function') {
let compTid = ctor.tid;
if (ctor.tid === -1) {
@@ -587,14 +587,27 @@ export module ecs {
this.remove(comp, false);
}
private _remove_release(comp: CompType<IComp>) {
this.remove(comp, true);
}
/**
* 销毁实体,实体会被回收到实体缓存池中。
* 销毁实体,实体会被回收到实体缓存池中。不清楚ECS组件上的数据
*/
destroy() {
this.compTid2Ctor.forEach(this._remove, this);
destroyEntity(this);
this.compTid2Obj.clear();
}
/**
* 销毁实体实体会被回收到实体缓存池中。可触发ecs.Comp 与 cc.Component节后组件的reset
*/
release() {
this.compTid2Ctor.forEach(this._remove_release, this);
destroyEntity(this);
this.compTid2Obj.clear();
}
}
export class Group<E extends Entity = Entity> {
@@ -1032,7 +1045,8 @@ export module ecs {
* 根据提供的组件过滤实体。
*/
abstract filter(): IMatcher;
abstract update(entities: E[]): void;
// abstract update(entities: E[]): void;
update(entities: E[]) { }; // 避免不需要用update时写一些多余的代码
}
/**

View File

@@ -2,7 +2,7 @@
* @Author: dgflash
* @Date: 2021-08-11 16:41:12
* @LastEditors: dgflash
* @LastEditTime: 2021-09-08 09:58:20
* @LastEditTime: 2022-01-24 15:00:52
*/
/**
* 数组工具
@@ -74,15 +74,6 @@ export default class ArrayUtil {
return array;
}
/**
* 数组去重
* @param array 目标数组
*/
public static removeRepeated(array: any[]): any[] {
let newArray = [...new Set(array)];
return newArray;
}
/** 删除数组中指定项 */
public static removeItem(array: any[], item: any) {
var temp = array.concat();

View File

@@ -2,15 +2,15 @@
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2021-11-12 10:41:50
* @LastEditTime: 2022-01-24 14:56:17
*/
import { ecs } from "../core/libs/ECS";
import { EcsDemoSystem } from "./system/EcsDemoSystem";
import { EcsAccountSystem } from "./system/account/EcsAccountSystem";
export class RootSystem extends ecs.RootSystem {
constructor() {
super();
this.add(new EcsDemoSystem());
this.add(new EcsAccountSystem());
}
}

View File

@@ -1,37 +0,0 @@
/*
* @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;
}

View File

@@ -1,17 +0,0 @@
/*
* @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;
}
}

View File

@@ -1,35 +0,0 @@
/*
* @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() {
}
}

View File

@@ -1,41 +0,0 @@
/*
* @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!;
}
}

View File

@@ -1,57 +0,0 @@
/*
* @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);
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8de4a716-cb33-4e3c-bff1-1a35d0d86b5d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -2,7 +2,7 @@
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "d86cb41c-73d3-490b-919e-3988db4bb173",
"uuid": "687f067e-02ad-4507-8882-373abd7ae718",
"files": [],
"subMetas": {},
"userData": {

View File

@@ -0,0 +1,23 @@
/*
* @Author: dgflash
* @Date: 2021-11-12 10:02:31
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:54:28
*/
import { ecs } from "../../../core/libs/ECS";
/**
* 游戏帐号数据
*/
@ecs.register('AccountModel')
export class AccountModelComp extends ecs.Comp {
/** 资源列表 */
currency: any = {};
reset() {
}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8d0c16b0-b4ff-4324-9bc1-2d75c78e9db1",
"uuid": "8f35d0a4-3ee2-4a90-a175-f49e9515e7f1",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -0,0 +1,16 @@
/*
* @Author: dgflash
* @Date: 2021-11-23 15:51:15
* @LastEditors: H.Joeson
* @LastEditTime: 2021-11-25 17:13:13
*/
import { ecs } from "../../../core/libs/ECS";
/** 帐号网络数据请求 */
@ecs.register('AccountNetData')
export class AccountNetDataComp extends ecs.Comp {
reset() {
}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "033c35f2-5cb9-44fc-8b3c-7eb86bb817f4",
"uuid": "cd124d00-d854-4283-baf8-9c9d463ef23b",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -1,12 +1,12 @@
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "34404075-bd40-407e-aa82-ef81768b3bfa",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "eb97a6c3-d498-43e2-9939-24c716c34d03",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,120 @@
/*
* @Author: dgflash
* @Date: 2021-11-11 19:05:32
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:41:29
*/
import { Component, Node, _decorator } from 'cc';
import { EventDispatcher } from "../../../core/common/event/EventDispatcher";
import { ecs } from "../../../core/libs/ECS";
import { ViewUtil } from "../../../core/utils/ViewUtil";
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;
abstract reset(): void;
private nodes: Map<string, Node> = new Map();
/** 通过节点名获取预制上的节点,整个预制不能有重名节点 */
get(name: string): Node | undefined {
return this.nodes.get(name);
}
onLoad() {
ViewUtil.nodeTreeInfoLite(this.node, this.nodes);
}
//#region 全局事件管理
private _eventDispatcher: EventDispatcher | null = null;
public get eventDispatcher(): EventDispatcher {
if (!this._eventDispatcher) {
this._eventDispatcher = new EventDispatcher();
}
return this._eventDispatcher;
}
// 事件是否绑定node的active
private _isBindMessageActive: boolean = false;
/** 绑定node active属性即只有active为true才会响应事件 */
public bindMessageActive() {
this._isBindMessageActive = true;
}
/** 解绑node active属性无论node是否可见都会响应事件 */
public unbindMessageActive() {
this._isBindMessageActive = false;
}
/**
* 注册全局事件
* @param event(string) 事件名
* @param listener(function) 处理事件的侦听器函数
* @param thisObj(object) 侦听函数绑定的this对象
*/
public on(event: string, listener: Function, thisObj: any) {
this.eventDispatcher.on(event, (event, args) => {
if (!this.isValid) {
if (this._eventDispatcher) {
this._eventDispatcher.destroy();
this._eventDispatcher = null;
}
return;
}
if (this._isBindMessageActive) {
if (this.node.active) {
listener.call(thisObj, event, args);
}
}
else {
listener.call(thisObj, event, args);
}
}, thisObj);
}
/**
* 移除全局事件
* @param event(string) 事件名
*/
public off(event: string) {
if (this._eventDispatcher) {
this._eventDispatcher.off(event);
}
}
/**
* 触发全局事件
* @param event(string) 事件名
* @param arg(Array) 事件参数
*/
public dispatchEvent(event: string, arg: any = null) {
this.eventDispatcher.dispatchEvent(event, arg);
}
onDestroy() {
if (this._eventDispatcher) {
this._eventDispatcher.destroy();
this._eventDispatcher = null;
}
this.nodes.clear();
}
//#endregion
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "1329d483-ea72-4225-a71c-7f7a235b0dac",
"uuid": "a3bae49c-c110-463d-ba51-06398605d586",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -0,0 +1,123 @@
/*
* @Author: dgflash
* @Date: 2021-11-11 19:05:32
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:51:52
*/
import { Node, _decorator } from 'cc';
import { EventDispatcher } from "../../../core/common/event/EventDispatcher";
import { ecs } from "../../../core/libs/ECS";
import VMParent from "../../../core/libs/model-view/VMParent";
import { ViewUtil } from "../../../core/utils/ViewUtil";
const { ccclass, property } = _decorator;
/**
* Cocos Creator Component + ECS Comp + VM VMParent
* 使用方法:
* 1、ECS结合Cocos Creator组件可独立形成一个ECS的复杂视图实例对象
* 2、网络游戏优先有数据对象在才创建视图组件的流程在释放视图组件时不释放数据对象
* 3、主要用于游戏界面绑定数据
*/
@ccclass('CCVMParentComp')
export abstract class CCVMParentComp extends VMParent implements ecs.IComp {
static tid: number = -1;
static compName: string;
canRecycle!: boolean;
ent!: ecs.Entity;
abstract reset(): void;
private nodes: Map<string, Node> = new Map();
/** 通过节点名获取预制上的节点,整个预制不能有重名节点 */
get(name: string): Node | undefined {
return this.nodes.get(name);
}
onLoad() {
ViewUtil.nodeTreeInfoLite(this.node, this.nodes);
super.onLoad();
}
//#region 全局事件管理
private _eventDispatcher: EventDispatcher | null = null;
public get eventDispatcher(): EventDispatcher {
if (!this._eventDispatcher) {
this._eventDispatcher = new EventDispatcher();
}
return this._eventDispatcher;
}
// 事件是否绑定node的active
private _isBindMessageActive: boolean = false;
/** 绑定node active属性即只有active为true才会响应事件 */
public bindMessageActive() {
this._isBindMessageActive = true;
}
/** 解绑node active属性无论node是否可见都会响应事件 */
public unbindMessageActive() {
this._isBindMessageActive = false;
}
/**
* 注册全局事件
* @param event(string) 事件名
* @param listener(function) 处理事件的侦听器函数
* @param thisObj(object) 侦听函数绑定的this对象
*/
public on(event: string, listener: Function, thisObj: any) {
this.eventDispatcher.on(event, (event, args) => {
if (!this.isValid) {
if (this._eventDispatcher) {
this._eventDispatcher.destroy();
this._eventDispatcher = null;
}
return;
}
if (this._isBindMessageActive) {
if (this.node.active) {
listener.call(thisObj, event, args);
}
}
else {
listener.call(thisObj, event, args);
}
}, thisObj);
}
/**
* 移除全局事件
* @param event(string) 事件名
*/
public off(event: string) {
if (this._eventDispatcher) {
this._eventDispatcher.off(event);
}
}
/**
* 触发全局事件
* @param event(string) 事件名
* @param arg(Array) 事件参数
*/
public dispatchEvent(event: string, arg: any = null) {
this.eventDispatcher.dispatchEvent(event, arg);
}
onDestroy() {
if (this._eventDispatcher) {
this._eventDispatcher.destroy();
this._eventDispatcher = null;
}
this.nodes.clear();
}
//#endregion
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "f4c96747-a764-4a4f-9161-63a68ee8aecb",
"uuid": "7b2b02dc-5717-4179-9dd2-787b6e6ca738",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "88cd6342-234d-42f8-a10a-4b5b1d33a745",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,20 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 14:20:46
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 13:41:49
*/
import { ecs } from "../../../core/libs/ECS";
import { Initialize } from "../../entity/Initialize";
/** 游戏模块 */
@ecs.register('SingletonModule')
export class SingletonModuleComp extends ecs.Comp {
/** 游戏初始化模块 */
initialize: Initialize = null!;
/** 游戏账号模块 */
// account: Account = null!;
reset() { }
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4a0968a5-4e40-4344-98d0-9f9d4ef455b2",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "b2d6c1f2-6f0f-4fda-af28-f589b88cb074",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -1,14 +1,25 @@
import { _decorator } from 'cc';
import { engine } from '../../core/Engine';
import VMParent from '../../core/libs/model-view/VMParent';
import { resLoader } from '../../core/common/loader/ResLoader';
import { UIID } from '../../Main';
import { config } from '../config/Config';
/*
* @Author: dgflash
* @Date: 2021-07-03 16:13:17
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:49:29
*/
import { _decorator } from "cc";
import { resLoader } from "../../../core/common/loader/ResLoader";
import { Logger } from "../../../core/common/log/Logger";
import { engine } from "../../../core/Engine";
import { ecs } from "../../../core/libs/ECS";
import { config } from "../../../game/config/Config";
import { UIID } from "../../../game/config/UIConfig";
import { CCVMParentComp } from "../common/CCVMParentComp";
import { SingletonModuleComp } from "../common/SingletonModuleComp";
const { ccclass, property } = _decorator;
@ccclass('Loading')
export class Loading extends VMParent {
@ccclass('LoadingViewComp')
@ecs.register('LoadingView', false)
export class LoadingViewComp extends CCVMParentComp {
protected data: any = {
finished: 0,
total: 0,
@@ -17,6 +28,11 @@ export class Loading extends VMParent {
private progress: number = 0;
reset(): void {
resLoader.releaseDir("loading");
Logger.logView("释放loading资源");
}
start() {
this.loadRes();
}
@@ -57,11 +73,12 @@ export class Loading extends VMParent {
}
private onCompleteCallback() {
engine.gui.remove(UIID.UILoading);
engine.gui.remove(UIID.Loading);
// 释放 ECS 组件
// this.ent.remove(LoadingViewComp);
engine.gui.open(UIID.Demo);
}
onDestroy() {
resLoader.releaseDir("loading");
// 进入游戏主界面
var module = ecs.getSingleton(SingletonModuleComp);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "e316d2a4-1d8a-4f55-994c-f00db0076e7f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,48 @@
/*
* @Author: dgflash
* @Date: 2021-11-11 17:45:23
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:04:19
*/
import { ecs } from "../../core/libs/ECS";
import { netChannel } from "../../game/net/NetChannelManager";
import { AccountModelComp } from "../component/account/AccountModelComp";
import { AccountNetDataComp } from "../component/account/AccountNetDataComp";
export class AccountEntity extends ecs.Entity {
AccountModel!: AccountModelComp;
AccountNetData!: AccountNetDataComp;
}
/**
* 账号模块
* 1、连接游戏服务器
* 2、登录玩家帐号获取玩家信息
* 3、断线重连接
* 4、加载游戏资源
* 5、初始化游戏配置数据表
* 6、初始化游戏初始用到的模块
*/
export class Account {
public entity: AccountEntity = null!;
constructor() {
this.create();
}
create() {
this.entity = ecs.createEntityWithComps(AccountModelComp);
}
/** 连接游戏服务器 */
connect() {
netChannel.gameCreate();
netChannel.gameConnect();
}
// 登录游戏
requestLoadPlayer() {
this.entity.add(AccountNetDataComp);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "5fcd663a-ae07-4585-9fc5-bde898df5e78",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,50 +0,0 @@
/*
* @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;
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c28b2b5b-353e-4128-8a45-a3e57826aec9",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,79 @@
/*
* @Author: dgflash
* @Date: 2021-11-11 17:45:23
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:11:00
*/
import { Node, sys } from "cc";
import { resLoader } from "../../core/common/loader/ResLoader";
import { AsyncQueue, NextFunction } from "../../core/common/queue/AsyncQueue";
import { engine } from "../../core/Engine";
import { UICallbacks } from "../../core/gui/layer/Defines";
import { ecs } from "../../core/libs/ECS";
import { config } from "../../game/config/Config";
import { UICF, UIID } from "../../game/config/UIConfig";
import { LoadingViewComp } from "../component/initialize/LoadingViewComp";
export class InitializeEntity extends ecs.Entity {
LoadingView!: LoadingViewComp;
}
/**
* 游戏进入初始化模块
* 1、热更新
* 2、加载默认资源
* 3、转到帐号模块
*/
export class Initialize {
private entity: InitializeEntity = null!;
constructor() {
engine.gui.init(UICF);
this.create();
}
create() {
this.entity = ecs.createEntityWithComps();
}
/** 打开初始界面 */
open() {
var queue: AsyncQueue = new AsyncQueue();
// 加载多语言包
queue.push((next: NextFunction, params: any, args: any) => {
// 设置当前的渠道号
// if (config.query.channelId) SDKPlatform.setChannelId(config.query.channelId);
// 设置语言包路径
engine.i18n.setAssetsPath(config.game.languagePathJson, config.game.languagePathTexture);
// 设置默认语言
let lan = sys.localStorage.getItem("game_language");
if (!lan) {
// lan = SDKPlatform.getLanguage();
sys.localStorage.setItem("game_language", lan!);
}
engine.i18n.setLanguage(lan!, next);
});
// 加载ttf字库
queue.push((next: NextFunction, params: any, args: any) => {
// resLoader.load("language/font/" + engine.i18n.currentLanguage, next);
next();
});
// 加载公共资源
queue.push((next: NextFunction, params: any, args: any) => {
resLoader.loadDir("common", next);
});
// 进入第一个场景
queue.complete = () => {
var uic: UICallbacks = {
onAdded: (node: Node, params: any) => {
var comp = node.getComponent(LoadingViewComp) as ecs.Comp;
this.entity.add(comp);
}
};
engine.gui.open(UIID.Loading, null, uic);
};
queue.play();
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "cf13f5fd-4110-4579-b980-1f8b0ac6a673",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,49 +0,0 @@
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);
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "51cdc2fc-19ac-4211-8e44-378964e89ebf",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,15 +0,0 @@
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());
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ad41f606-de52-4753-9792-8a23e65d615d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "1349626f-f1aa-44bd-a039-8f8c34b9ba28",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -0,0 +1,39 @@
/*
* @Author: dgflash
* @Date: 2021-11-24 15:51:01
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:16:17
*/
import { log } from "cc";
import { ecs } from "../../../core/libs/ECS";
import { netChannel } from "../../../game/net/NetChannelManager";
import { netConfig } from "../../../game/net/NetConfig";
import { AccountModelComp } from "../../component/account/AccountModelComp";
import { AccountNetDataComp } from "../../component/account/AccountNetDataComp";
import { AccountEntity } from "../../entity/Account";
/** 请求玩家游戏数据 */
export class AccountNetDataSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem {
filter(): ecs.IMatcher {
return ecs.allOf(AccountNetDataComp, AccountModelComp);
}
entityEnter(entities: AccountEntity[]): void {
for (let e of entities) {
// 请求角色登录游戏
var params: any = {
playerId: netConfig.dbid,
sessionKey: netConfig.sessionKey,
}
let onComplete = {
target: this,
callback: (data: any) => {
log("帐号数据", data);
}
}
netChannel.game.req("LoginAction", "loadPlayer", params, onComplete);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4cb053a3-017a-46bd-ae1e-138ba927213f",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,16 @@
/*
* @Author: dgflash
* @Date: 2022-01-24 14:56:01
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 14:56:10
*/
import { ecs } from "../../../core/libs/ECS";
import { AccountNetDataSystem } from "./AccountNetDataSystem";
export class EcsAccountSystem extends ecs.System {
constructor() {
super();
this.add(new AccountNetDataSystem());
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "790e52d0-4ac6-4186-b2b2-f051d622ecc1",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,15 @@
/*
* @Author: dgflash
* @Date: 2021-11-23 15:28:39
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:09:01
*/
/** 游戏事件 */
export class GameEvent {
/** 游戏服务器连接成功 */
static GameServerConnected: string = "GameServerConnected";
// 登陆成功
static LOGIN_SUCCESS: string = "LOGIN_SUCCESS";
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "28ac0ad6-53bf-471a-9256-ae7c8ad351a7",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,25 @@
/*
* @Date: 2021-08-12 09:33:37
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:00:21
*/
import { LayerType, UIConfig } from '../../core/gui/layer/LayerManager';
export enum UIID {
/** 资源加载界面 */
Loading,
/** 弹窗界面 */
Window,
/** 加载与延时提示界面 */
Netinstable = 2,
/** DEMO */
Demo = 3,
}
export var UICF: { [key: number]: UIConfig } = {
[UIID.Loading]: { layer: LayerType.UI, prefab: "loading/prefab/loading" },
[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" },
[UIID.Demo]: { layer: LayerType.UI, prefab: "gui/prefab/demo" },
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "084510dd-1c52-44e1-9bce-00633e73f0fc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,36 @@
/*
* @Author: dgflash
* @Date: 2021-11-23 15:28:39
* @LastEditors: luobao
* @LastEditTime: 2022-01-04 18:37:32
*/
/** 游戏事件 */
export class GameEvent {
/** 游戏服务器连接成功 */
static GameServerConnected: string = "GameServerConnected";
// 登陆成功
static LOGIN_SUCCESS: string = "LOGIN_SUCCESS";
// 请求玩家数据成功
static REQUEST_PLAYER_SUCCESS: string = "REQUEST_PLAYER_SUCCESS";
/**所有点击提示事件 */
static COMMON_TOUCH_TIPS: string = "COMMON_TOUCH_TIPS";
/**角色属性计算完成刷新所有相关界面*/
static ALL_UI_REFRESH: string = "ALL_UI_REFRESH";
/**时间跳转**/
static GAME_DATE_JUMP: string = "GAME_DATE_JUMP";
/**设置节日 **/
static SET_HOLIDAY: string = "SET_HOLIDAY";
/**购买物品更新背包数据后 **/
static UPDATE_BAG_GOODS: string = "UPDATE_BAG_GOODS";
/**建筑升级中 **/
static BUILDING: string = "BUILDING";
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "31e1bb3d-ea38-4ab0-a574-2dcbab7b310a",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,13 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "4b0f33d4-c169-4794-b64c-3e7b19f4ccc5",
"files": [],
"subMetas": {},
"userData": {
"moduleId": "project:///assets/script/game/loading/Loading.js",
"importerSettings": 4,
"simulateGlobals": []
}
}

View File

@@ -1,142 +0,0 @@
import { Logger } from "../../core/common/log/Logger";
import { engine } from "../../core/Engine";
import { netChannel } from "./NetChannelManager";
import { netConfig } from "./NetConfig";
/** 登录管理 */
export class LoginManager {
constructor() {
this.test();
}
async test() {
var channelId = 101;
var config = await this.requestServerConfig();
console.log("config", config);
var login_data = await this.requestLogin("dgflash", channelId);
console.log("login_data", login_data);
var server_list: any = await this.requestServerList(101, 1088);
console.log("server_list", server_list);
netChannel.gameCreate();
netChannel.gameConnect();
// netChannel.chatCreate();
// netChannel.chatConnect();
netConfig.channelid = 101;
this.requestLoadPlayer(10040311);
this.requestPlayerAction();
}
requestPlayerAction() {
var cb = (data: any) => {
console.log(data);
}
netChannel.game.setResponeHandler("itemData", cb, this);
netChannel.game.setResponeHandler("userData", cb, this);
netChannel.game.setResponeHandler("chatInfo", cb, this);
}
requestHeart() {
netChannel.game.req("LoginAction", "heart", null, {
target: this, callback: (data: any) => {
console.log("heart", data);
}
});
}
/** 请求角色登录游戏 */
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);
}
/** 请求服务器配置数据 */
requestServerConfig() {
return new Promise((resolve, reject) => {
var url = `${netConfig.gmServer}?c=conf&a=getConf`;
var onComplete = (data: any) => {
netConfig.updateUrl = data.update;
netConfig.noticeUrl = data.notice;
netConfig.loginUrl = data.login;
netConfig.payUrl = data.pay;
netConfig.serverListUrl = data.serverList;
resolve(data);
}
var onError = () => {
Logger.trace("配置服务器连接失败");
resolve(null);
}
engine.http.get(url, onComplete, onError);
});
}
/**
* 请求登录
* @param username 用户名
* @param channelId 渠道编号
*/
requestLogin(user_name: string, channel_id: number) {
return new Promise((resolve, reject) => {
let params = { username: user_name, channelId: channel_id };
var onComplete = (data: any) => {
netConfig.dbid = parseInt(data.dbid);
netConfig.accessToken = data.access_token;
netConfig.sessionKey = data.sessionKey;
resolve(data);
}
var onError = () => {
Logger.trace("配置服务器连接失败");
resolve(null);
}
engine.http.post(netConfig.loginUrl, params, onComplete, onError);
});
}
/**
* 获取游戏服务器列表
* @param channelId 渠道编号
* @param dbid 数据库编号
*/
requestServerList(channelId: number, dbid: number) {
return new Promise((resolve, reject) => {
var url = `${netConfig.serverListUrl}&channelId=${channelId}&dbid=${dbid}`;
var onComplete = (data: any) => {
for (var key in data) {
netConfig.listServer.set(key, data[key]);
}
resolve(data);
}
var onError = () => {
Logger.trace("游戏服务器列表获取失败");
resolve(null);
}
engine.http.get(url, onComplete, onError);
})
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c518b172-fa00-4523-88f0-e3968fa04674",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,64 +0,0 @@
/** 服务器区域信息 */
export interface IServerRegionInfo {
/** 服务区域名 */
title: string,
/** 服务区域状态 */
state: number,
/** 服务器列表 */
servers: Array<IServerInfo>
}
/** 服务器区域信息 */
export interface IServerInfo {
/** 服务器编号 */
id: number,
/** 服务器编名 */
name: string,
/** 服务器地址 */
host: string,
/** 游戏服务器端口 */
port: number,
/** 聊天服务器端口 */
chat_port: number,
/** 服务器状态 */
server_state: number,
/** 连接状态 */
connect_state: number,
/** */
pingshen: number
}
/** 网络配置 */
class NetConfig {
public gmServer: string = "http://192.168.1.13/";
/** 更新地址 */
public updateUrl!: string;
/** 通知地址 */
public noticeUrl!: string;
/** 登录地址 */
public loginUrl!: string;
/** 支付地址 */
public payUrl!: string;
/** 服务器列表地址 */
public serverListUrl!: string;
/** 渠道编号 */
public channelid!: number;
/** 数据库编号 */
public dbid!: number;
/** SDK访问令牌 */
public accessToken!: string;
/** 会话关键字 */
public sessionKey!: string
/** 服务器列表 */
public listServer: Map<string, IServerRegionInfo> = new Map<string, IServerRegionInfo>();
/** 最后一次登录服务器信息 */
public get lastLoginServer(): IServerInfo {
var lastLoginServers = this.listServer.get("lastLogin")!;
return lastLoginServers.servers[lastLoginServers.state];
}
}
/** 网络配置 */
export var netConfig = new NetConfig();

View File

@@ -1,38 +0,0 @@
import { INetworkTips } from "../../core/network/NetInterface";
/** 网络提示(管理一个视图对象) */
export class NetTips implements INetworkTips {
/** 连接提示 */
connectTips(isShow: boolean): void {
if (isShow) {
console.log("connectTips_start");
}
else {
console.log("connectTips_end");
}
}
/** 重连接提示 */
reconnectTips(isShow: boolean): void {
if (isShow) {
console.log("reconnectTips_start");
}
else {
console.log("reconnectTips_end");
}
}
/** 请求提示 */
requestTips(isShow: boolean): void {
if (isShow) {
console.log("requestTips_start");
}
else {
console.log("requestTips_end");
}
}
/** 响应错误码提示 */
responseErrorCode(code: number): void {
console.log("错误码", code);
}
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "6bcfc550-d636-4095-8c77-0d5599ff8046",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,12 @@
{
"ver": "1.1.0",
"importer": "directory",
"imported": true,
"uuid": "b2862692-2ee7-4a20-b1fc-696efd03b010",
"files": [],
"subMetas": {},
"userData": {
"compressionType": {},
"isRemoteBundle": {}
}
}

View File

@@ -1,17 +1,21 @@
/*
* @Date: 2021-08-12 09:33:37
* @LastEditors: H.Joeson
* @LastEditTime: 2021-11-25 15:49:50
*/
import { DefStringProtocol, NetData } from "../../core/network/NetInterface";
import { NetManager } from "../../core/network/NetManager";
import { WebSock } from "../../core/network/WebSock";
import { netConfig } from "./NetConfig";
import { NetGameTips } from "./NetGameTips";
import { NetNodeGame } from "./NetNodeGame";
import { NetTips } from "./NetTips";
export enum NetChannelType {
/** 游戏服务器 */
Game = 0,
/** 聊天服务器 */
Chat = 1
}
/** 游戏服务器心跳协议 */
class GameProtocol extends DefStringProtocol {
/** 心跳协议 */
getHearbeat(): NetData {
@@ -21,41 +25,27 @@ class GameProtocol extends DefStringProtocol {
export class NetChannelManager {
public game!: NetNodeGame;
public chat!: NetNodeGame;
/** 创建游戏服务器 */
gameCreate() {
this.game = new NetNodeGame();
this.game.init(new WebSock(), new GameProtocol(), new NetTips());
// 游戏网络事件逻辑统一在 NetGameTips 里写
this.game.init(new WebSock(), new GameProtocol(), new NetGameTips());
NetManager.getInstance().setNetNode(this.game, NetChannelType.Game);
}
/** 连接游戏服务器 */
gameConnect() {
NetManager.getInstance().connect({ url: `ws://${netConfig.lastLoginServer.host}:${netConfig.lastLoginServer.port}`, autoReconnect: 0 }, NetChannelType.Game);
NetManager.getInstance().connect({
url: `ws://${netConfig.gameIp}:${netConfig.gamePort}`,
autoReconnect: 0 // 手动重连接
}, NetChannelType.Game);
}
/** 断开游戏服务器 */
gameClose() {
NetManager.getInstance().close(undefined, undefined, NetChannelType.Game);
}
/** 创建聊天服务器 */
chatCreate() {
this.chat = new NetNodeGame();
this.chat.init(new WebSock(), new DefStringProtocol());
NetManager.getInstance().setNetNode(this.chat, NetChannelType.Chat);
}
/** 连接聊天服务器 */
chatConnect() {
NetManager.getInstance().connect({ url: `ws://${netConfig.lastLoginServer.host}:${netConfig.lastLoginServer.chat_port}`, autoReconnect: 0 }, NetChannelType.Chat);
}
/** 断开游戏服务器 */
chatClose() {
NetManager.getInstance().close(undefined, undefined, NetChannelType.Chat);
}
}
export var netChannel = new NetChannelManager();

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "7b86c1cb-bd4f-4584-b685-7d4e9770b813",
"uuid": "ac861aa1-8743-466a-9fc6-d36e1b13ad94",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -0,0 +1,18 @@
/*
* @Date: 2021-08-12 09:33:37
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:15:30
*/
/** 网络配置 */
class NetConfig {
public gameIp !: string;
public gamePort !: string;
public dbid!: number;
public sdkUid!: string;
public serverId!: number;
public sessionKey!: string;
public channelid!: number;
}
export var netConfig = new NetConfig();

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "bc9e7f44-900f-4f3e-84c0-cab51544913b",
"uuid": "de66c7dd-a7e3-4f76-84ea-97c4cafc43cf",
"files": [],
"subMetas": {},
"userData": {}

View File

@@ -0,0 +1,60 @@
/*
* @Date: 2021-08-12 09:33:37
* @LastEditors: dgflash
* @LastEditTime: 2022-01-24 15:08:35
*/
import { Message } from "../../core/common/event/MessageManager";
import { Logger } from "../../core/common/log/Logger";
import { tips } from "../../core/gui/prompt/TipsManager";
import { INetworkTips } from "../../core/network/NetInterface";
import { GameEvent } from "../demo/GameEvent";
import { netChannel } from "./NetChannelManager";
/** 游戏服务器提示 */
export class NetGameTips implements INetworkTips {
/** 连接提示 */
connectTips(isShow: boolean): void {
if (isShow) {
Logger.logNet("游戏服务器正在连接");
// tips.netInstableOpen();
}
else {
Logger.logNet("游戏服务器连接成功");
// tips.netInstableClose();
Message.dispatchEvent(GameEvent.GameServerConnected);
}
}
disconnectTips(): void {
tips.alert("net_server_disconnected", () => {
netChannel.gameConnect();
})
}
/** 重连接提示 */
reconnectTips(isShow: boolean): void { }
/** 请求提示 */
requestTips(isShow: boolean): void {
if (isShow) {
}
else {
}
}
/** 响应错误码提示 */
responseErrorCode(code: number): void {
console.log("游戏服务器错误码", code);
if (code < 0) {
tips.alert("netcode_" + code, () => {
// SDKPlatform.restartGame(;)
});
}
else {
tips.alert("netcode_" + code);
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "446e8905-8cfa-49c2-af78-5c60459754dc",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -2,7 +2,7 @@
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "76d37d3e-013b-43c8-8728-1484fe972082",
"uuid": "bcdefa1e-679e-4d17-96f4-f5c25417a5e2",
"files": [],
"subMetas": {},
"userData": {}