oops-framework框架 之 界面管理(三)

引擎: CocosCreator 3.8.0

环境: Mac

Gitee: oops-game-kit

注: 作者dgflashoops-framework框架QQ群: 628575875


回顾


在上文中主要通过oops-game-kit大家了一个新的模版项目, 主要注意项是resources目录下的两个文件夹:

  • common 用于放置公共资源,在游戏启动时进行的必须加载
  • game 用于放置动态非必须资源,在游戏进度条显示时进行的加载

两个文件夹必须存在,否则程序会有报错。更多内容,可参考博客:

oops-framework框架 之 创建项目(二)

今天的文章主要讲述下框架的界面管理,以用于创建页面、切换页面、弹窗显示等处理。

若理解不当,欢迎您的指出。


界面管理


oops-framework的作者dgflash 针对于界面的管理主要分为了如下几个类型:

类型说明
Game游戏层,比如地图逻辑处理
UI主界面层,比如地图上方的菜单页面
PopUp弹窗层, 窗口显示后,支持非窗口区域点击,可显示多个不同配置的弹窗
Dialog模式窗口层,窗口显示后,非窗口区域不可透点
System系统窗口层,与Dialog类似,可用于显示系统信息的弹窗错误提示
Notify提示信息层, Tip信息显示,显示以后会上移消失
Guide新手引导层,用于新手的强制引导

注:界面类型来源于LayerManager.ts的枚举: LayerType

页面的显示,我们通常使用预制体Prefab实现,然后挂载上组件脚本。在框架中编写组件脚本,不需要特意的去继承什么,依然是Component即可。

页面构建后,需要在GameUIConfig.ts中进行配置:

// 界面唯一标识ID
export enum UIID {Loading = 1,		// 资源加载界面Window,					// 弹窗界面Netinstable,		// 加载与延时提示界面UI_MAIN,				// UI界面
}/*
界面配置数据 UIConfig
export interface UIConfig {bundle?: string;			// 包名layer: LayerType;			// 页面类型prefab: string;				// 预制资源相对路径
}
*/
export var UIConfigData: { [key: number]: UIConfig } = {[UIID.Loading]: { layer: LayerType.UI, prefab: "common/prefab/loading", bundle: "resources"},[UIID.Netinstable]: { layer: LayerType.PopUp, prefab: "common/prefab/netinstable",bundle: "resources"},[UIID.Window]: { layer: LayerType.Dialog, prefab: "common/prefab/window",  bundle: "resources"},[UIID.UI_MAIN]: { layer: LayerType.UI, prefab: "game/prefab/uiMain", bundle: "resources"},
}

在配置完成以后,显示或隐藏页面的简单使用:

// 显示UI主页面
oops.gui.open(UIID.UI_MAIN);
// 关闭加载页面
oops.gui.remove(UIID.Loading);

LayerManager


LayerManager管理类是框架提供的界面管理类,在框架的Oops.ts中提供的入口:

// ../oops-plugin-framework/assets/core/Oop.ts
export class oops {static gui: LayerManager;
}

该管理类主要负责对不同页面的管理,提供的主要接口有:

参数或接口说明
root获取界面根节点
camera获取界面摄像机
game获取游戏界面根节点
guide获取新手引导
uiMap获取界面地图
setUIMap()设置界面地图配置
init()初始化所有UI配置
setConfig()根据uiId,设置UI配置
toast()Tip提示显示,支持是否显示多语言
open()根据uiId,同步打开某个页面或窗口
openAsync()根据uiId,异步打开某个页面或窗口
has()根据uiId, 检测是否存在某个页面或窗口
remove()根据uiId,移除某个页面或窗口
removeByNode()根据this框架添加的节点,移除某个页面或窗口
clear()清除所有窗口

看下LayerManager的构造函数实现:

constructor(root: Node) {this.root = root;this.camera = this.root.getComponentInChildren(Camera)!;// 不同界面类型构建节点,然后顺序添加到根节点中this.game = this.create_node(LayerType.Game);this.ui = new LayerUI(LayerType.UI);this.popup = new LayerPopUp(LayerType.PopUp);this.dialog = new LayerDialog(LayerType.Dialog);this.system = new LayerDialog(LayerType.System);this.notify = new LayerNotify(LayerType.Notify);this.guide = this.create_node(LayerType.Guide);// 注意下层级, LayerType.Game的最低,LayerType.Guide的最高root.addChild(this.game);root.addChild(this.ui);root.addChild(this.popup);root.addChild(this.dialog);root.addChild(this.system);root.addChild(this.notify);root.addChild(this.guide);
}private create_node(name: string) {var node = new Node(name);node.layer = Layers.Enum.UI_2D;// 添加widget组件,设置上下左右对齐和对齐模式var w: Widget = node.addComponent(Widget);w.isAlignLeft = w.isAlignRight = w.isAlignTop = w.isAlignBottom = true;w.left = w.right = w.top = w.bottom = 0;w.alignMode = 2;w.enabled = true;return node;
}

