html做网站项目案例,建设部网站关于公租房,建站公司那家好,网站策划运营引擎#xff1a; CocosCreator 3.8.0
环境#xff1a; Mac
Gitee: oops-game-kit 注#xff1a; 作者dgflash的oops-framework框架QQ群#xff1a; 628575875 回顾 在上文中主要通过oops-game-kit大家了一个新的模版项目#xff0c; 主要注意项是resources目录下的两个文…引擎 CocosCreator 3.8.0
环境 Mac
Gitee: oops-game-kit 注 作者dgflash的oops-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提示
继承结构如下 #mermaid-svg-d31C3yCki6D7T7Xn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .error-icon{fill:#552222;}#mermaid-svg-d31C3yCki6D7T7Xn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-d31C3yCki6D7T7Xn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-d31C3yCki6D7T7Xn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-d31C3yCki6D7T7Xn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-d31C3yCki6D7T7Xn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-d31C3yCki6D7T7Xn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-d31C3yCki6D7T7Xn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-d31C3yCki6D7T7Xn .marker.cross{stroke:#333333;}#mermaid-svg-d31C3yCki6D7T7Xn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-d31C3yCki6D7T7Xn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .cluster-label text{fill:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .cluster-label span{color:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .label text,#mermaid-svg-d31C3yCki6D7T7Xn span{fill:#333;color:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .node rect,#mermaid-svg-d31C3yCki6D7T7Xn .node circle,#mermaid-svg-d31C3yCki6D7T7Xn .node ellipse,#mermaid-svg-d31C3yCki6D7T7Xn .node polygon,#mermaid-svg-d31C3yCki6D7T7Xn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-d31C3yCki6D7T7Xn .node .label{text-align:center;}#mermaid-svg-d31C3yCki6D7T7Xn .node.clickable{cursor:pointer;}#mermaid-svg-d31C3yCki6D7T7Xn .arrowheadPath{fill:#333333;}#mermaid-svg-d31C3yCki6D7T7Xn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-d31C3yCki6D7T7Xn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-d31C3yCki6D7T7Xn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-d31C3yCki6D7T7Xn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-d31C3yCki6D7T7Xn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-d31C3yCki6D7T7Xn .cluster text{fill:#333;}#mermaid-svg-d31C3yCki6D7T7Xn .cluster span{color:#333;}#mermaid-svg-d31C3yCki6D7T7Xn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-d31C3yCki6D7T7Xn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 主界面 游戏层 引导层 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
}注这个接口的定义在页面参数传递或动画播放中使用很频繁。 弹窗示例
在框架的弹窗中 虽有PopUpDialogSystem的几种类型但他们是类似的
PopUp 打开以后支持非窗口区域透点支持打开多个不同配置的弹窗Dialog 仅支持显示一个非窗口区域不可透点System 同Dialog类似作者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-framework的TipsManager.ts中增加了更多的窗口示例推荐查看学习 Toast示例
提示内容的显示就相对简单了主要代码如下
private _tipIndex: number 0;public clickTip(event, customData: string) {this._tipIndex;// 参数内容是否使用多语言默认falseoops.gui.toast(这是第${this._tipIndex}个提示);
}总结
在框架中对界面的显示和隐藏主要逻辑如下
页面的构建继承于Component即可如果需要获取参数就增加 onAdded 方法在GameUIConfig.ts中设置 UIID的唯一标识符ID 和 UIConfig 配置页面的调用使用open或openAsync提示的显示使用Toast
最后注意
任何页面的显示不建议重复调用
oops.gui.open(UIID.UI_LAYER, {param: 参数});
oops.gui.open(UIID.UI_LAYER, {param: 参数});注框架会告知路径为【game/prefab/uiLayer】的预制重复加载 PopUp的弹窗支持显示多个指的是不同配置的Pop弹窗原因1
感谢作者dgflash的分享作者CSDN博客 dgflash CSDN
最后祝大家学习和生活愉快!