!8 合并develop内容到master

Merge pull request !8 from dgflash/develop
This commit is contained in:
dgflash
2025-04-24 01:04:57 +00:00
committed by Gitee
16 changed files with 221 additions and 135 deletions

View File

@@ -24,7 +24,7 @@ import { GameManager } from "./game/GameManager";
import { LayerManager } from "./gui/layer/LayerManager";
/** 框架版本号 */
export var version: string = "2.0.0.20250325";
export var version: string = "2.0.0.20250423";
/** 框架核心模块访问入口 */
export class oops {

View File

@@ -5,7 +5,7 @@
* @LastEditTime: 2023-01-09 11:52:38
*/
import { Node } from "cc";
import { UIConfig } from "./LayerManager";
import { UIConfig } from "./UIConfig";
/*** 界面回调参数对象定义 */
export interface UICallbacks {
@@ -38,6 +38,8 @@ export interface UICallbacks {
/** 本类型仅供gui模块内部使用请勿在功能逻辑中使用 */
export class ViewParams {
/** 界面唯一编号 */
uiid: number = -1;
/** 界面配置 */
config: UIConfig = null!;
/** 传递给打开界面的参数 */

View File

@@ -62,6 +62,9 @@ export class DelegateComponent extends Component {
this.removed(this.vp, isDestroy);
}
}
else {
this.removed(this.vp, isDestroy);
}
}
/** 窗口关闭前动画处理完后的回调方法,主要用于释放资源 */
@@ -87,16 +90,22 @@ export class DelegateComponent extends Component {
// 释放界面相关资源
oops.res.release(vp.config.prefab, vp.config.bundle);
// oops.log.logView(`【界面管理】释放【${vp.config.prefab}】界面资源`);
// 释放自动递增编号的界面配置
if (vp.config.auto) {
oops.gui.setConfig(vp.uiid, null!);
}
oops.log.logView(`【界面管理】释放【${vp.config.prefab}】界面资源`);
}
else {
this.node.removeFromParent();
}
// 触发窗口组件上窗口移除之后的事件
this.applyComponentsFunction(this.node, EventOnRemoved, this.vp.params);
}
onDestroy() {
// 触发窗口组件上窗口移除之后的事件
this.applyComponentsFunction(this.node, EventOnRemoved, this.vp.params);
this.vp = null!;
}

View File

@@ -6,8 +6,8 @@
*/
import { UICallbacks, ViewParams } from "./Defines";
import { UIConfig } from "./LayerManager";
import { LayerPopUp } from "./LayerPopup";
import { UIConfig } from "./UIConfig";
/** 模式弹窗数据 */
type DialogParam = {
@@ -23,7 +23,7 @@ export class LayerDialog extends LayerPopUp {
/** 窗口调用参数队列 */
private params: Array<DialogParam> = [];
add(config: UIConfig, params?: any, callbacks?: UICallbacks) {
add(uiid: number, config: UIConfig, params?: any, callbacks?: UICallbacks) {
// 控制同一时间只能显示一个模式窗口
if (this.ui_nodes.size > 0) {
this.params.push({

View File

@@ -0,0 +1,41 @@
/** 屏幕适配类型 */
export enum ScreenAdapterType {
/** 自动适配 */
Auto,
/** 横屏适配 */
Landscape,
/** 竖屏适配 */
Portrait
}
/** 界面层类型 */
export enum LayerType {
/** 二维游戏层 */
Game = "LayerGame",
/** 主界面层 */
UI = "LayerUI",
/** 弹窗层 */
PopUp = "LayerPopUp",
/** 模式窗口层 */
Dialog = "LayerDialog",
/** 系统触发模式窗口层 */
System = "LayerSystem",
/** 消息提示层 */
Notify = "LayerNotify",
/** 新手引导层 */
Guide = "LayerGuide"
}
/** 界面层组件类型 */
export enum LayerTypeCls {
/** 主界面层 */
UI = "UI",
/** 弹窗层 */
PopUp = "PopUp",
/** 模式窗口层 */
Dialog = "Dialog",
/** 消息提示层 */
Notify = "Notify",
/** 自定义节点层 */
Node = "Node"
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "a33b5645-72a0-4590-80c9-b0ff4a33fe9c",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -3,90 +3,23 @@ import { oops } from "../../Oops";
import { UICallbacks } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { LayerDialog } from "./LayerDialog";
import { LayerType, LayerTypeCls } from "./LayerEnum";
import { LayerNotify } from "./LayerNotify";
import { LayerPopUp } from "./LayerPopup";
import { LayerUI } from "./LayerUI";
import { UIConfig } from "./UIConfig";
/** 屏幕适配类型 */
export enum ScreenAdapterType {
/** 自动适配 */
Auto,
/** 横屏适配 */
Landscape,
/** 竖屏适配 */
Portrait
}
/** 自动生成界面编号最小值 */
const uiidMin = 1000000;
/** 自动生成界面编号最大值 */
const uiidMax = 9999999;
var uiid: number = uiidMin; // 当前自动递增界面编号
/** 界面层类型 */
export enum LayerType {
/** 二维游戏层 */
Game = "LayerGame",
/** 主界面层 */
UI = "LayerUI",
/** 弹窗层 */
PopUp = "LayerPopUp",
/** 模式窗口层 */
Dialog = "LayerDialog",
/** 系统触发模式窗口层 */
System = "LayerSystem",
/** 消息提示层 */
Notify = "LayerNotify",
/** 新手引导层 */
Guide = "LayerGuide"
}
/** 界面层组件类型 */
export enum LayerTypeCls {
/** 主界面层 */
UI = "UI",
/** 弹窗层 */
PopUp = "PopUp",
/** 模式窗口层 */
Dialog = "Dialog",
/** 消息提示层 */
Notify = "Notify",
/** 自定义节点层 */
Node = "Node"
}
/**
* 界面配置结构体
* @help https://gitee.com/dgflash/oops-framework/wikis/pages?sort_id=12037986&doc_id=2873565
* @example
// 界面唯一标识
export enum UIID {
Loading = 1,
Window,
Netinstable
}
// 打开界面方式的配置数据
export var UIConfigData: { [key: number]: UIConfig } = {
[UIID.Loading]: { layer: LayerType.UI, prefab: "loading/prefab/loading", bundle: "resources" },
[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" }
}
*/
export interface UIConfig {
/** -----公共属性----- */
/** 远程包名 */
bundle?: string;
/** 窗口层级 */
layer: string;
/** 预制资源相对路径 */
prefab: string;
/** 是否自动施放(默认不自动释放) */
destroy?: boolean;
/** -----弹窗属性----- */
/** 是否触摸非窗口区域关闭(默认关闭) */
vacancy?: boolean,
/** 是否打开窗口后显示背景遮罩(默认关闭) */
mask?: boolean;
/** 是否启动真机安全区域显示 */
safeArea?: boolean;
/** 界面弹出时的节点排序索引 */
siblingIndex?: number;
/** 自动获取界面唯一编号 */
function getUiid(): number {
if (uiid == uiidMax) uiid = uiidMin;
uiid++;
return uiid;
}
/** 界面层级管理器 */
@@ -253,16 +186,19 @@ export class LayerManager {
/**
* 设置界面配置
* @param uiId 要设置的界面id
* @param uiid 要设置的界面id
* @param config 要设置的配置
*/
setConfig(uiId: number, config: UIConfig): void {
this.configs[uiId] = config;
setConfig(uiid: number, config: UIConfig): void {
if (config)
this.configs[uiid] = config;
else
delete this.configs[uiid];
}
/**
* 同步打开一个窗口
* @param uiId 窗口唯一编号
* @param uiid 窗口唯一编号
* @param uiArgs 窗口参数
* @param callbacks 回调对象
* @example
@@ -276,30 +212,30 @@ export class LayerManager {
};
oops.gui.open(UIID.Loading, null, uic);
*/
open(uiId: number, uiArgs: any = null, callbacks?: UICallbacks): void {
const config = this.configs[uiId];
open(uiid: number, uiArgs: any = null, callbacks?: UICallbacks): void {
const config = this.configs[uiid];
if (config == null) {
warn(`打开编号为【${uiId}】的界面失败,配置信息不存在`);
warn(`打开编号为【${uiid}】的界面失败,配置信息不存在`);
return;
}
let layer = this.uiLayers.get(config.layer);
if (layer) {
layer.add(config, uiArgs, callbacks);
layer.add(uiid, config, uiArgs, callbacks);
}
else {
console.error(`打开编号为【${uiId}】的界面失败,界面层不存在`);
console.error(`打开编号为【${uiid}】的界面失败,界面层不存在`);
}
}
/**
* 异步打开一个窗口
* @param uiId 窗口唯一编号
* @param uiid 窗口唯一编号
* @param uiArgs 窗口参数
* @example
* var node = await oops.gui.openAsync(UIID.Loading);
*/
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) => {
const callbacks: UICallbacks = {
onAdded: (node: Node, params: any) => {
@@ -309,7 +245,22 @@ export class LayerManager {
resolve(null);
}
};
this.open(uiId, uiArgs, callbacks);
this.open(uiid, uiArgs, callbacks);
});
}
/**
* 通过界面配置打开一个界面
* @param config 界面配置数据
* @returns
*/
openAsyncConfig(config: UIConfig): Promise<number> {
return new Promise(async (resolve, reject) => {
let uiid = getUiid();
config.auto = true;
this.setConfig(uiid, config);
await oops.gui.openAsync(uiid, { uiid: uiid });
resolve(uiid);
});
}
@@ -350,14 +301,14 @@ export class LayerManager {
/**
* 缓存中是否存在指定标识的窗口
* @param uiId 窗口唯一标识
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
has(uiId: number): boolean {
const config = this.configs[uiId];
has(uiid: number): boolean {
const config = this.configs[uiid];
if (config == null) {
warn(`编号为【${uiId}】的界面配置不存在,配置信息不存在`);
warn(`编号为【${uiid}】的界面配置不存在,配置信息不存在`);
return false;
}
@@ -367,7 +318,7 @@ export class LayerManager {
result = layer.has(config.prefab);
}
else {
console.error(`验证编号为【${uiId}】的界面失败,界面层不存在`);
console.error(`验证编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
@@ -375,14 +326,14 @@ export class LayerManager {
/**
* 缓存中是否存在指定标识的窗口
* @param uiId 窗口唯一标识
* @param uiid 窗口唯一标识
* @example
* oops.gui.has(UIID.Loading);
*/
get(uiId: number): Node {
const config = this.configs[uiId];
get(uiid: number): Node {
const config = this.configs[uiid];
if (config == null) {
warn(`编号为【${uiId}】的界面配置不存在,配置信息不存在`);
warn(`编号为【${uiid}】的界面配置不存在,配置信息不存在`);
return null!;
}
@@ -392,22 +343,22 @@ export class LayerManager {
result = layer.get(config.prefab);
}
else {
console.error(`获取编号为【${uiId}】的界面失败,界面层不存在`);
console.error(`获取编号为【${uiid}】的界面失败,界面层不存在`);
}
return result;
}
/**
* 移除指定标识的窗口
* @param uiId 窗口唯一标识
* @param isDestroy 移除后是否释放
* @param uiid 窗口唯一标识
* @param isDestroy 移除后是否释放(默认释放内存)
* @example
* oops.gui.remove(UIID.Loading);
*/
remove(uiId: number, isDestroy?: boolean) {
const config = this.configs[uiId];
remove(uiid: number, isDestroy: boolean = true) {
const config = this.configs[uiid];
if (config == null) {
warn(`删除编号为【${uiId}】的界面失败,配置信息不存在`);
warn(`删除编号为【${uiid}】的界面失败,配置信息不存在`);
return;
}
@@ -416,24 +367,24 @@ export class LayerManager {
layer.remove(config.prefab, isDestroy);
}
else {
console.error(`移除编号为【${uiId}】的界面失败,界面层不存在`);
console.error(`移除编号为【${uiid}】的界面失败,界面层不存在`);
}
}
/**
* 删除一个通过this框架添加进来的节点
* 通过界面节点移除
* @param node 窗口节点
* @param isDestroy 移除后是否释放资源
* @param isDestroy 移除后是否释放资源(默认释放内存)
* @example
* oops.gui.removeByNode(cc.Node);
*/
removeByNode(node: Node, isDestroy?: boolean) {
removeByNode(node: Node, isDestroy: boolean = true) {
if (node instanceof Node) {
let comp = node.getComponent(DelegateComponent);
if (comp && comp.vp) {
// 释放显示的界面
if (node.parent) {
this.uiLayers.get(comp.vp.config.layer)!.remove(comp.vp.config.prefab, isDestroy);
this.remove(comp.vp.uiid, isDestroy);
}
// 释放缓存中的界面
else if (isDestroy) {
@@ -445,7 +396,7 @@ export class LayerManager {
}
}
else {
warn(`当前删除的node不是通过界面管理器添加到舞台上`);
warn(`当前删除的 Node 不是通过界面管理器添加`);
node.destroy();
}
}

View File

@@ -8,8 +8,8 @@ import { BlockInputEvents, EventTouch, Layers, Node } from "cc";
import { ViewUtil } from "../../utils/ViewUtil";
import { PromptResType } from "../GuiEnum";
import { ViewParams } from "./Defines";
import { UIConfig } from "./LayerManager";
import { LayerUI } from "./LayerUI";
import { UIConfig } from "./UIConfig";
/* 弹窗层,允许同时弹出多个窗口 */
export class LayerPopUp extends LayerUI {

View File

@@ -3,7 +3,7 @@ import { Collection } from "db://oops-framework/libs/collection/Collection";
import { oops } from "../../Oops";
import { UICallbacks, ViewParams } from "./Defines";
import { DelegateComponent } from "./DelegateComponent";
import { UIConfig } from "./LayerManager";
import { UIConfig } from "./UIConfig";
/** 界面层对象 */
export class LayerUI extends Node {
@@ -35,7 +35,7 @@ export class LayerUI extends Node {
* @param callbacks 回调函数对象,可选
* @returns ture为成功,false为失败
*/
add(config: UIConfig, params?: any, callbacks?: UICallbacks) {
add(uiid: number, config: UIConfig, params?: any, callbacks?: UICallbacks) {
if (this.ui_nodes.has(config.prefab)) {
console.warn(`路径为【${config.prefab}】的预制重复加载`);
return;
@@ -45,6 +45,7 @@ export class LayerUI extends Node {
let vp = this.ui_cache.get(config.prefab);
if (vp == null) {
vp = new ViewParams();
vp.uiid = uiid;
vp.config = config;
}
this.ui_nodes.set(config.prefab, vp);
@@ -172,6 +173,10 @@ export class LayerUI extends Node {
this.onCloseWindow(vp);
this.ui_cache.delete(prefabPath);
const childNode = vp.node;
const comp = childNode.getComponent(DelegateComponent)!;
if (comp) {
comp.remove(true);
}
childNode.destroy();
}
}

View File

@@ -0,0 +1,42 @@
/**
* 界面配置结构体
* @help https://gitee.com/dgflash/oops-framework/wikis/pages?sort_id=12037986&doc_id=2873565
* @example
// 界面唯一标识
export enum UIID {
Loading = 1,
Window,
Netinstable
}
// 打开界面方式的配置数据
export var UIConfigData: { [key: number]: UIConfig } = {
[UIID.Loading]: { layer: LayerType.UI, prefab: "loading/prefab/loading", bundle: "resources" },
[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable" },
[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window" }
}
*/
export interface UIConfig {
/** 是否为自动生成的界面编号 */
auto?: boolean,
/** -----公共属性----- */
/** 远程包名 */
bundle?: string;
/** 窗口层级 */
layer: string;
/** 预制资源相对路径 */
prefab: string;
/** 是否自动施放(默认不自动释放) */
destroy?: boolean;
/** -----弹窗属性----- */
/** 是否触摸非窗口区域关闭(默认关闭) */
vacancy?: boolean,
/** 是否打开窗口后显示背景遮罩(默认关闭) */
mask?: boolean;
/** 是否启动真机安全区域显示 */
safeArea?: boolean;
/** 界面弹出时的节点排序索引 */
siblingIndex?: number;
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "41bb526c-a934-4564-9c6e-e2f6a7ba6114",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -20,8 +20,11 @@ export class ViewUtil {
let items = parent.children;
for (let i = 0; i < items.length; i++) {
let _node = items[i];
if (_node.name.indexOf(" ") < 0) {
map.set(_node.name, _node);
if (_node.name.length > 0) {
if (map.has(_node.name))
console.error(`使用ViewUtil.nodeTreeInfoLite方法时发现重复的节点名称【${_node.name}`);
else
map.set(_node.name, _node);
}
ViewUtil.nodeTreeInfoLite(_node, map);
}

View File

@@ -52,7 +52,10 @@ export class MoveTo extends Component {
update(dt: number) {
let end: Vec3;
console.assert(this.speed > 0, "移动速度必须要大于零");
if (this.speed <= 0) {
console.error("移动速度必须要大于零");
return;
}
if (this.target instanceof Node) {
end = this.ns == Node.NodeSpace.WORLD ? this.target.worldPosition : this.target.position;

View File

@@ -41,9 +41,16 @@ export class LanguageData {
*
* 3、config/game/Language配置表使用oops-plugin-excel-to-json插件生成点击项目根目录下载update-oops-plugin-framework.bat或update-oops-plugin-framework.sh脚本下载插件
*/
public static getLangByID(labId: string): string {
static getLangByID(labId: string): string {
let content: string = null!;
for (const [key, value] of this.language) {
const content = value[labId];
if (key == LanguageDataType.Excel) {
let lang = value[labId];
if (lang) content = lang[this.current];
}
else {
content = value[labId];
}
if (content) return content;
}
return labId;

View File

@@ -4,7 +4,7 @@
* @LastEditors: dgflash
* @LastEditTime: 2022-12-13 11:36:00
*/
import { Asset, Button, Component, EventHandler, EventKeyboard, EventTouch, Input, Node, Sprite, SpriteFrame, __private, _decorator, input, isValid } from "cc";
import { Asset, Button, Component, EventHandler, EventKeyboard, EventTouch, Input, Node, Prefab, Sprite, SpriteFrame, __private, _decorator, input, isValid } from "cc";
import { oops } from "../../core/Oops";
import { EventDispatcher } from "../../core/common/event/EventDispatcher";
import { EventMessage, ListenerFunc } from "../../core/common/event/EventMessage";
@@ -76,7 +76,7 @@ export class GameComponent extends Component {
//#region 预制节点管理
/** 摊平的节点集合(所有节点不能重名) */
protected nodes: Map<string, Node> = null!;
nodes: Map<string, Node> = null!;
/** 通过节点名获取预制上的节点,整个预制不能有重名节点 */
getNode(name: string): Node | undefined {
@@ -106,7 +106,11 @@ export class GameComponent extends Component {
* @param bundleName 资源包名
*/
createPrefabNodeAsync(path: string, bundleName: string = oops.res.defaultBundleName): Promise<Node> {
return ViewUtil.createPrefabNodeAsync(path, bundleName);
return new Promise(async (resolve, reject) => {
await this.loadAsync(bundleName, path, Prefab);
let node = ViewUtil.createPrefabNode(path, bundleName);
resolve(node);
});
}
//#endregion
@@ -343,6 +347,8 @@ export class GameComponent extends Component {
async playEffect(url: string, bundleName?: string) {
if (bundleName == null) bundleName = oops.res.defaultBundleName;
await oops.audio.playEffect(url, bundleName, () => {
if (!this.isValid) return;
const rps = this.resPaths.get(ResType.Audio);
if (rps) {
const key = this.getResKey(bundleName, url);
@@ -485,7 +491,6 @@ export class GameComponent extends Component {
/** 游戏旋转屏幕事件回调 */
protected onGameOrientation(): void { }
//#endregion
protected onDestroy() {
// 释放消息对象
if (this._event) {

View File

@@ -15,7 +15,7 @@ export class ModuleUtil {
* @param uiId 界面资源编号
* @param uiArgs 界面参数
*/
public static addViewUi<T extends CCVMParentComp | CCComp>(
static addViewUi<T extends CCVMParentComp | CCComp>(
ent: ecs.Entity,
ctor: __private.__types_globals__Constructor<T> | __private.__types_globals__AbstractedConstructor<T>,
uiId: number,
@@ -38,7 +38,7 @@ export class ModuleUtil {
* @param uiArgs 界面参数
* @returns 界面节点
*/
public static addViewUiAsync<T extends CCVMParentComp | CCComp>(
static addViewUiAsync<T extends CCVMParentComp | CCComp>(
ent: ecs.Entity,
ctor: __private.__types_globals__Constructor<T> | __private.__types_globals__AbstractedConstructor<T>,
uiId: number,
@@ -65,7 +65,7 @@ export class ModuleUtil {
* @param parent 显示对象父级
* @param url 显示资源地址
*/
public static addView<T extends CCVMParentComp | CCComp>(
static addView<T extends CCVMParentComp | CCComp>(
ent: ecs.Entity,
ctor: __private.__types_globals__Constructor<T> | __private.__types_globals__AbstractedConstructor<T>,
parent: Node,
@@ -83,7 +83,7 @@ export class ModuleUtil {
* @param uiId 界面资源编号
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
*/
public static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true) {
static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true) {
if (isDestroy) ent.remove(ctor, isDestroy);
oops.gui.remove(uiId, isDestroy);
}