LayerManager主要管理的页面是:

  • LayerUI 用于管理主页面UI层
  • LayerPopUp 用于管理PopUp弹窗
  • LayerDialog 用于管理Dialog模式窗口,System系统窗口
  • LayerNotify 用于管理Notify提示

继承结构如下:

主界面
游戏层
引导层
PopUp弹窗
Toast消息
Dialog窗口/System窗口
LayerUI
Node
Game
Guide
LayerPopUp
LayerNotify
LayerDialog

然后我们看下打开窗口的逻辑处理,有助于后面示例的理解:

/*
@func: 同步打开一个窗口
@param: uiId 窗口唯一标识符ID
@param: uiArgs 页面参数,可以通过回调对象的onAdded或onRemoved回调获取
@param: callbacks 回调对象
*/
open(uiId: number, uiArgs: any = null, callbacks?: UICallbacks): void {var config = this.configs[uiId];if (config == null) {warn(`打开编号为【${uiId}】的界面失败,配置信息不存在`);return;}switch (config.layer) {case LayerType.UI:this.ui.add(config, uiArgs, callbacks);break;case LayerType.PopUp:this.popup.add(config, uiArgs, callbacks);break;case LayerType.Dialog:this.dialog.add(config, uiArgs, callbacks);break;case LayerType.System:this.system.add(config, uiArgs, callbacks);break;}
}

打开的逻辑处理其实很简单,从UI配置中获取配置数据,然后通过add设置不同窗口的显示逻辑。


示例

简单的示例,在上面有说过。在项目开发中,如果切换页面可以这样:

// 关闭当前页面
oops.gui.remove(UIID.Loading);
// 显示新的页面
oops.gui.open(UIID.UI_MAIN);

这样的处理方式主要是为了避免: 页面资源较多,切换页面时导致黑屏情况的出现。

框架针对于这种情况,通过页面回调的方式做了处理,主要定义是: UICallbacks

// ../oops-plugin-framework/assets/core/gui/layer/Defines.ts
export interface UICallbacks {// 节点添加到层级以后的回调,参数为当前页面节点,传递参数onAdded?: (node: Node, params: any) => void,// 窗口节点destroy之后回调,参数为当前页面节点,传递参数onRemoved?: (node: Node | null, params: any) => void,// 页面在移除的时候,进行的调用,可用于隐藏动画的显示,参数为当前页面节点,回调// 注意:如果调用`this.node.destroy()`,该回调将直接忽略onBeforeRemove?: (node: Node, next: Function) => void
}

注:这个接口的定义在页面参数传递或动画播放中使用很频繁。

弹窗示例

在框架的弹窗中, 虽有PopUp,Dialog,System的几种类型,但他们是类似的

  • PopUp 打开以后,支持非窗口区域透点,支持打开多个不同配置的弹窗
  • Dialog 仅支持显示一个,非窗口区域不可透点
  • SystemDialog类似,作者dgflash增加这个处理的原因主要是为了区别窗口提示的不同类型,比如客户端自身和服务器的提示,方便问题的定位。

增加一个窗口的UI预制体,如下图所示:
请添加图片描述

GameUIConfig.ts中增加配置后, 添加示例:

public openWindow(event, customData: string) {let params = {title: "窗口标题",content: "这是一段描述",}let callBack: UICallbacks = {onAdded: (node: Node, params: any) => {console.log("onAdded获取传递的参数:", params)},onRemoved:(node: Node | null, params: any) => {console.log("onRemoved获取传递的参数:", params)     }}oops.gui.open(UIID.UI_POPUP, params, callBack);
}

如果想在指定的页面中获取传入的参数,可以这样:

