FairyGUI 超简单的UI框架

Laya使用fgui的超简单UI框架

使用场景:用于使用fgui进行layaUI开发的程序人员

整个框架分为3个模块,共有4个类:

  • FGUIManager :FGUI的管理类,继承于IUIManager 负责所有UI的打开关闭等事项
  • FUIBase :UI的管理基类,具体实现
  • IUIManager :FGUI的接口类 规定管理类的各个方法
  • UILayerType: UI 层级分类

FGUIManager管理类

  1. import IUIManager from "./IUIManager";
  2. import { FUIBase } from "./FUIBase";
  3. import GameEntry from "../../GameEntry";
  4. /**
  5. * @ name:FGUIManager
  6. * @ desc:自动创建说明
  7. * @ user:By NUOLO
  8. * @ data: 2021-06-02 18:14
  9. */
  10. export default class FGUIManager implements IUIManager {
  11. /**
  12. *
  13. */
  14. constructor() {
  15. this.Init();
  16. }
  17. Init(): void {
  18. Laya.stage.addChild(fgui.GRoot.inst.displayObject); //初始化FGUI
  19. this.UIroot = fgui.GRoot.inst.displayObject;
  20. this.UIroot.width = Laya.stage.width;
  21. this.UIroot.height = Laya.stage.height;
  22. fgui.UIConfig.packageFileExtension = "fui"; //设置导出文件的拓展名 代码默认的拓展名为fui,可能于自身导出的拓展名不同 但最好这样做因为有些平台只认这种文件名
  23. this.UIDic = {};
  24. }
  25. /**
  26. * UI字典
  27. */
  28. UIDic: { [name: string]: FUIBase<fgui.GComponent>};
  29. /**
  30. * UI的根节点
  31. */
  32. private UIroot: Laya.Sprite;
  33. /**
  34. * 注入FUIBase
  35. */
  36. RigisterUIBase(name: string, ui: FUIBase<fgui.GComponent>): void {
  37. if (this.UIDic[name]) {
  38. console.log(name + "::字段已存在UI界面,请勿重复添加")
  39. return;
  40. }
  41. else {
  42. this.UIDic[name] = ui;
  43. }
  44. }
  45. CreateOrOpenPanel(name: string, data?:new () => FUIBase<fgui.GComponent> , isCloseOther?: boolean): FUIBase<any> {
  46. if (!this.UIroot) {
  47. this.Init();
  48. }
  49. if (this.UIDic[name]) {
  50. return this.OpenPanel(name, isCloseOther);
  51. }
  52. else {
  53. let cla = new data();
  54. if (fgui.UIPackage.addPackage(data['ResName']) == null) {
  55. console.log('资源包未加载,将进行自动加载');
  56. fgui.UIPackage.addPackage(data['ResName']);
  57. }
  58. // let com = fgui.UIPackage.createObject(data['UIpackName'], data['UIName'], cla.ClassType).asCom;
  59. let com = fgui.UIPackage.createObjectFromURL(cla.ClassType.URL,cla.ClassType).asCom ;
  60. com.name = data['UIName'];
  61. fgui.GRoot.inst.addChild(com);
  62. com.makeFullScreen();
  63. com.sortingOrder = cla.LayerType;
  64. cla.MUI = com;
  65. cla.UIMgr = this;
  66. cla.AutoRigisterToUIManager();
  67. cla.onAwake();
  68. cla.onEnable();
  69. return cla;
  70. }
  71. }
  72. OpenPanel(name: string, isCloseOther?: boolean): FUIBase<any> {
  73. if (isCloseOther) {
  74. for (let uiname in this.UIDic) {
  75. this.UIDic[uiname].Close();
  76. }
  77. }
  78. if (this.UIDic[name]) {
  79. let ui = this.UIDic[name];
  80. ui.Open();
  81. return ui;
  82. }
  83. else {
  84. console.error(name + "::字段在UI字典中不存在,请检查是否有误")
  85. return null;
  86. }
  87. }
  88. ClosePanel(name: string, toOpenWindow?: string): void {
  89. if (this.UIDic[name]) {
  90. let ui = this.UIDic[name];
  91. ui.Close();
  92. if (toOpenWindow != null) {
  93. this.OpenPanel(toOpenWindow);
  94. }
  95. }
  96. else {
  97. console.log(name + "::字段在UI字典中不存在,请检查是否有误")
  98. }
  99. }
  100. CloseAllPanel(): void {
  101. for (const key in this.UIDic) {
  102. this.UIDic[key].Close();
  103. }
  104. }
  105. GetUIPanel(name: string): any {
  106. if (this.UIDic[name]) {
  107. return this.UIDic[name] ;
  108. }
  109. else {
  110. console.log(name + "::字段在Ui字典中不存在,请检查")
  111. return null;
  112. }
  113. }
  114. DestoryUIPanel(name: string) {
  115. if (this.UIDic[name]) {
  116. this.UIDic[name].Destory();
  117. }
  118. else {
  119. console.log(name + "::字段在Ui字典中不存在,请检查")
  120. }
  121. }
  122. }

