mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-30 18:39:18 +08:00
游戏通用配置模块提到框架中成为复用功能模块
This commit is contained in:
@@ -2,18 +2,20 @@
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-02 09:58:15
|
||||
* @LastEditTime: 2022-08-05 17:20:11
|
||||
*/
|
||||
import { Component, director, game, Game, log, Node, view, _decorator } from "cc";
|
||||
import { ecs } from "../libs/ecs/ECS";
|
||||
import { LanguageManager } from "../libs/gui/language/Language";
|
||||
import { HttpRequest } from "../libs/network/HttpRequest";
|
||||
import { config } from "../module/config/Config";
|
||||
import { AudioManager } from "./common/audio/AudioManager";
|
||||
import { EventMessage } from "./common/event/EventMessage";
|
||||
import { Message } from "./common/event/MessageManager";
|
||||
import { TimerManager } from "./common/manager/TimerManager";
|
||||
import { GameManager } from "./game/GameManager";
|
||||
import { GUI } from "./gui/GUI";
|
||||
import { LanguageManager } from "../libs/gui/language/Language";
|
||||
import { LayerManager } from "./gui/layer/LayerManager";
|
||||
import { HttpRequest } from "../libs/network/HttpRequest";
|
||||
import { oops, version } from "./Oops";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
@@ -35,6 +37,26 @@ export class Root extends Component {
|
||||
console.log(`Oops Framework v${version}`);
|
||||
|
||||
this.init();
|
||||
config.init(this.run.bind(this));
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
oops.ecs.execute(dt);
|
||||
}
|
||||
|
||||
/** 初始化游戏界面 */
|
||||
protected initGui() {
|
||||
|
||||
}
|
||||
|
||||
/** 初始化游戏业务模块 */
|
||||
protected initEcsSystem() {
|
||||
|
||||
}
|
||||
|
||||
/** 加载完引擎配置文件后执行 */
|
||||
protected run() {
|
||||
|
||||
}
|
||||
|
||||
protected init() {
|
||||
@@ -42,8 +64,12 @@ export class Root extends Component {
|
||||
oops.timer = new TimerManager(this);
|
||||
oops.audio = AudioManager.instance;
|
||||
oops.http = new HttpRequest();
|
||||
oops.gui = new LayerManager(this.gui!);
|
||||
oops.game = new GameManager(this.game!);
|
||||
oops.gui = new LayerManager(this.gui!);
|
||||
this.initGui();
|
||||
oops.ecs = new ecs.RootSystem();
|
||||
this.initEcsSystem();
|
||||
oops.ecs.init();
|
||||
|
||||
// 游戏显示事件
|
||||
game.on(Game.EVENT_SHOW, () => {
|
||||
|
||||
@@ -62,7 +62,7 @@ export class LayerManager {
|
||||
private configs: { [key: number]: UIConfig } = {};
|
||||
|
||||
/** 是否为竖屏显示 */
|
||||
public get portrait() {
|
||||
get portrait() {
|
||||
return this.root.getComponent(GUI)!.portrait;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ export class LayerManager {
|
||||
* 初始化所有UI的配置对象
|
||||
* @param configs 配置对象
|
||||
*/
|
||||
public init(configs: { [key: number]: UIConfig }): void {
|
||||
init(configs: { [key: number]: UIConfig }): void {
|
||||
this.configs = configs;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export class LayerManager {
|
||||
* @param content 文本表示
|
||||
* @param useI18n 是否使用多语言
|
||||
*/
|
||||
public toast(content: string, useI18n: boolean = false) {
|
||||
toast(content: string, useI18n: boolean = false) {
|
||||
this.notify.show(content, useI18n)
|
||||
}
|
||||
|
||||
@@ -88,12 +88,12 @@ export class LayerManager {
|
||||
* @param uiId 要设置的界面id
|
||||
* @param config 要设置的配置
|
||||
*/
|
||||
public setConfig(uiId: number, config: UIConfig): void {
|
||||
setConfig(uiId: number, config: UIConfig): void {
|
||||
this.configs[uiId] = config;
|
||||
}
|
||||
|
||||
/** 设置界面地图配置 */
|
||||
public setUIMap(data: any) {
|
||||
setUIMap(data: any) {
|
||||
if (this.uiMap == null) {
|
||||
this.uiMap = new UIMap();
|
||||
}
|
||||
@@ -107,7 +107,7 @@ export class LayerManager {
|
||||
* @param callbacks 回调对象
|
||||
* @returns
|
||||
*/
|
||||
public open(uiId: number, uiArgs: any = null, callbacks?: UICallbacks): void {
|
||||
open(uiId: number, uiArgs: any = null, callbacks?: UICallbacks): void {
|
||||
var config = this.configs[uiId];
|
||||
if (config == null) {
|
||||
warn(`打开编号为【${uiId}】的界面失败,配置信息不存在`);
|
||||
@@ -136,7 +136,7 @@ export class LayerManager {
|
||||
* @param uiArgs 窗口参数
|
||||
* @returns
|
||||
*/
|
||||
public async openAsync(uiId: number, uiArgs: any = null): Promise<Node | null> {
|
||||
async openAsync(uiId: number, uiArgs: any = null): Promise<Node | null> {
|
||||
return new Promise<Node | null>((resolve, reject) => {
|
||||
var callbacks: UICallbacks = {
|
||||
onAdded: (node: Node, params: any) => {
|
||||
@@ -148,7 +148,7 @@ export class LayerManager {
|
||||
}
|
||||
|
||||
/** 缓存中是否存在指定标识的窗口 */
|
||||
public has(uiId: number) {
|
||||
has(uiId: number) {
|
||||
var config = this.configs[uiId];
|
||||
if (config == null) {
|
||||
warn(`编号为【${uiId}】的界面失败,配置信息不存在`);
|
||||
@@ -173,7 +173,7 @@ export class LayerManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
public remove(uiId: number, isDestroy = true) {
|
||||
remove(uiId: number, isDestroy = true) {
|
||||
var config = this.configs[uiId];
|
||||
if (config == null) {
|
||||
warn(`删除编号为【${uiId}】的界面失败,配置信息不存在`);
|
||||
@@ -197,7 +197,7 @@ export class LayerManager {
|
||||
}
|
||||
|
||||
/** 删除一个通过this框架添加进来的节点 */
|
||||
public removeByNode(node: Node, isDestroy: boolean = false) {
|
||||
removeByNode(node: Node, isDestroy: boolean = false) {
|
||||
if (node instanceof Node) {
|
||||
let comp = node.getComponent(DelegateComponent);
|
||||
if (comp && comp.viewParams) {
|
||||
@@ -213,14 +213,14 @@ export class LayerManager {
|
||||
}
|
||||
|
||||
/** 清除所有窗口 */
|
||||
public clear(isDestroy: boolean = false) {
|
||||
clear(isDestroy: boolean = false) {
|
||||
this.ui.clear(isDestroy);
|
||||
this.popup.clear(isDestroy);
|
||||
this.dialog.clear(isDestroy);
|
||||
this.alert.clear(isDestroy);
|
||||
}
|
||||
|
||||
public constructor(root: Node) {
|
||||
constructor(root: Node) {
|
||||
this.root = root;
|
||||
this.camera = this.root.getComponentInChildren(Camera)!;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"ver": "1.0.1",
|
||||
"importer": "text",
|
||||
"ver": "1.0.0",
|
||||
"importer": "*",
|
||||
"imported": true,
|
||||
"uuid": "75bee78b-9817-4c58-a8a2-ac3626541dc2",
|
||||
"files": [
|
||||
".json"
|
||||
".json",
|
||||
".md"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
|
||||
12
assets/module.meta
Normal file
12
assets/module.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "160e4538-8053-451b-ad7e-8d51300731bb",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
12
assets/module/common.meta
Normal file
12
assets/module/common.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "0bb68e2b-ea6e-4969-9d2c-c6751d909f6d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
31
assets/module/common/CCComp.ts
Normal file
31
assets/module/common/CCComp.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 19:05:32
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-05 10:31:47
|
||||
*/
|
||||
|
||||
import { _decorator } from 'cc';
|
||||
import { GameComponent } from '../../core/game/GameComponent';
|
||||
import { ecs } from '../../libs/ecs/ECS';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* ECS结合Cocos Creator组件
|
||||
* 使用方法:
|
||||
* 1、对象拥有Cocos引擎组件功能、ECS 组件全局访问功能
|
||||
* 2、网络游戏,优先有数据对象,在才创建视图组件的流程,在释放视图组件时,不释放数据对象
|
||||
* 3、对象自带监听、释放、发送全局消息功能
|
||||
* 4、对象管理的所有节点摊平,直接通过节点名获取cc.Node对象(节点名不能有重名)
|
||||
*/
|
||||
@ccclass('CCComp')
|
||||
export abstract class CCComp extends GameComponent implements ecs.IComp {
|
||||
static tid: number = -1;
|
||||
static compName: string;
|
||||
|
||||
canRecycle!: boolean;
|
||||
ent!: ecs.Entity;
|
||||
|
||||
abstract reset(): void;
|
||||
}
|
||||
9
assets/module/common/CCComp.ts.meta
Normal file
9
assets/module/common/CCComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "dd2077e2-c862-4b7f-9afe-6e488c83076d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
31
assets/module/common/CCVMParentComp.ts
Normal file
31
assets/module/common/CCVMParentComp.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-11-11 19:05:32
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-05 10:31:44
|
||||
*/
|
||||
|
||||
import { _decorator } from 'cc';
|
||||
import { ecs } from '../../libs/ecs/ECS';
|
||||
import VMParent from '../../libs/model-view/VMParent';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* Cocos Creator Component + ECS Comp + VM VMParent
|
||||
* 使用方法:
|
||||
* 1、对象拥有Cocos引擎组件功能、ECS 组件全局访问功能、显示对象与数据结构绑定功能
|
||||
* 2、网络游戏,优先有数据对象,然后才创建视图组件,在释放视图组件时,不释放数据对象
|
||||
* 3、对象自带监听、释放、发送全局消息功能
|
||||
* 4、对象管理的所有节点摊平,直接通过节点名获取cc.Node对象(节点名不能有重名)
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
9
assets/module/common/CCVMParentComp.ts.meta
Normal file
9
assets/module/common/CCVMParentComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5908a4e6-3359-48b6-95e0-a3b44ea50790",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
12
assets/module/config.meta
Normal file
12
assets/module/config.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "ca1994dc-b0e8-4b45-8748-976ae4f5d0b9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"compressionType": {},
|
||||
"isRemoteBundle": {}
|
||||
}
|
||||
}
|
||||
23
assets/module/config/BuildTimeConstants.ts
Normal file
23
assets/module/config/BuildTimeConstants.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-02 14:25:27
|
||||
*/
|
||||
import * as buildTimeConstants from 'cc/env';
|
||||
|
||||
const keys = (Object.keys(buildTimeConstants) as (keyof typeof buildTimeConstants)[]).sort();
|
||||
|
||||
/* 游戏运行环境 */
|
||||
export class BuildTimeConstants {
|
||||
constructor() {
|
||||
const keyNameMaxLen = keys.reduce((len, key) => Math.max(len, key.length), 0);
|
||||
var enviroment = `${keys.map((key) => {
|
||||
const value = buildTimeConstants[key];
|
||||
const valueRep = typeof value === 'boolean' ? (value ? 'true' : 'false') : value;
|
||||
return `\n${key.padStart(keyNameMaxLen, ' ')} : ${valueRep}`;
|
||||
})}`;
|
||||
|
||||
console.log(enviroment);
|
||||
}
|
||||
}
|
||||
9
assets/module/config/BuildTimeConstants.ts.meta
Normal file
9
assets/module/config/BuildTimeConstants.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "21a39ff8-1dc8-4974-9912-40a28a90b87d",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
48
assets/module/config/Config.ts
Normal file
48
assets/module/config/Config.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-05 17:20:01
|
||||
*/
|
||||
|
||||
import { game, JsonAsset } from "cc";
|
||||
import { resLoader } from "../../../../../extensions/oops-plugin-framework/assets/core/common/loader/ResLoader";
|
||||
import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
import { BuildTimeConstants } from "./BuildTimeConstants";
|
||||
import { GameConfig } from "./GameConfig";
|
||||
import { GameQueryConfig } from "./GameQueryConfig";
|
||||
|
||||
/** 游戏配置静态访问类 */
|
||||
export class Config {
|
||||
/** 构建时环境常量 */
|
||||
public btc!: BuildTimeConstants;
|
||||
|
||||
/** 配置数据,版本号、支持语种等数据 */
|
||||
public game!: GameConfig;
|
||||
|
||||
/** 处理浏览器地址栏参数,包括服务器ip、端口等数据 */
|
||||
public query!: GameQueryConfig;
|
||||
|
||||
public init(callback: Function) {
|
||||
let config_name = "config/config";
|
||||
resLoader.load(config_name, JsonAsset, () => {
|
||||
var config = resLoader.get(config_name);
|
||||
this.btc = new BuildTimeConstants();
|
||||
this.query = new GameQueryConfig();
|
||||
this.game = new GameConfig(config);
|
||||
|
||||
// 初始化每秒传输帧数
|
||||
game.frameRate = this.game.frameRate;
|
||||
// Http 服务器地址
|
||||
oops.http.server = this.game.httpServer;
|
||||
// Http 请求超时时间
|
||||
oops.http.timeout = this.game.httpTimeout;
|
||||
// 初始化本地存储加密
|
||||
oops.storage.init(this.game.localDataKey, this.game.localDataIv);
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const config = new Config()
|
||||
9
assets/module/config/Config.ts.meta
Normal file
9
assets/module/config/Config.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "5034d11e-ce8e-45ae-be9d-8591958264e1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
59
assets/module/config/GameConfig.ts
Normal file
59
assets/module/config/GameConfig.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2021-07-03 16:13:17
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-05 17:06:44
|
||||
*/
|
||||
|
||||
import { oops } from "../../core/Oops";
|
||||
|
||||
/* 游戏配置解析,对应 resources/config/config.json 配置 */
|
||||
export class GameConfig {
|
||||
/** 客户端版本号配置 */
|
||||
get version(): string {
|
||||
return this._data["config"]["version"];
|
||||
}
|
||||
/** 包名 */
|
||||
get package(): string {
|
||||
return this._data["config"]["package"];
|
||||
}
|
||||
/** 游戏每秒传输帧数 */
|
||||
get frameRate(): number {
|
||||
return this._data.config.frameRate;
|
||||
}
|
||||
/** 本地存储内容加密 key */
|
||||
get localDataKey(): string {
|
||||
return this._data.config.localDataKey;
|
||||
}
|
||||
/** 本地存储内容加密 iv */
|
||||
get localDataIv(): string {
|
||||
return this._data.config.localDataIv;
|
||||
}
|
||||
/** Http 服务器地址 */
|
||||
get httpServer(): string {
|
||||
return this._data.config.httpServer;
|
||||
}
|
||||
/** Http 请求超时时间 */
|
||||
get httpTimeout(): number {
|
||||
return this._data.config.httpTimeout;
|
||||
}
|
||||
|
||||
/** 获取当前客户端支持的语言类型 */
|
||||
get language(): Array<string> {
|
||||
return this._data.language.type || ["zh"];
|
||||
}
|
||||
get languagePathJson(): string {
|
||||
return this._data.language.path.json || "language/json";
|
||||
}
|
||||
get languagePathTexture(): string {
|
||||
return this._data.language.path.texture || "language/texture";
|
||||
}
|
||||
|
||||
private _data: any = null;
|
||||
constructor(config: any) {
|
||||
let data = config.json;
|
||||
this._data = Object.freeze(data);
|
||||
|
||||
oops.log.logConfig(this._data, "游戏配置");
|
||||
}
|
||||
}
|
||||
9
assets/module/config/GameConfig.ts.meta
Normal file
9
assets/module/config/GameConfig.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "54585cc1-b26b-467d-9103-7332c6dd21f9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
77
assets/module/config/GameQueryConfig.ts
Normal file
77
assets/module/config/GameQueryConfig.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* @Author: dgflash
|
||||
* @Date: 2022-04-14 17:08:01
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-08-05 10:47:51
|
||||
*/
|
||||
import { sys } from "cc";
|
||||
import { guid } from "../../core/common/manager/TimerManager";
|
||||
import { oops } from "../../core/Oops";
|
||||
|
||||
/**
|
||||
* 获取和处理浏览器地址栏参数
|
||||
* @example
|
||||
* config.query.data.username
|
||||
*/
|
||||
export class GameQueryConfig {
|
||||
/** 调试模式开关 */
|
||||
public get debug(): string {
|
||||
return this._data["debug"];
|
||||
}
|
||||
|
||||
/** 玩家帐号名 */
|
||||
public get username(): string {
|
||||
return this._data["username"];
|
||||
}
|
||||
|
||||
/** 语言 */
|
||||
public get lang(): string {
|
||||
return this._data["lang"] || "zh";
|
||||
}
|
||||
|
||||
private _data: any = null;
|
||||
/** 浏览器地址栏原始参数 */
|
||||
public get data(): any {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
if (!sys.isBrowser) {
|
||||
this._data = {};
|
||||
return;
|
||||
}
|
||||
this._data = this.parseUrl();
|
||||
|
||||
if (!this._data["username"]) {
|
||||
this._data["username"] = guid();
|
||||
}
|
||||
|
||||
oops.log.logConfig(this._data, "查询参数");
|
||||
}
|
||||
|
||||
private parseUrl() {
|
||||
if (typeof window !== "object") return {};
|
||||
if (!window.document) return {};
|
||||
|
||||
let url = window.document.location.href.toString();
|
||||
let u = url.split("?");
|
||||
if (typeof (u[1]) == "string") {
|
||||
u = u[1].split("&");
|
||||
let get: any = {};
|
||||
for (let i = 0, l = u.length; i < l; ++i) {
|
||||
let j = u[i];
|
||||
let x = j.indexOf("=");
|
||||
if (x < 0) {
|
||||
continue;
|
||||
}
|
||||
let key = j.substring(0, x);
|
||||
let value = j.substring(x + 1);
|
||||
get[decodeURIComponent(key)] = value && decodeURIComponent(value);
|
||||
}
|
||||
return get;
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
9
assets/module/config/GameQueryConfig.ts.meta
Normal file
9
assets/module/config/GameQueryConfig.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d09ac531-714e-4783-8914-8cac551162f2",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user