@ccclass('UIPop')
export class UIPop extends Component {@property(Label) titleLabel: Label = null;@property(Label) descLabel: Label = null; private _okFunc = null;// 增加onAdded的回调,获取参数onAdded(args: any) {if (args) {this._okFunc = args.okFunc || null;this.titleLabel.string = args.title || "";this.descLabel.string = args.content || "未知错误";}}onClose() {if (this._okFunc) {this._okFunc();}oops.gui.removeByNode(this.node);}
}

一般弹窗的出现是需要有显示或隐藏动画的,我们可以通过回调方法:

  • onAdded 增加显示动画
  • onBeforeRemove 增加隐藏动画

动画的显示可以通过tween缓动系统或CocosCreator的Animation组件进行添加:

public clickSystem(event, customData: string) {console.log(customData);let params = {title: `系统窗口`,content: "数据异常",}oops.gui.open(UIID.UI_SYSTEM, params, this.getPopCommonEffect());
}// 弹窗动画
private getPopCommonEffect(callbacks?: PopViewParams) {let newCallbacks: PopViewParams = {// 节点添加动画onAdded: (node, params) => {node.setScale(0.1, 0.1, 0.1);tween(node).to(0.2, { scale: new Vec3(1, 1, 1) }).start();},// 节点删除动画onBeforeRemove: (node, next) => {tween(node).to(0.2, { scale: new Vec3(0.1, 0.1, 0.1) }).call(next).start();},}if (callbacks) {if (callbacks && callbacks.onAdded) {let onAdded = callbacks.onAdded;callbacks.onAdded = (node: Node, params: any) => {onAdded(node, params);newCallbacks.onAdded(node, params);};}if (callbacks && callbacks.onBeforeRemove) {let onBeforeRemove = callbacks.onBeforeRemove;callbacks.onBeforeRemove = (node, params) => {onBeforeRemove(node, params);newCallbacks.onBeforeRemove(node, params);};}return callbacks;}return newCallbacks;
}

注:作者在oops-frameworkTipsManager.ts中增加了更多的窗口示例,推荐查看学习

Toast示例

提示内容的显示就相对简单了,主要代码如下:

private _tipIndex: number = 0;public clickTip(event, customData: string) {this._tipIndex++;// 参数:内容,是否使用多语言默认falseoops.gui.toast(`这是第${this._tipIndex}个提示`);
}

总结

在框架中对界面的显示和隐藏主要逻辑如下:

  1. 页面的构建,继承于Component即可,如果需要获取参数,就增加 onAdded 方法
  2. GameUIConfig.ts中设置 UIID的唯一标识符ID 和 UIConfig 配置
  3. 页面的调用,使用openopenAsync;提示的显示使用Toast

最后注意:

  1. 任何页面的显示,不建议重复调用
oops.gui.open(UIID.UI_LAYER, {param: "参数"});
oops.gui.open(UIID.UI_LAYER, {param: "参数"});

注:框架会告知路径为【game/prefab/uiLayer】的预制重复加载

  1. PopUp的弹窗支持显示多个,指的是不同配置的Pop弹窗,原因1

感谢作者dgflash的分享,作者CSDN博客: dgflash CSDN

最后,祝大家学习和生活愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在安卓Termux中使用SFTP文件传输并结合内网穿透工具实现远程传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了…

Jmeter的安装配置,性能测试编写

1、jmeter介绍 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工具之一。 运行环境为Windows 10系统&#xff0c…

AI创作ChatGPT网站系统源码保姆级搭建部署教程+支持GPT-4图片对话能力

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

数据结构与算法-动态查找表

查找 🎈3动态查找表🔭3.1二叉排序树🏆3.1.1二叉排序树的类定义🏆3.1.2二叉排序树的插入和生成🏆3.1.3二叉树的查找🏆3.1.4二叉排序树的删除 🔭3.2平衡二叉树🏆3.2.1平衡二叉树的调整…

基于粒子群算法思想的电动汽车充放电策略-V2G模型-程序代码!

电动汽车充放电对电网的安全稳定带来影响,合理规划电动汽车充放电时间和策略是目前的研究热点。本程序仿真了汽车有序充电和无需充电两种案例,利用电动汽车合理消纳新能源电量,利用粒子群算法思想来求解模型,程序中案例丰富&#…

智能锁-SI522TORC522方案资料

南京中科微这款SI522目前完全PinTOPin兼容的NXP:RC522、CV520 复旦微:FM17520、FM17522/FM17550 瑞盟:MS520、MS522 国民技术:NZ3801、NZ3802 SI522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员。是NXP 公司针对&quo…

2.1 Linux C 编程

一、Hello World 1、在用户根目录下创建一个C_Program,并在这里面创建3.1文件夹来保存Hellow World程序; 2、安装最新版nvim ①sudo apt-get install ninja-build gettext cmake unzip curl ②sudo apt install lua5.1 ③git clone https://github.…

HarmonyOS 振动效果开发指导

Vibrator 开发概述 振动器模块服务最大化开放硬工最新马达器件能力,通过拓展原生马达服务实现振动与交互融合设计,打造细腻精致的一体化振动体验和差异化体验,提升用户交互效率和易用性、提升用户体验、增强品牌竞争力。 运作机制 Vibrato…

内衣专用洗衣机怎么样?好用又便宜的迷你洗衣机推荐

迷你洗衣机作为一种小型便捷的家用必备洗涤设备,一直都受到越来越多家庭的青睐。一台迷你洗衣机可以帮助我们解决很多麻烦,节省我们的很多时间。对于不少在外工作的人,往往是一个人住,买一台大型的洗衣机或许有点浪费资源&#xf…

JWT令牌的获取与过滤器Filter的使用

JWT,全称JSON Web Token(JSON Web令牌),是一个开放标准 (rfc7519)。它定义了一种紧凑的、自包含的方式,以JSON对象的形式安全地在各方之间传输信息。这种信息可以被验证和信任,因为它是通过数字签名实现的。…

专升本期间部分C语言程序整理

说明 这些程序是我在专升本期间在CSDN上上传的作业、练习等,仅为学习备考的一小部分程序,整理成一篇文章,方便专升本的学弟学妹参考。 时间:2021年~2022年专升本期间 字符串题 输入字符串提取 数字字符 并 求和 (4处…

WPS论文写作——公式和公式序号格式化

首先新建一个表格,表格尺寸按你的需求来确定,直接 插入--》表格 即可。 然后在表格对应位置填上公式(公式要用公式编辑器)和公式序号,然后可以按照单独的单元格或者整行或整列等来设置样式,比如居中对齐、…

电脑监控软件的监控方式有哪些

电脑监控软件是一种用于监视和控制计算机操作的工具,通常用于企业或个人对计算机的使用情况进行监控和管理。本文将探讨电脑监控软件的监控方式及其存在的问题。 首先,电脑监控软件的监控方式主要包括以下几种: 1、屏幕监控:这种…

【23-24 秋学期】NNDL 作业10 BPTT

习题6-1P 推导RNN反向传播算法BPTT. 习题6-2 推导公式(6.40)和公式(6.41)中的梯度. 习题6-3 当使用公式(6.50)作为循环神经网络的状态更新公式时, 分析其可能存在梯度爆炸的原因并给出解决方法. 习题6-2P 设计简单RNN模型,分别…

洛谷P1044 [NOIP2003 普及组] 栈 递归方法

目录 核心: 问题转化: 状态转化:(你得先读懂题,理解我们要干什么) 对应不同情况下的状态转化:(比如栈空就不能出栈,,) AC代码: 题…

【每日OJ —— 110. 平衡二叉树】

每日OJ —— 110. 平衡二叉树 1.题目:110. 平衡二叉树2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目:110. 平衡二叉树 2.解法 2.1.算法讲解 1.这道题中的平衡二叉树的定义是:二叉树的每个节点的左右子树的高度差的绝对值不超过 11…

Android12之MediaCodec硬编解码调试手段(四十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

继续画图带你学习TCP 其他 7 大特性

四、滑动窗口机制 五、流量控制 六、拥塞控制 (安全机制) 七、延迟应答 (效率机制) 八、捎带应答 (效率机制) 九、粘包问题 十、保活机制 TCP总结 四、滑动窗口机制 滑动窗口机制,是在可靠性的前提下,进一步地提高传输效率 认识滑动窗口 一发一收…

vscode的eslint检查代码格式不严谨的快速修复

问题: 原因:复制的代码,esLint检查代码格式不正确。或者写的代码位置不严谨,总是提示 解决 设置在Ctrl S保存时自动格式化代码 1、vscode设置 2、点击右上角,切换json模式 3、添加设置 "editor.codeActionsOn…

Rust UI开发(五):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)

注:此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库,用于为rust语言程序构建UI界面。 这是一个系列博文,本文是第五篇,前四篇链接: 1、Rust UI开发(一):使用iced构建UI时…