FUIBase

  1. import AssetData from "../../Asset/AssetData";
  2. import Debug from "../../Debug/Debug";
  3. import GameEntry from "../../GameEntry";
  4. import IUIManager from "./IUIManager";
  5. import { UILayerType } from "./UILayerType";
  6. /**
  7. * @ name:FUIBase
  8. * @ desc:自动创建说明
  9. * @ user:By NUOLO
  10. * @ data: 2021-06-02 16:24
  11. */
  12. export class FUIBase<T extends fgui.GComponent> {
  13. /**需子类设置 导出包的路径 */
  14. public static ResName: string = "res/UIVSLoading";
  15. /**需子类设置 图集的数量 从0 开始 */
  16. public static AtliasCount: number = 1;
  17. public static UIName: string = "1"; //UI的名字 要存在字典中
  18. public get UIName(): string { return FUIBase.UIName; }
  19. public set UIName(v: string) { FUIBase.UIName = v; }
  20. /** UI的层级 默认0级为最底层 */
  21. public LayerType: UILayerType = UILayerType.Normal;
  22. /**fgui 组件 */
  23. private m_uiComPonent: T;
  24. public get MUI(): T { return this.m_uiComPonent; }
  25. public set MUI(v: T) { this.m_uiComPonent = v; }
  26. /**fgui 组件 */
  27. public ClassType: any;
  28. /**UI管理类 */
  29. private m_uimgr: IUIManager;
  30. public get UIMgr(): IUIManager { return this.m_uimgr; }
  31. public set UIMgr(v: IUIManager) { this.m_uimgr = v; }
  32. /**
  33. * 自动注册进UIManager
  34. */
  35. public AutoRigisterToUIManager() {
  36. this.UIMgr.RigisterUIBase(this.UIName, this);
  37. }
  38. /**
  39. * 打开界面
  40. */
  41. public Open() {
  42. this.onEnable();
  43. this.m_uiComPonent.visible = true;
  44. }
  45. /**
  46. * 关闭界面
  47. */
  48. public Close() {
  49. this.onDisable();
  50. this.m_uiComPonent.visible = false;
  51. }
  52. /**
  53. * 销毁界面
  54. */
  55. public Destory() {
  56. this.m_uiComPonent.dispose();
  57. }
  58. //#region fgui加载
  59. /**
  60. * 获取当前界面所对应的资源文件
  61. * @returns
  62. */
  63. public static GetLoadUIPackDic(): any[] {
  64. let urls = [];
  65. urls.push({ url: this.ResName + ".fui", type: Laya.Loader.BUFFER });
  66. urls.push({ url: this.ResName + "_atlas0.png", type: Laya.Loader.IMAGE });
  67. //加载纹理集
  68. if (this.AtliasCount >=1) {
  69. for (let i = 1; i <= this.AtliasCount; i++) {
  70. urls.push({ url: this.ResName + "_atlas0_" + i + ".png", type: Laya.Loader.IMAGE });
  71. }
  72. }
  73. return urls;
  74. }
  75. /**
  76. * 获取FGUI 二进制文件路径
  77. * @returns 对应路径
  78. */
  79. public static GetUIByte(): string {
  80. return this.ResName + ".fui";
  81. }
  82. /**
  83. * 加载完成之后 将包添加到fgui包管理中
  84. */
  85. public static AddPackage() {
  86. fgui.UIPackage.addPackage(this.ResName);
  87. }
  88. //#endregion
  89. //#region 功能
  90. /**
  91. * 获得子节点
  92. * @param path 路径信息 s.b.v
  93. */
  94. public FindChild<T extends fgui.GObject>(path: String): T {
  95. return this.m_uiComPonent.getChildByPath(path) as T;
  96. }
  97. /**
  98. * 添加事件监听
  99. * @param btn 点击按钮
  100. * @param callback 回调
  101. * @param args 传递数据
  102. */
  103. public AddLinster(btn: fgui.GObject, callback, ...args) {
  104. btn.onClick(this, callback, args);
  105. }
  106. /**
  107. * 移除事件监听
  108. * @param btn 按钮
  109. * @param callback 回调
  110. */
  111. public RemoveLinster(btn: fgui.GObject, callback) {
  112. btn.offClick(btn, callback);
  113. }
  114. //#endregion
  115. //#region 生命流程
  116. onAwake() {} //onAwake 创建时调用
  117. onEnable() {} //每次打开时调用,可自行拓展打开时的打开效果等功能
  118. onDisable() {} //每次关闭时调用,可自行拓展关闭时的 所需调用的功能
  119. //#endregion
  120. }

