UIManager.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import { Constructor, director, error, find, instantiate, Node, Prefab, resources, Scene } from "cc";
  2. import { UIBase, UIType } from "../Game/GameFrameWork/UIBase";
  3. class UIManager {
  4. static instance: UIManager = null;
  5. private _uis: Map<string, UIBase> = new Map();
  6. private _uiNodes: Map<string, Node> = new Map();
  7. private _prefabs: Map<string, Prefab> = new Map();
  8. //获取UI
  9. getUI<T extends UIBase>(name: string | Constructor<T>): T {
  10. if (typeof (name) === "string") {
  11. return <T>this._uis.get(name);
  12. }
  13. //遍历所有的value组成的数组
  14. for (const ui of Array.from(this._uis.values())) {
  15. if (ui instanceof name) {
  16. return <T>ui;
  17. }
  18. }
  19. return null;
  20. }
  21. //打开页面 全屏 弹窗 挂件
  22. async openUI(preName: string, type: UIType = UIType.PAGE) {
  23. let ui = this._uis.get(preName);
  24. if (ui) {
  25. //把ui显示出来
  26. ui.show();
  27. return;
  28. }
  29. //是否在节点容器当中
  30. let node = this._uiNodes.get(preName);
  31. if (node) {
  32. node.active = true;
  33. return;
  34. }
  35. //node 不存在的情况下 加载出来
  36. //先判断一下预制体是否下载过
  37. let prefab = this._prefabs.get(preName);
  38. if (!prefab) {
  39. prefab = await this._loadUI("UI/" + preName);
  40. this._prefabs.set(preName, prefab)
  41. }
  42. //查找ui根节点
  43. node = instantiate(prefab);
  44. let root = find("Canvas/UIRoot");
  45. if(!root){
  46. //如果场景当中没有 就加载预制体 创建一个
  47. const rootPre: Prefab = await this._loadUI("UI/UIRoot")
  48. root = instantiate(rootPre);
  49. root.parent = find("Canvas");
  50. }
  51. node.parent = root.children[type];
  52. //处理逻辑
  53. ui = node.getComponent(UIBase);
  54. if (ui) {
  55. //对ui进行多态处理
  56. ui.init();
  57. ui.UIName = preName;
  58. this._uis.set(preName, ui);
  59. return;
  60. }
  61. this._uiNodes.set(preName, node);
  62. // resources.load("UI/" + preName, Prefab, (err: Error, asset: Prefab)=>{
  63. // const node = instantiate(asset);
  64. // node.parent = find("Canvas/UIRoot").children[type];
  65. // //处理逻辑
  66. // const ui = node.getComponent(UIBase);
  67. // //对UI进行多态处理
  68. // })
  69. }
  70. async openScene(sceneName: string, uiName?: string){
  71. await this._loadScene(sceneName);
  72. uiName && this.openUI(uiName);
  73. }
  74. private _loadScene(sceneName: string){
  75. new Promise((revolve, reject)=>{
  76. director.loadScene(sceneName,(err: Error, scene: Scene)=>{
  77. if(err){
  78. error("加载" + sceneName + "场景错误!");
  79. reject(err);
  80. }
  81. else{
  82. revolve(scene);
  83. }
  84. })
  85. })
  86. }
  87. //加载UI预制体
  88. private _loadUI(path: string): Promise<Prefab> {
  89. return new Promise((revole, reject) => {
  90. resources.load(path, Prefab, (err: Error, asset: Prefab) => {
  91. if (err) {
  92. reject(err);
  93. } else {
  94. revole(asset);
  95. }
  96. })
  97. })
  98. }
  99. //关闭UI
  100. closeUI(uibase: string | UIBase, clear: boolean = true){
  101. let ui: UIBase;
  102. if(typeof(uibase) === "string"){
  103. ui = this._uis.get(uibase);
  104. if(ui){
  105. ui.hide(clear);
  106. clear && this._uis.delete(uibase);
  107. }
  108. return;
  109. }
  110. uibase.hide(clear);
  111. clear && this._uis.delete(uibase.UIName);
  112. return;
  113. // for(const u of Array.from(this._uis.values())){
  114. // if(uiName === u){
  115. // u.hide(clear);
  116. // return;
  117. // }
  118. // }
  119. }
  120. //UI之间的消息互通
  121. sendMsg(msg: string,ui: string|UIBase, ...args){
  122. let m: UIBase;
  123. if(typeof(ui) === "string"){
  124. m = this.getUI(ui);
  125. }
  126. else{
  127. m = ui;
  128. }
  129. //判断如果找到的UI模块是个空 什么也不做
  130. if(!m){
  131. return;
  132. }
  133. //m 是个对象 找m中有没有 名字叫做msg的函数
  134. //对象都是键值对 访问键对应的值
  135. const func = m[msg];
  136. if(func && typeof(func) === "function"){
  137. func.apply(m, [...args]);
  138. return;
  139. }
  140. }
  141. }
  142. export const UIMgr: UIManager = UIManager.instance = new UIManager();