IUIManager

  1. import { FUIBase } from "./FUIBase";
  2. /**
  3. * @ name:IUIManager
  4. * @ desc:UI管理类的接口
  5. * @ user:By NUOLO
  6. * @ data: 2021-06-02 16:14
  7. */
  8. export default interface IUIManager {
  9. /**
  10. * 初始化
  11. */
  12. Init():void
  13. /**
  14. * UI字典
  15. */
  16. UIDic: { [name: string]: FUIBase<any> };
  17. /**
  18. * 注入FUIBase
  19. */
  20. RigisterUIBase(name: string, ui: FUIBase<any>): void;
  21. /**
  22. * 自动创建 或者打开 界面 注意:创建UI是异步操作的
  23. * @param name 名字
  24. * @param isCloseOther 是否关闭其他界面
  25. * @param data 数据
  26. */
  27. CreateOrOpenPanel(name: string, data?:any, isCloseOther?: boolean ): FUIBase<any>
  28. /**
  29. * 打开UI界面
  30. * @param name 要打开界面的名字
  31. * @param isCloseOther 是否关闭其他界面 默认否
  32. */
  33. OpenPanel(name: string, isCloseOther?: boolean): FUIBase<any>;
  34. /**
  35. * 关闭UI界面
  36. * @param name 要关闭UI界面的名字
  37. * @param TOOpen 关闭此界面后要打开的界面的名字 默认无 不打开其他界面
  38. */
  39. ClosePanel(name: string,toOpenWindow?:string): void;
  40. /**
  41. * 关闭所有UI界面
  42. */
  43. CloseAllPanel(): void;
  44. /**
  45. * 根据标识符获取FUIBase
  46. * @param name 标识符
  47. */
  48. GetUIPanel(name: string):any;
  49. /**
  50. * 销毁UIPanel
  51. * @param name 标识符
  52. */
  53. DestoryUIPanel(name: string);
  54. }

UILayerType

  1. /**
  2. * @ name:UILayerType
  3. * @ desc:UI 层级分类
  4. * @ user:By NUOLO
  5. * @ data: 2021-06-02 16:55
  6. */
  7. export enum UILayerType {
  8. //普通窗体
  9. Normal=0,
  10. //固定窗体
  11. Fixed=20,
  12. //弹出窗体
  13. PopUp = 50,
  14. //提示窗体
  15. Tip = 40,
  16. }

框架就分为这4个类 使用的话就每个UI界面都继承 FUIBase<具体fgui导出的UI类>

并重写 参数

如例子:

  1. fgui 导出文件为 Package1.fui
  2. Package1Binder.ts
  3. UI_Component1.ts
  4. Package1Binder.ts
  5. 新建一个ShowUI 的脚本 继承与FUIBase <UI_Component1>

示例 ShowUI类

  1. import { FUIBase } from "../Core/UI/FGUI/FUIBase";
  2. import { UILayerType } from "../Core/UI/FGUI/UILayerType";
  3. import Package1Binder from "./Package1/Package1Binder";
  4. import UI_Component1 from "./Package1/UI_Component1";
  5. /**
  6. * @ name:ShowUI
  7. * @ desc:UI的控制类
  8. * @ user:By NUOLO
  9. * @ data: 2021-06-09 11:00
  10. */
  11. export default class ShowUI extends FUIBase <UI_Component1>{
  12. public static ResName: string = "res/FGUI/Package1"; //路径
  13. public static AtliasCount: number = 0; //图集数量 从0开始
  14. public static UIName: string = "1"; //名称
  15. constructor() {
  16. super();
  17. this.LayerType = UILayerType.Normal; //设置层级
  18. this.ClassType = UI_Component1; //设置UI所对应的类,,确定好再填
  19. Package1Binder.bindAll(); //UI绑定类
  20. }
  21. onAwake() {
  22. super.onAwake();
  23. }
  24. onEnable() {
  25. super.onEnable();
  26. }
  27. onDisable() {
  28. super.onDisable();
  29. }
  30. }

示例 调用方法

  1. onConfigLoaded(): void {
  2. //加载IDE指定的场景
  3. // GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
  4. this.openFGUI();
  5. }
  6. openFGUI() {
  7. let uimagr = new FGUIManager(); //初始化UI管理类
  8. //打开界面
  9. Laya.loader.create(ShowUI.GetLoadUIPackDic(), Laya.Handler.create(this, () => {
  10. uimagr.CreateOrOpenPanel(ShowUI.UIName, ShowUI);
  11. }));
  12. }

整个调用过程都很简单,代码逻辑也很明了,自己正在使用中

如果有更好的方法和更优雅的写法,也请通过邮件联系我,共同学习一下,多谢!

个人博客地址 https://nuolo.xyz

laya fgui 超简单的UI框架的更多相关文章

  1. WPF - 简单的UI框架

    实现了一个简单的WPF应用程序UI框架 ,分享出来.界面效果图如下: 运行效果如下: 喜欢的可以下载源码参考:https://github.com/DuelWithSelf/WPFEffects 左侧 ...

  2. WPF - 简单的UI框架 - 仪表盘

    源码链接:https://github.com/DuelWithSelf/WPFEffects 参考:https://www.cnblogs.com/duel/p/duel_clock.html 更新 ...

  3. 【设计和开发一套简单自己主动化UI框架】

    !有兴趣的朋友请直接移步Github,本帖子已经不做更新,框架的详细的实现已经做了优化和代码整理,本文仅仅介绍了详细的设计思路! 目标:编写一个简单通用UI框架用于管理页面和完毕导航跳转 终于的实现效 ...

  4. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  5. ssh框架整合---- spring 4.0 + struts 2.3.16 + maven ss整合超简单实例

    一 . 需求 学了这么久的ssh,一直都是别人整合好的框架去写代码,自己实际动手时才发现框架配置真是很坑爹,一不小心就踏错,真是纸上得来终觉浅! 本文将记录整合struts + spring的过程 , ...

  6. (转载)基于Unity~UGUI的简单UI框架(附UIFramework源码)

    此博客跟随siki老师的课程笔记生成,感谢siki老师的辛勤付出! 此框架功能较简单,适用于学习,可以很好的锻炼我们的设计思想 框架源码地址: UIFramework litjson.dll下载地址: ...

  7. 关于几种UI框架简单总结

    最近两年多的时间先后做过几款终端程序,UI框架从MFC转向过WxWidgets,之后再转向Qt.三种框架精通远谈不上,用起来还是没什么问题. 简单聊聊三种框架的优缺点. 1.MFC 似乎作为一种饱受批 ...

  8. ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  9. 如何快速体验鸿蒙全新声明式UI框架ArkUI?

    HDC2021将于10月22日在东莞松山湖正式开幕,大会将设立Codelab体验专区,超多好玩.有趣的Demo等你体验.想快速入门HarmonyOS?学习HarmonyOS新特性?以下几个Codela ...

随机推荐

  1. Python中的迭代器、生成器、装饰器

    1. 迭代器  1 """ 2 iterator 3 迭代器协议: 对象必须提供一个next()方法,执行该方法要么返回迭代中的下一项,要么引起一个StopIterati ...

  2. 类的两个装饰器classmethod、staticethod和内置魔术方法

    一.两个装饰器@classmethod.@staticmethod @classmethod:把类中的绑定方法变成一个类方法,cls 就等于类名 有什么用? 1.在方法中任然可以引用类中的静态变量 2 ...

  3. 2-9-9-12分页机制(xp)

    10-10-12分页限制 10-10-12分页因为页表PEB只有四个字节所以只能访问2^32 = 4GB物理地址空间,现在的物理内存都大于4GB为了能访问到更多的物理内存2-9-9-12将PEB的大小 ...

  4. 改善c++程序的150个建议(读后总结)-------10-11

    10. 优化结构体中元素的布局 结构体变量所占空间大小并不是其所含类型所占字节数之和,其所占内存字节数涉及到字节对齐. 字节对齐 :变量在内存中储存都是以字节数为单位,每一个字节都有自己的地址,逻辑上 ...

  5. Pytorch_Part4_损失函数

    VisualPytorch beta发布了! 功能概述:通过可视化拖拽网络层方式搭建模型,可选择不同数据集.损失函数.优化器生成可运行pytorch代码 扩展功能:1. 模型搭建支持模块的嵌套:2. ...

  6. 【BUAA 软工博客作业】个人博客作业

    项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:热身作业,阅读并撰写博客 作业要求 课程目标 学习大规模软件开发的技巧与方法,锻炼开发能力 作业目标 阅读教材, ...

  7. opencv——轮廓发现与轮廓(二值图像)分析

    引言 二值图像分析最常见的一个主要方式就是轮廓发现与轮廓分析,其中轮廓发现的目的是为轮廓分析做准备,经过轮廓分析我们可以得到轮廓各种有用的属性信息. 这里顺带提下边缘检测,和轮廓提取的区别: 边缘检测 ...

  8. 每天一个linux命令(49):at命令   atrm删除作业,由作业号标识。

    atq命令 例如:从现在起三天后的下午四点运行作业at 4pm + 3 days:在July 31上午十点运行作业at 10am July 31:明天上午一点运行作业at 1am tomorrow. ...

  9. 【BIGDATA】ElasticSearch HEAD插件的GET请求的坑

    今使用HEAD插件,发现复杂查询功能下,使用GET请求有坑. 查询语句如下: GET kk/_search { "query": { "match": { &q ...

  10. MyBatis 高级查询之一对多查询(十)

    高级查询之一对多查询 查询条件:根据游戏名称,查询游戏账号信息 我们在之前创建的映射器接口 GameMapper.java 中添加接口方法,如下: /** * 根据游戏名查询游戏账号 * @param ...