Sfoglia il codice sorgente

【更新】:
1.添加音效;

youhaitao 2 anni fa
parent
commit
9e18fa8ade
91 ha cambiato i file con 3163 aggiunte e 710 eliminazioni
  1. 5 5
      README.md
  2. 2 2
      assets/game/b01_u01/b01_u01_g01/res/spine/flowerpot/flowerpot.png.meta
  3. 3 0
      assets/game/b01_u01/b01_u01_g01/src/Game_b01_u01_g01.ts
  4. 99 101
      assets/main/SceneMain.fire
  5. 81 32
      assets/main/SceneMain.ts
  6. BIN
      assets/res/common/audio/finish_0.mp3
  7. 1 1
      assets/res/common/audio/finish_0.mp3.meta
  8. BIN
      assets/res/common/audio/finish_1.mp3
  9. 1 1
      assets/res/common/audio/finish_1.mp3.meta
  10. BIN
      assets/res/common/audio/finish_2.mp3
  11. 1 1
      assets/res/common/audio/finish_2.mp3.meta
  12. BIN
      assets/res/common/img/btnNext.png
  13. 38 0
      assets/res/common/img/btnNext.png.meta
  14. 3 2
      assets/res/downCount/src/DownCount.ts
  15. 1 1
      assets/res/http.meta
  16. 0 0
      assets/res/http/HttpStateMap.ts
  17. 1 1
      assets/res/http/HttpStateMap.ts.meta
  18. 7 5
      assets/res/luojigouFinish/src/LuojigouFinish.ts
  19. 1 1
      assets/res/luojigouStart/res/prefab/luojigouStart.prefab
  20. 15 14
      assets/res/luojigouStart/src/LuojigouStart.ts
  21. 10 8
      assets/res/tipHand/src/TipHand.ts
  22. 0 12
      assets/res/tipHand/描述文本.md
  23. 0 6
      assets/res/tipHand/描述文本.md.meta
  24. 13 0
      assets/res/videoPlayer/res/img.meta
  25. BIN
      assets/res/videoPlayer/res/img/bg.jpg
  26. 38 0
      assets/res/videoPlayer/res/img/bg.jpg.meta
  27. BIN
      assets/res/videoPlayer/res/img/btn_replay.png
  28. 38 0
      assets/res/videoPlayer/res/img/btn_replay.png.meta
  29. 450 3
      assets/res/videoPlayer/res/prefab/videoPlayer.prefab
  30. 62 25
      assets/res/videoPlayer/src/VideoPlayer.ts
  31. 13 0
      assets/resources.meta
  32. 13 0
      assets/resources/audio.meta
  33. BIN
      assets/resources/audio/button_touch.mp3
  34. 8 0
      assets/resources/audio/button_touch.mp3.meta
  35. BIN
      assets/resources/audio/clock.mp3
  36. 8 0
      assets/resources/audio/clock.mp3.meta
  37. BIN
      assets/resources/audio/error_good_0.mp3
  38. 8 0
      assets/resources/audio/error_good_0.mp3.meta
  39. BIN
      assets/resources/audio/error_good_1.mp3
  40. 8 0
      assets/resources/audio/error_good_1.mp3.meta
  41. BIN
      assets/resources/audio/error_touch.mp3
  42. 8 0
      assets/resources/audio/error_touch.mp3.meta
  43. BIN
      assets/resources/audio/good_move.mp3
  44. 8 0
      assets/resources/audio/good_move.mp3.meta
  45. BIN
      assets/resources/audio/good_touch.mp3
  46. 8 0
      assets/resources/audio/good_touch.mp3.meta
  47. BIN
      assets/resources/audio/handTip.mp3
  48. 8 0
      assets/resources/audio/handTip.mp3.meta
  49. BIN
      assets/resources/audio/particle_0.mp3
  50. 8 0
      assets/resources/audio/particle_0.mp3.meta
  51. BIN
      assets/resources/audio/particle_1.mp3
  52. 8 0
      assets/resources/audio/particle_1.mp3.meta
  53. BIN
      assets/resources/audio/right_0.mp3
  54. 8 0
      assets/resources/audio/right_0.mp3.meta
  55. BIN
      assets/resources/audio/right_1.mp3
  56. 8 0
      assets/resources/audio/right_1.mp3.meta
  57. BIN
      assets/resources/audio/right_2.mp3
  58. 8 0
      assets/resources/audio/right_2.mp3.meta
  59. BIN
      assets/resources/audio/right_3.mp3
  60. 8 0
      assets/resources/audio/right_3.mp3.meta
  61. BIN
      assets/resources/audio/star_1.mp3
  62. 8 0
      assets/resources/audio/star_1.mp3.meta
  63. BIN
      assets/resources/audio/star_2.mp3
  64. 8 0
      assets/resources/audio/star_2.mp3.meta
  65. BIN
      assets/resources/audio/star_3.mp3
  66. 8 0
      assets/resources/audio/star_3.mp3.meta
  67. BIN
      assets/resources/audio/star_hide.mp3
  68. 8 0
      assets/resources/audio/star_hide.mp3.meta
  69. 20 0
      assets/resources/configAudio.json
  70. 6 0
      assets/resources/configAudio.json.meta
  71. 13 0
      assets/resources/prefab.meta
  72. 1155 0
      assets/resources/prefab/popUp.prefab
  73. 9 0
      assets/resources/prefab/popUp.prefab.meta
  74. 15 21
      assets/src/audioUitls/AudioCB.ts
  75. 43 0
      assets/src/audioUitls/AudioManager.ts
  76. 1 1
      assets/src/audioUitls/AudioManager.ts.meta
  77. 0 1
      assets/src/common/CConst.ts
  78. 32 5
      assets/src/common/GameBase.ts
  79. 26 10
      assets/src/common/Tools.ts
  80. 140 10
      assets/src/common/common.ts
  81. 3 2
      assets/src/config/Loader.ts
  82. 0 243
      assets/src/http/Http.ts
  83. 0 141
      assets/src/http/HttpSystem.ts
  84. 0 53
      assets/src/http/IHttpSystem.ts
  85. 13 0
      assets/src/popUp.meta
  86. 57 0
      assets/src/popUp/ConfirmPopup.ts
  87. 1 1
      assets/src/popUp/ConfirmPopup.ts.meta
  88. 144 0
      assets/src/popUp/PopupBase.ts
  89. 1 1
      assets/src/popUp/PopupBase.ts.meta
  90. 434 0
      assets/src/popUp/PopupManager.ts
  91. 10 0
      assets/src/popUp/PopupManager.ts.meta

+ 5 - 5
README.md

@@ -21,15 +21,15 @@
         ]
     3.每个游戏内的配置文件:b01_u01_g01/config.json // 第一册 第一集 第一个游戏
         {
-            "star": 4,// 难度系数
-            "type": "[观察力挑战四]", // 卡片页描述1
-            "title": "根据部分花纹找相同" // 卡片页描述2
+            "star": 1,// 难度系数
+            "type": "[观察力挑战一]", // 卡片页描述
+            "title": "根据部分花纹找相同" // 卡片页描述
         }
 
 测试配置:
     assets/src/common/common.ts
         isDebug: boolean = true;// 是否开启测试
-        unitCur: number = 6;// 第几集,从1开始
-        pageCur: number = 4;// 第几个游戏,从1开始
+        unitCur: number = 1;// 第几集,从1开始
+        pageCur: number = 1;// 第几个游戏,从1开始
     上面的描述:测试状态,从第六集第四个游戏开始测试。
 

+ 2 - 2
assets/game/b01_u01/b01_u01_g01/res/spine/flowerpot/flowerpot.png.meta

@@ -8,8 +8,8 @@
   "premultiplyAlpha": false,
   "genMipmaps": false,
   "packable": true,
-  "width": 1216,
-  "height": 167,
+  "width": 558,
+  "height": 339,
   "platformSettings": {},
   "subMetas": {
     "flowerpot": {

+ 3 - 0
assets/game/b01_u01/b01_u01_g01/src/Game_b01_u01_g01.ts

@@ -302,12 +302,14 @@ export default class Game_b01_u01_g01 extends GameBase {
             ).call(() => {
                 itemQ.active = false;
             }).start();
+            this.playAudioGoodMove();
         };
 
         // 角色声音和动作
         let audio = this.arrAudioRight[dataOne.roleId];
         let timeRole = audio.duration;
         let funcRole = () => {
+            this.playAudioRight();
             let spineRole = role.getChildByName('spineRole');
             let skeRole = spineRole.getComponent(sp.Skeleton);
             skeRole.setSkin(dataOne.roleSkin);
@@ -334,6 +336,7 @@ export default class Game_b01_u01_g01 extends GameBase {
      */
     playAniWrong(_data: MsgForGame, callBack: Function): void {
         let itemQ = this.arrQues[_data.idQ];
+        this.playAudioErrorYao();
         cc.tween(itemQ)
             .to(0.2, { angle: -5 })
             .to(0.2, { angle: 5 })

+ 99 - 101
assets/main/SceneMain.fire

@@ -73,6 +73,9 @@
       },
       {
         "__id__": 5
+      },
+      {
+        "__id__": 7
       }
     ],
     "_active": true,
@@ -137,7 +140,7 @@
   },
   {
     "__type__": "cc.Node",
-    "_name": "Main Camera",
+    "_name": "bg",
     "_objFlags": 0,
     "_parent": {
       "__id__": 2
@@ -160,8 +163,8 @@
     },
     "_contentSize": {
       "__type__": "cc.Size",
-      "width": 0,
-      "height": 0
+      "width": 2480,
+      "height": 1440
     },
     "_anchorPoint": {
       "__type__": "cc.Vec2",
@@ -174,7 +177,7 @@
       "array": [
         0,
         0,
-        292.7165864791403,
+        0,
         0,
         0,
         0,
@@ -195,66 +198,52 @@
     "_is3DNode": false,
     "_groupIndex": 0,
     "groupIndex": 0,
-    "_id": "6cpkuQ6cRBtbztWX0p1RLQ"
+    "_id": "6fzT7uVktEdYAS59qVBov/"
   },
   {
-    "__type__": "cc.Camera",
+    "__type__": "cc.Sprite",
     "_name": "",
     "_objFlags": 0,
     "node": {
       "__id__": 3
     },
     "_enabled": true,
-    "_cullingMask": 4294967295,
-    "_clearFlags": 7,
-    "_backgroundColor": {
-      "__type__": "cc.Color",
-      "r": 0,
-      "g": 0,
-      "b": 0,
-      "a": 0
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "7d07c1e2-73b5-410d-998f-dbe6f1cc8026"
     },
-    "_depth": -1,
-    "_zoomRatio": 1,
-    "_targetTexture": null,
-    "_fov": 60,
-    "_orthoSize": 10,
-    "_nearClip": 1,
-    "_farClip": 4096,
-    "_ortho": true,
-    "_rect": {
-      "__type__": "cc.Rect",
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
       "x": 0,
-      "y": 0,
-      "width": 1,
-      "height": 1
+      "y": 0
     },
-    "_renderStages": 1,
-    "_alignWithScreen": true,
-    "_id": "ea1MDxU7BPMb9AjP2dy+Az"
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": "c3HBEHJz9MNqvFbgEm4Cp+"
   },
   {
     "__type__": "cc.Node",
-    "_name": "btnNext",
+    "_name": "Main Camera",
     "_objFlags": 0,
     "_parent": {
       "__id__": 2
     },
-    "_children": [
-      {
-        "__id__": 6
-      }
-    ],
+    "_children": [],
     "_active": true,
     "_components": [
       {
-        "__id__": 8
-      },
-      {
-        "__id__": 9
-      },
-      {
-        "__id__": 10
+        "__id__": 6
       }
     ],
     "_prefab": null,
@@ -262,14 +251,14 @@
     "_color": {
       "__type__": "cc.Color",
       "r": 255,
-      "g": 0,
+      "g": 255,
       "b": 255,
       "a": 255
     },
     "_contentSize": {
       "__type__": "cc.Size",
-      "width": 100,
-      "height": 100
+      "width": 1920,
+      "height": 1080
     },
     "_anchorPoint": {
       "__type__": "cc.Vec2",
@@ -280,10 +269,10 @@
       "__type__": "TypedArray",
       "ctor": "Float64Array",
       "array": [
-        910,
-        490,
         0,
         0,
+        292.7165864791403,
+        0,
         0,
         0,
         1,
@@ -303,20 +292,62 @@
     "_is3DNode": false,
     "_groupIndex": 0,
     "groupIndex": 0,
-    "_id": "5cG5KB0fpMNZKVSQaNJ9wd"
+    "_id": "6cpkuQ6cRBtbztWX0p1RLQ"
+  },
+  {
+    "__type__": "cc.Camera",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 5
+    },
+    "_enabled": true,
+    "_cullingMask": 4294967295,
+    "_clearFlags": 7,
+    "_backgroundColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 0
+    },
+    "_depth": -1,
+    "_zoomRatio": 1,
+    "_targetTexture": null,
+    "_fov": 60,
+    "_orthoSize": 10,
+    "_nearClip": 1,
+    "_farClip": 4096,
+    "_ortho": true,
+    "_rect": {
+      "__type__": "cc.Rect",
+      "x": 0,
+      "y": 0,
+      "width": 1,
+      "height": 1
+    },
+    "_renderStages": 1,
+    "_alignWithScreen": true,
+    "_id": "ea1MDxU7BPMb9AjP2dy+Az"
   },
   {
     "__type__": "cc.Node",
-    "_name": "label",
+    "_name": "btnNext",
     "_objFlags": 0,
     "_parent": {
-      "__id__": 5
+      "__id__": 2
     },
     "_children": [],
-    "_active": true,
+    "_active": false,
     "_components": [
       {
-        "__id__": 7
+        "__id__": 8
+      },
+      {
+        "__id__": 9
+      },
+      {
+        "__id__": 10
       }
     ],
     "_prefab": null,
@@ -331,7 +362,7 @@
     "_contentSize": {
       "__type__": "cc.Size",
       "width": 100,
-      "height": 72.32
+      "height": 100
     },
     "_anchorPoint": {
       "__type__": "cc.Vec2",
@@ -342,8 +373,8 @@
       "__type__": "TypedArray",
       "ctor": "Float64Array",
       "array": [
-        0,
-        0,
+        900,
+        480,
         0,
         0,
         0,
@@ -351,7 +382,7 @@
         1,
         1,
         1,
-        1
+        0
       ]
     },
     "_eulerAngles": {
@@ -365,47 +396,14 @@
     "_is3DNode": false,
     "_groupIndex": 0,
     "groupIndex": 0,
-    "_id": "ebeg43vZNKzoNwsfI81U5q"
-  },
-  {
-    "__type__": "cc.Label",
-    "_name": "",
-    "_objFlags": 0,
-    "node": {
-      "__id__": 6
-    },
-    "_enabled": true,
-    "_materials": [
-      {
-        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
-      }
-    ],
-    "_srcBlendFactor": 770,
-    "_dstBlendFactor": 771,
-    "_string": "下一个游戏",
-    "_N$string": "下一个游戏",
-    "_fontSize": 32,
-    "_lineHeight": 32,
-    "_enableWrapText": true,
-    "_N$file": null,
-    "_isSystemFontUsed": true,
-    "_spacingX": 0,
-    "_batchAsBitmap": false,
-    "_styleFlags": 0,
-    "_underlineHeight": 0,
-    "_N$horizontalAlign": 1,
-    "_N$verticalAlign": 1,
-    "_N$fontFamily": "Arial",
-    "_N$overflow": 3,
-    "_N$cacheMode": 0,
-    "_id": "09MbeTD1BHRZNkcH70DHDa"
+    "_id": "5cG5KB0fpMNZKVSQaNJ9wd"
   },
   {
     "__type__": "cc.Sprite",
     "_name": "",
     "_objFlags": 0,
     "node": {
-      "__id__": 5
+      "__id__": 7
     },
     "_enabled": true,
     "_materials": [
@@ -413,10 +411,10 @@
         "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
       }
     ],
-    "_srcBlendFactor": 770,
+    "_srcBlendFactor": 1,
     "_dstBlendFactor": 771,
     "_spriteFrame": {
-      "__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91"
+      "__uuid__": "b888a314-aa5f-4d35-afd2-5fb4b49b6e36"
     },
     "_type": 0,
     "_sizeMode": 0,
@@ -437,15 +435,15 @@
     "_name": "",
     "_objFlags": 0,
     "node": {
-      "__id__": 5
+      "__id__": 7
     },
     "_enabled": true,
     "alignMode": 1,
     "_target": null,
     "_alignFlags": 33,
     "_left": 0,
-    "_right": 0,
-    "_top": 0,
+    "_right": 10,
+    "_top": 10,
     "_bottom": 0,
     "_verticalCenter": 0,
     "_horizontalCenter": 0,
@@ -464,7 +462,7 @@
     "_name": "",
     "_objFlags": 0,
     "node": {
-      "__id__": 5
+      "__id__": 7
     },
     "_enabled": true,
     "_normalMaterial": null,
@@ -478,8 +476,8 @@
     ],
     "_N$interactable": true,
     "_N$enableAutoGrayEffect": false,
-    "_N$transition": 0,
-    "transition": 0,
+    "_N$transition": 3,
+    "transition": 3,
     "_N$normalColor": {
       "__type__": "cc.Color",
       "r": 255,
@@ -585,7 +583,7 @@
       "__uuid__": "cd07e761-75fb-4f91-be77-c08f86d00457"
     },
     "btnNext": {
-      "__id__": 5
+      "__id__": 7
     },
     "_id": "80oQpM9U1KTIx7FH0iSB/b"
   },

+ 81 - 32
assets/main/SceneMain.ts

@@ -7,6 +7,7 @@ import Loader from "../src/config/Loader";
 import GameStart, { PropsStart } from "../res/luojigouStart/src/LuojigouStart";
 import GameFinish, { PropsFinish } from "../res/luojigouFinish/src/LuojigouFinish";
 import AudioCB from "../src/audioUitls/AudioCB";
+import AudioManager from "../src/audioUitls/AudioManager";
 
 const { ccclass, property } = cc._decorator;
 @ccclass
@@ -45,14 +46,19 @@ export default class Scene extends cc.Component {
         prefabs: cc.Prefab | any,
     } = { bundles: {}, prefabs: {} };
 
+    protected onLoad(): void {
+        // 设置游戏窗口变化的回调(仅 Web 平台有效)
+        cc.view.setResizeCallback(() => this.onResize());
+    }
+
     /** 注册监听事件 */
     protected onEnable(): void {
+        this.adapt();// 第一次显示的屏幕适配
         NotifierCenter.listen(CConst.EVENT_LJG_START, this.showLgjStart, this, false);
         NotifierCenter.listen(CConst.EVENT_LJG_FINISH, this.showLgjFinish, this, false);
         NotifierCenter.listen(CConst.EVENT_ENTER_UNIT, this.msgResultEnterUnit, this, false);
         NotifierCenter.listen(CConst.EVENT_ENTER_GAME, this.msgResultEnterGame, this, false);
         NotifierCenter.listen(CConst.EVENT_SHOW_TIP, this.msgResultShowTip, this, false);
-        NotifierCenter.listen(CConst.EVENT_READY_TO_PLAY, this.msgResultReadyVideo, this, false);
     }
 
     /** 取消监听事件 */
@@ -62,20 +68,10 @@ export default class Scene extends cc.Component {
 
     /** 游戏开始 */
     async start() {
+        common.hideLoading();
+
         this.initUI();
         await this.initData();
-
-        // 用于判断视频是否可以自动播放
-        let node = new cc.Node();
-        node.setContentSize(cc.winSize);
-        node.on(cc.Node.EventType.TOUCH_START, () => {
-            common.isCanPlayVideo = true;
-            node.off(cc.Node.EventType.TOUCH_START);
-            node.removeFromParent();
-        });
-        node['_touchListener'].setSwallowTouches(false); // 不吞噬触摸事件
-        this.node.addChild(node, CConst.ZORDER_TOP);
-
         common.log("场景加载完成,等待进入游戏层");
         if (common.isDebug) {
             this.nodePageMap.active = false;
@@ -85,7 +81,8 @@ export default class Scene extends cc.Component {
 
     /** 初始化游戏数据 */
     async initData() {
-        await AudioCB.instance.init();
+        await AudioCB.getInstance().init();
+        await AudioManager.getInstance().loadAudios();
         // 保存地图配置
         let unitAll = this.jsonConfig.json;
         for (const key in unitAll) {
@@ -131,11 +128,11 @@ export default class Scene extends cc.Component {
 
         this.nodeShow = null;
         this.btnNext.zIndex = CConst.ZORDER_BUTTON_NEXT;
-        this.btnNext.active = false;
     }
 
     /** 添加预制体 分别处理游戏跟视频*/
     async addPrefab(unitNum: number, pageNum: number) {
+        this.resetBtnNext(false);
         common.setPageNum(pageNum);
         let attribute: AttributeUnit = common.attributeMap[unitNum];
         let configOne = attribute.config[pageNum - 1]
@@ -156,36 +153,41 @@ export default class Scene extends cc.Component {
         let prefab = await Loader.loadBundlePrefab(bundle, config.prefabName);
 
         this.removePrefab();// 去掉游戏页
-        this.nodePageMap.active = false;// 隐藏地图页
         this.nodeVideo.active = false;// 隐藏视频页
+        this.nodePageMap.active = false; // 隐藏地图页
 
         this.nodeShow = cc.instantiate(prefab);
-        let script = this.getScriptByNode(this.nodeShow, config.scriptName);
-        if (script && script.initBundle) {
-            script.initBundle(bundle, config);
-        }
         this.node.addChild(this.nodeShow, CConst.ZORDER_GAME);
-        this.btnNext.active = true;
+        this.node.getChildByName('bg').active = true;
+        
+        this.resetBtnNext(true);
     }
 
     /** 加载视频 先不去除游戏节点 */
     async addPrefabVideo(bundle, config) {
+        this.removePrefab();// 去掉游戏页
+        this.nodePageMap.active = false; // 隐藏地图页
+
         // 加载视频页
         let script = this.getScriptByNode(this.nodeVideo, config.scriptName);
         if (script && script.initBundle) {
             script.initBundle(bundle, config);
         }
-        this.nodeVideo.opacity = 0;
         this.nodeVideo.active = true;
+        this.node.getChildByName('bg').active = false;
+        this.resetBtnNext(true);
     }
 
-    /** 视频准备完成,去除游戏节点,显示视频 */
-    msgResultReadyVideo() {
-        this.removePrefab();// 隐藏游戏页
-        this.nodePageMap.active = false;// 隐藏地图页
-
-        this.nodeVideo.opacity = 255;// 显示视频
-        this.btnNext.active = true;// 显示下一步按钮
+    resetBtnNext(show) {
+        if (common.isDebug) {
+            this.btnNext.active = true;
+        }
+        else{
+            this.btnNext.active = false;// 显示下一步按钮
+            if (!show) return;
+            let gameOne = common.getGameFormLocal();
+            this.btnNext.active = Number(gameOne) >= 0;
+        }
     }
 
     /**
@@ -219,8 +221,8 @@ export default class Scene extends cc.Component {
      * 返回到地图页
      */
     enterPageMap() {
+        this.resetBtnNext(false);
         this.removePrefab();// 隐藏游戏相关
-        this.btnNext.active = false;// 隐藏下一步按钮
         this.nodeVideo.active = false; // 隐藏视频页
         this.nodePageMap.active = true; // 显示地图页
     };
@@ -233,8 +235,6 @@ export default class Scene extends cc.Component {
 
     /** 事件回调:进入下一个游戏 */
     msgResultEnterGame() {
-        this.btnNext.active = false;
-
         let curUint = common.getUnitNum();
         let curPage = common.getPageNum();
         let attribute: AttributeUnit = common.attributeMap[curUint];
@@ -266,6 +266,55 @@ export default class Scene extends cc.Component {
         return script;
     };
 
+    /**
+     * 窗口变化回调
+     */
+     protected onResize() {
+        // 适配
+        this.adapt();
+    }
+
+    /**
+    * 适配
+    */
+    protected adapt() {
+        // 实际屏幕比例
+        const winSize = cc.winSize,
+            screenRatio = winSize.width / winSize.height;
+        // 设计比例
+        const designResolution = cc.Canvas.instance.designResolution,
+            designRatio = designResolution.width / designResolution.height;
+
+        // 对比判断 
+        common.log('win ratio: ', screenRatio, '; w: ', winSize.width, '; h: ', winSize.height);
+        common.log('des ratio: ', designRatio, '; w: ', designResolution.width, '; h: ', designResolution.height);
+        if (screenRatio < designRatio) {
+            common.log("适配宽  屏幕宽高比 小于 设计比例");
+            this.setFitWidth();
+        } else {
+            common.log("适配高  屏幕宽高比 大于等于 设计比例");
+            this.setFitHeight();
+        }
+    }
+
+    /**
+     * 适配高度模式
+     */
+    protected setFitHeight() {
+        const canvas = cc.Canvas.instance;
+        canvas.fitHeight = true;
+        canvas.fitWidth = false;
+    }
+
+    /**
+     * 适配宽度模式
+     */
+    protected setFitWidth() {
+        const canvas = cc.Canvas.instance;
+        canvas.fitHeight = false;
+        canvas.fitWidth = true;
+    }
+
     /**
      * 下载游戏zip
      * @param zipName 

BIN
assets/res/common/audio/finish_0.mp3


+ 1 - 1
assets/res/common/audio/finish_0.mp3.meta

@@ -3,6 +3,6 @@
   "uuid": "bf1b3269-140b-4a18-8718-4ba8e3501cfb",
   "importer": "audio-clip",
   "downloadMode": 0,
-  "duration": 6.008163,
+  "duration": 3.1355,
   "subMetas": {}
 }

BIN
assets/res/common/audio/finish_1.mp3


+ 1 - 1
assets/res/common/audio/finish_1.mp3.meta

@@ -3,6 +3,6 @@
   "uuid": "30891dbe-794e-4dda-9bc1-f5011d37622c",
   "importer": "audio-clip",
   "downloadMode": 0,
-  "duration": 6.896327,
+  "duration": 3.630688,
   "subMetas": {}
 }

BIN
assets/res/common/audio/finish_2.mp3


+ 1 - 1
assets/res/common/audio/finish_2.mp3.meta

@@ -3,6 +3,6 @@
   "uuid": "b54710f4-3cab-4e63-87c9-fa8d11cfe088",
   "importer": "audio-clip",
   "downloadMode": 0,
-  "duration": 7.340408,
+  "duration": 3.682813,
   "subMetas": {}
 }

BIN
assets/res/common/img/btnNext.png


+ 38 - 0
assets/res/common/img/btnNext.png.meta

@@ -0,0 +1,38 @@
+{
+  "ver": "2.3.7",
+  "uuid": "eaf46ca9-16c0-40f2-9e0d-191a37606c82",
+  "importer": "texture",
+  "type": "sprite",
+  "wrapMode": "clamp",
+  "filterMode": "bilinear",
+  "premultiplyAlpha": true,
+  "genMipmaps": false,
+  "packable": true,
+  "width": 91,
+  "height": 93,
+  "platformSettings": {},
+  "subMetas": {
+    "btnNext": {
+      "ver": "1.0.6",
+      "uuid": "b888a314-aa5f-4d35-afd2-5fb4b49b6e36",
+      "importer": "sprite-frame",
+      "rawTextureUuid": "eaf46ca9-16c0-40f2-9e0d-191a37606c82",
+      "trimType": "auto",
+      "trimThreshold": 1,
+      "rotated": false,
+      "offsetX": 0,
+      "offsetY": 0,
+      "trimX": 0,
+      "trimY": 0,
+      "width": 91,
+      "height": 93,
+      "rawWidth": 91,
+      "rawHeight": 93,
+      "borderTop": 0,
+      "borderBottom": 0,
+      "borderLeft": 0,
+      "borderRight": 0,
+      "subMetas": {}
+    }
+  }
+}

+ 3 - 2
assets/res/downCount/src/DownCount.ts

@@ -1,3 +1,4 @@
+import AudioManager from "../../../src/audioUitls/AudioManager";
 import Tools from "../../../src/common/Tools";
 
 const { ccclass, property } = cc._decorator;
@@ -54,6 +55,7 @@ export default class DownCount extends cc.Component {
 
     /** 倒计时-启动 */
     downCountLunch(): void {
+        AudioManager.getInstance().playEffect('audio/clock');
         const progressBar = this.nodeProgress.getComponent(cc.ProgressBar);
         this.schedule(() => {
             this.timeCount += this.timeDelay;
@@ -66,6 +68,7 @@ export default class DownCount extends cc.Component {
                     if (icon.active) {
                         icon.active = false;
                         item.getChildByName('gray').active = true;
+                        AudioManager.getInstance().playEffect('audio/star_hide');
                     }
                 }
             });
@@ -81,10 +84,8 @@ export default class DownCount extends cc.Component {
     }
 
     errorAdd(){
-        this.downCountStop();
         this.errorCount++;
         this.timeCount += 20;
-        this.downCountLunch();
     }
 
     /** 获取题卡获得的星星 用在过关后的弹窗 */

+ 1 - 1
assets/src/http.meta → assets/res/http.meta

@@ -1,6 +1,6 @@
 {
   "ver": "1.1.3",
-  "uuid": "84ef85f8-11d9-4b61-8cca-e2b6e8b65417",
+  "uuid": "ce5a5e86-ed24-4b13-aeaf-ab76182672f9",
   "importer": "folder",
   "isBundle": false,
   "bundleName": "",

+ 0 - 0
assets/src/http/HttpState.ts → assets/res/http/HttpStateMap.ts


+ 1 - 1
assets/src/http/HttpState.ts.meta → assets/res/http/HttpStateMap.ts.meta

@@ -1,6 +1,6 @@
 {
   "ver": "1.1.0",
-  "uuid": "b38bd646-94b3-4532-a7be-f29e7703b7a2",
+  "uuid": "74025aa4-04ef-4519-a078-32fa5287e7a6",
   "importer": "typescript",
   "isPlugin": false,
   "loadPluginInWeb": true,

+ 7 - 5
assets/res/luojigouFinish/src/LuojigouFinish.ts

@@ -1,6 +1,8 @@
 import Tools from "../../../src/common/Tools";
 import CConst from "../../../src/common/CConst";
 import NotifierCenter from "../../../src/webtcp/NotifierCenter";
+import common from "../../../src/common/common";
+import AudioManager from "../../../src/audioUitls/AudioManager";
 
 const EStarSkineMap = new Map([
     [1, '1-Star'],
@@ -25,21 +27,19 @@ export default class LuojigouFinish extends cc.Component {
     @property({ tooltip: '弹窗中的spine', type: sp.Skeleton })
     SuccessSpine: sp.Skeleton = null;
 
-    protected onDisable(): void {
-        this.unscheduleAllCallbacks();
-        Tools.stopEffects();
-    }
-
     /**
      * @description 设置成功弹窗的动画
      * @description 星星数
      */
     setAnimation(props: PropsFinish): void {
+        common.setGameToLocal();
         this.node.active = true;
         const spine = this.SuccessSpine;
         spine.setSkin(EStarSkineMap.get(props.star));
+        spine.timeScale = 0.8;
         spine.setAnimation(0, ESuccessAni.success1, false);
         spine.addAnimation(0, ESuccessAni.success2, true);
+        AudioManager.getInstance().playEffect('audio/star_' + props.star);
 
         if (props.audios && props.audios.length > 0) {
             Tools.playEffectArr(props.audios, this.closeLJGCard.bind(this));
@@ -53,7 +53,9 @@ export default class LuojigouFinish extends cc.Component {
        * @description 关闭逻辑狗弹窗
        */
     closeLJGCard() {
+        Tools.stopEffects();
         this.node.active = false;
+        this.unscheduleAllCallbacks();
         NotifierCenter.trigger(CConst.EVENT_ENTER_GAME);
     }
 }

+ 1 - 1
assets/res/luojigouStart/res/prefab/luojigouStart.prefab

@@ -1528,7 +1528,7 @@
     },
     "component": "",
     "_componentId": "dceb764dL1JiYCW/zhyLoDq",
-    "handler": "closeLJGCard",
+    "handler": "eventClose",
     "customEventData": ""
   },
   {

+ 15 - 14
assets/res/luojigouStart/src/LuojigouStart.ts

@@ -1,6 +1,7 @@
 import Tools from "../../../src/common/Tools";
 import CConst from "../../../src/common/CConst";
 import NotifierCenter from "../../../src/webtcp/NotifierCenter";
+import AudioManager from "../../../src/audioUitls/AudioManager";
 
 /**
  * @description 逻辑狗card的脚本
@@ -35,11 +36,6 @@ export default class LuojigouStart extends cc.Component {
     @property({ tooltip: '星星list', type: cc.Node })
     StarList: cc.Node[] = []
 
-    protected onDisable(): void {
-        this.unscheduleAllCallbacks();
-        Tools.stopEffects();
-    }
-
     /**
      * @description 设置逻辑狗卡片
      */
@@ -51,21 +47,26 @@ export default class LuojigouStart extends cc.Component {
         this.ChallengeType.getComponent(cc.Label).string = props.type;
         this.ChallengeTitle.getComponent(cc.Label).string = props.title;
 
-        if (props.audios && props.audios.length > 0) {
-            Tools.playEffectArr(props.audios, this.closeLJGCard.bind(this));
-        }
-        else {
-            this.scheduleOnce(this.closeLJGCard.bind(this), 4);
-        }
+        // if (props.audios && props.audios.length > 0) {
+        //     Tools.playEffectArr(props.audios, this.closeLJGCard.bind(this));
+        // }
+        // else {
+        this.scheduleOnce(this.closeLJGCard.bind(this), 4);
+        // }
+    }
+
+    eventClose() {
+        this.closeLJGCard();
+        AudioManager.getInstance().playEffect('audio/button_touch');
     }
 
     /**
      * @description 关闭逻辑狗弹窗
      */
     closeLJGCard() {
+        // Tools.stopEffects();
         this.node.active = false;
+        this.unscheduleAllCallbacks();
         NotifierCenter.trigger(CConst.EVENT_GAME_START);
     }
-}
-
-
+}

+ 10 - 8
assets/res/tipHand/src/TipHand.ts

@@ -1,3 +1,4 @@
+import AudioManager from "../../../src/audioUitls/AudioManager";
 import Tools from "../../../src/common/Tools";
 
 /** 提示参数 */
@@ -115,6 +116,7 @@ export default class TipHand extends cc.Component {
 
     /* 按下 */
     private Press(callback: Function) {
+        AudioManager.getInstance().playEffect('audio/handTip');
         this.skAperture.node.active = false;
         Tools.playAnimation(this.skHand, this.event_danji, false, () => {
             this.skAperture.node.active = true;
@@ -136,6 +138,7 @@ export default class TipHand extends cc.Component {
         this.nodeTip.active = true;
         this.nodeTip.position = pStart;
         this.skAperture.node.active = true;
+        AudioManager.getInstance().playEffect('audio/handTip');
         Tools.playAnimation(this.skAperture, this.ani_dianji, false);
         Tools.playAnimation(this.skHand, this.event_danji, false, () => {
             Tools.playAnimation(this.skHand, this.event_taishou, false, () => {
@@ -155,8 +158,8 @@ export default class TipHand extends cc.Component {
     touchCycleByTimes(pStart: cc.Vec3, times: number, callBack: Function = null) {
         let funcStart = (index, point) => {
             if (index < times) {
+                index++;
                 this.touch(point, () => {
-                    index++;
                     funcStart(index, point);
                 });
             }
@@ -178,9 +181,9 @@ export default class TipHand extends cc.Component {
         this.nodeTip.position = pStart;
         this.nodeTip.opacity = 0;
         this.skHand.clearTracks();
-        cc.tween(this.nodeTip).to(0.3, { opacity: 255 }).call(() => {
-            funcStart(0, pStart);
-        }).start();
+        this.skAperture.clearTracks();
+        cc.tween(this.nodeTip).to(0.3, { opacity: 255 }).start();
+        funcStart(0, pStart);
     }
 
     /* 可以调节点击速度的 点击循环 */
@@ -215,7 +218,6 @@ export default class TipHand extends cc.Component {
     /** 左右滑动 */
     dragABAB(starPos: cc.Vec3, size: cc.Size, time: number = 0.4, callBack: Function = null) {
         let funcStart = () => {
-            this.nodeTip.stopAllActions();
             this.Press(() => {
                 cc.tween(this.nodeTip)
                     .to(time, { position: cc.v3(starPos.x - size.width, starPos.y - size.height) })
@@ -241,9 +243,8 @@ export default class TipHand extends cc.Component {
         this.nodeTip.position = starPos;
         this.nodeTip.opacity = 0;
         this.skHand.clearTracks();
-        cc.tween(this.nodeTip).to(0.3, { opacity: 255 }).call(() => {
-            funcStart();
-        }).start();
+        cc.tween(this.nodeTip).to(0.3, { opacity: 255 }).start();
+        funcStart();
     };
 
     /** 循环滑动 */
@@ -406,6 +407,7 @@ export default class TipHand extends cc.Component {
         this.nodeTip.setPosition(starPos);
         this.arrow.active = false;
         let len = cc.v2(endPos.x, endPos.y).sub(cc.v2(starPos.x, starPos.y)).mag();
+        AudioManager.getInstance().playEffect('audio/handTip');
         Tools.playAnimation(this.skHand, this.event_danji, false, () => {
             this.skAperture.node.active = true;
             Tools.playAnimation(this.skAperture, this.ani_dianji, true);

+ 0 - 12
assets/res/tipHand/描述文本.md

@@ -1,12 +0,0 @@
-# 引导手文档描述
-
-## 使用规则
-## 点击
- Click()
-
-## 循环点击
-ClickCycle()
-
-## 循环拖拽
-TouchCycle()
-## 

+ 0 - 6
assets/res/tipHand/描述文本.md.meta

@@ -1,6 +0,0 @@
-{
-  "ver": "2.0.2",
-  "uuid": "46c0a9e3-8bd9-40e7-9654-d1a0019dba60",
-  "importer": "markdown",
-  "subMetas": {}
-}

+ 13 - 0
assets/res/videoPlayer/res/img.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "7b923456-99f6-4639-aaa9-5a2b4f6af4d6",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

BIN
assets/res/videoPlayer/res/img/bg.jpg


+ 38 - 0
assets/res/videoPlayer/res/img/bg.jpg.meta

@@ -0,0 +1,38 @@
+{
+  "ver": "2.3.7",
+  "uuid": "d417db94-2b79-4bda-97d5-c82be119f5b5",
+  "importer": "texture",
+  "type": "sprite",
+  "wrapMode": "clamp",
+  "filterMode": "bilinear",
+  "premultiplyAlpha": false,
+  "genMipmaps": false,
+  "packable": true,
+  "width": 2480,
+  "height": 1440,
+  "platformSettings": {},
+  "subMetas": {
+    "bg": {
+      "ver": "1.0.6",
+      "uuid": "7d07c1e2-73b5-410d-998f-dbe6f1cc8026",
+      "importer": "sprite-frame",
+      "rawTextureUuid": "d417db94-2b79-4bda-97d5-c82be119f5b5",
+      "trimType": "auto",
+      "trimThreshold": 1,
+      "rotated": false,
+      "offsetX": 0,
+      "offsetY": 0,
+      "trimX": 0,
+      "trimY": 0,
+      "width": 2480,
+      "height": 1440,
+      "rawWidth": 2480,
+      "rawHeight": 1440,
+      "borderTop": 0,
+      "borderBottom": 0,
+      "borderLeft": 0,
+      "borderRight": 0,
+      "subMetas": {}
+    }
+  }
+}

BIN
assets/res/videoPlayer/res/img/btn_replay.png


+ 38 - 0
assets/res/videoPlayer/res/img/btn_replay.png.meta

@@ -0,0 +1,38 @@
+{
+  "ver": "2.3.7",
+  "uuid": "f5816476-5ed3-429e-a34c-3c210af60955",
+  "importer": "texture",
+  "type": "sprite",
+  "wrapMode": "clamp",
+  "filterMode": "bilinear",
+  "premultiplyAlpha": true,
+  "genMipmaps": false,
+  "packable": true,
+  "width": 136,
+  "height": 136,
+  "platformSettings": {},
+  "subMetas": {
+    "btn_replay": {
+      "ver": "1.0.6",
+      "uuid": "5f2c5577-d78d-41c2-8c97-d684d9a40ff4",
+      "importer": "sprite-frame",
+      "rawTextureUuid": "f5816476-5ed3-429e-a34c-3c210af60955",
+      "trimType": "auto",
+      "trimThreshold": 1,
+      "rotated": false,
+      "offsetX": 0,
+      "offsetY": 0,
+      "trimX": 0,
+      "trimY": 0,
+      "width": 136,
+      "height": 136,
+      "rawWidth": 136,
+      "rawHeight": 136,
+      "borderTop": 0,
+      "borderBottom": 0,
+      "borderLeft": 0,
+      "borderRight": 0,
+      "subMetas": {}
+    }
+  }
+}

+ 450 - 3
assets/res/videoPlayer/res/prefab/videoPlayer.prefab

@@ -19,19 +19,22 @@
     "_children": [
       {
         "__id__": 2
+      },
+      {
+        "__id__": 6
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 6
+        "__id__": 18
       },
       {
-        "__id__": 7
+        "__id__": 19
       }
     ],
     "_prefab": {
-      "__id__": 8
+      "__id__": 20
     },
     "_opacity": 255,
     "_color": {
@@ -189,6 +192,444 @@
     "fileId": "aekCeLntBN77jEUVJFSXym",
     "sync": false
   },
+  {
+    "__type__": "cc.Node",
+    "_name": "nodeStart",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 10
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 16
+      }
+    ],
+    "_prefab": {
+      "__id__": 17
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1920,
+      "height": 1080
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "bg",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 6
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 8
+      }
+    ],
+    "_prefab": {
+      "__id__": 9
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 2480,
+      "height": 1440
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 7
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "7d07c1e2-73b5-410d-998f-dbe6f1cc8026"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "6937c4f4-77ad-4091-aac0-c5e69333a25d"
+    },
+    "fileId": "82Od8Zx/FBAa5ZprHbs/lB",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "button",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 6
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 11
+      },
+      {
+        "__id__": 12
+      },
+      {
+        "__id__": 13
+      }
+    ],
+    "_prefab": {
+      "__id__": 15
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 250,
+      "height": 250
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 1,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "5f2c5577-d78d-41c2-8c97-d684d9a40ff4"
+    },
+    "_type": 0,
+    "_sizeMode": 0,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 18,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": 0,
+    "_horizontalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Button",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "_normalMaterial": null,
+    "_grayMaterial": null,
+    "duration": 0.1,
+    "zoomScale": 1.2,
+    "clickEvents": [
+      {
+        "__id__": 14
+      }
+    ],
+    "_N$interactable": true,
+    "_N$enableAutoGrayEffect": false,
+    "_N$transition": 0,
+    "transition": 0,
+    "_N$normalColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_N$pressedColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "pressedColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "_N$hoverColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "hoverColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_N$disabledColor": {
+      "__type__": "cc.Color",
+      "r": 124,
+      "g": 124,
+      "b": 124,
+      "a": 255
+    },
+    "_N$normalSprite": null,
+    "_N$pressedSprite": null,
+    "pressedSprite": null,
+    "_N$hoverSprite": null,
+    "hoverSprite": null,
+    "_N$disabledSprite": null,
+    "_N$target": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.ClickEvent",
+    "target": {
+      "__id__": 1
+    },
+    "component": "",
+    "_componentId": "26869snX2RDWIrulrewQySM",
+    "handler": "eventTouch",
+    "customEventData": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "6937c4f4-77ad-4091-aac0-c5e69333a25d"
+    },
+    "fileId": "38NAYRKc9OBa39f6W1HN/x",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 45,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": 0,
+    "_horizontalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 2480,
+    "_originalHeight": 1440,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "6937c4f4-77ad-4091-aac0-c5e69333a25d"
+    },
+    "fileId": "5bdzdfMDZJFINjcdytcP9T",
+    "sync": false
+  },
   {
     "__type__": "26869snX2RDWIrulrewQySM",
     "_name": "",
@@ -197,6 +638,12 @@
       "__id__": 1
     },
     "_enabled": true,
+    "jsonConfig": null,
+    "nodeCount": null,
+    "prefabCount": null,
+    "nodeStart": {
+      "__id__": 6
+    },
     "video": {
       "__id__": 3
     },

+ 62 - 25
assets/res/videoPlayer/src/VideoPlayer.ts

@@ -16,24 +16,31 @@ const { ccclass, property } = cc._decorator;
 @ccclass
 export default class VideoPlayer extends GameBase {
 
+    @property({ tooltip: '播放按钮', type: cc.Node })
+    nodeStart: cc.Node = null;
+
     @property({ tooltip: '视频资源', type: cc.VideoPlayer })
     video: cc.VideoPlayer = null;
 
-    /** 是否可以播放 */
-    isReadyToPlay = false;
-
-    protected onLoad(): void {
-        this.node.on(cc.Node.EventType.TOUCH_END, this.eventTouch, this, false);
-    }
-
+    currentTime = 0;
     protected onEnable(): void {
-        this.isReadyToPlay = false;
+        this.currentTime = 0;
+        this.nodeStart.active = true;
         this.loadVideo();
     }
 
     protected onDisable(): void {
-        this.isReadyToPlay = false;
-        this.video.stop();
+        this.stopVideo();
+    }
+
+    protected update(dt: number): void {
+        if (!this.nodeStart.active) {
+            return;
+        }
+        if (this.currentTime > 0 && this.video.isPlaying()) {
+            this.nodeStart.active = false;
+            common.log('视频 播放');
+        }
     }
 
     async loadVideo(){
@@ -46,28 +53,58 @@ export default class VideoPlayer extends GameBase {
     };
 
     /** 事件-点击屏幕 */
-    eventTouch(){
-        if (!this.isReadyToPlay) return;
-
-        if (this.video.isPlaying()) {
-            this.video.pause();
-        }
-        else{
-            this.video.play();
-        }
+    eventTouch() {
+        this.playVideo();
     }
 
     /** 事件-视频相关 */
     eventVideo(videoplayer: cc.VideoPlayer, event: cc.VideoPlayer.EventType, customEventData): void {
-        if(event === cc.VideoPlayer.EventType.READY_TO_PLAY){
-            this.isReadyToPlay = true;
-            if (common.isCanPlayVideo) {
-                this.video.play();
-            }
-            NotifierCenter.trigger(CConst.EVENT_READY_TO_PLAY, {});
+        common.log('视频 event: ', this.getStatus(event), ', isPlaying: ', this.video.isPlaying());
+        if (event === cc.VideoPlayer.EventType.READY_TO_PLAY) {
+            this.currentTime = 0.01;
+            this.playVideo();
+        }
+        else if (event === cc.VideoPlayer.EventType.META_LOADED) {
+            this.currentTime = this.video.currentTime + 0.01;
+            this.playVideo();
         }
         else if (event === cc.VideoPlayer.EventType.COMPLETED) {
+            common.setGameToLocal();
             NotifierCenter.trigger(CConst.EVENT_ENTER_GAME, {});
         }
+        else if (event === cc.VideoPlayer.EventType.CLICKED) {
+            this.playVideo();
+        }
+    }
+
+    playVideo() {
+        if (!this.video.isPlaying()) {
+            this.video.play();
+        }
     }
+
+    stopVideo() {
+        this.video.stop();
+    }
+
+    getStatus(event) {
+        switch (event) {
+            case cc.VideoPlayer.EventType.PLAYING:
+                return 'PLAYING';
+            case cc.VideoPlayer.EventType.PAUSED:
+                return 'PAUSED';
+            case cc.VideoPlayer.EventType.STOPPED:
+                return 'STOPPED';
+            case cc.VideoPlayer.EventType.COMPLETED:
+                return 'COMPLETED';
+            case cc.VideoPlayer.EventType.META_LOADED:
+                return 'META_LOADED';
+            case cc.VideoPlayer.EventType.CLICKED:
+                return 'CLICKED';
+            case cc.VideoPlayer.EventType.READY_TO_PLAY:
+                return 'READY_TO_PLAY';
+            default:
+                return 'NONE';
+        }
+    };
 }

+ 13 - 0
assets/resources.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "b5f676b7-bd02-494a-b1ea-8240dadfbf49",
+  "importer": "folder",
+  "isBundle": true,
+  "bundleName": "resources",
+  "priority": 8,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 13 - 0
assets/resources/audio.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "58c7106f-9b81-4257-b2cb-11762ba075cf",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

BIN
assets/resources/audio/button_touch.mp3


+ 8 - 0
assets/resources/audio/button_touch.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "9a475e9b-d39f-445d-aa6d-9e699e96974e",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.862041,
+  "subMetas": {}
+}

BIN
assets/resources/audio/clock.mp3


+ 8 - 0
assets/resources/audio/clock.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "9f61a1c0-3549-451d-bda6-750ca800c78f",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.128688,
+  "subMetas": {}
+}

BIN
assets/resources/audio/error_good_0.mp3


+ 8 - 0
assets/resources/audio/error_good_0.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "a5a535df-3fad-4d28-890f-0345d609b9fe",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.835918,
+  "subMetas": {}
+}

BIN
assets/resources/audio/error_good_1.mp3


+ 8 - 0
assets/resources/audio/error_good_1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "5d2eaf62-d455-4f37-a902-c70af8438795",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.629333,
+  "subMetas": {}
+}

BIN
assets/resources/audio/error_touch.mp3


+ 8 - 0
assets/resources/audio/error_touch.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "5ba04178-1681-43ee-993f-1aa71c951e98",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.317333,
+  "subMetas": {}
+}

BIN
assets/resources/audio/good_move.mp3


+ 8 - 0
assets/resources/audio/good_move.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "7cd7f98f-6bf0-4b17-8408-f86b3ee96fe2",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.940408,
+  "subMetas": {}
+}

BIN
assets/resources/audio/good_touch.mp3


+ 8 - 0
assets/resources/audio/good_touch.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "aa9b3ead-f687-46a3-b6f5-0e80614377cf",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.1045,
+  "subMetas": {}
+}

BIN
assets/resources/audio/handTip.mp3


+ 8 - 0
assets/resources/audio/handTip.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "1bc76fdc-a0ed-4f6a-a91d-b98ea71d9745",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.880816,
+  "subMetas": {}
+}

BIN
assets/resources/audio/particle_0.mp3


+ 8 - 0
assets/resources/audio/particle_0.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "ef3934cf-5190-45df-a34b-c098498b7942",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.071,
+  "subMetas": {}
+}

BIN
assets/resources/audio/particle_1.mp3


+ 8 - 0
assets/resources/audio/particle_1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "25624eca-be7f-46a6-9ce3-b5e9585fe70d",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.724,
+  "subMetas": {}
+}

BIN
assets/resources/audio/right_0.mp3


+ 8 - 0
assets/resources/audio/right_0.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "2a050f79-251e-40c5-aef6-314d9e1aefab",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.259,
+  "subMetas": {}
+}

BIN
assets/resources/audio/right_1.mp3


+ 8 - 0
assets/resources/audio/right_1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "f1b79829-d44e-4569-b678-f1e6a340fbe6",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 1.415375,
+  "subMetas": {}
+}

BIN
assets/resources/audio/right_2.mp3


+ 8 - 0
assets/resources/audio/right_2.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "5b319b7d-2c04-4244-b002-25db7dd57cf7",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.711688,
+  "subMetas": {}
+}

BIN
assets/resources/audio/right_3.mp3


+ 8 - 0
assets/resources/audio/right_3.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "7ae2e899-b918-4daf-b157-2d22b6677b6b",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 2.3249,
+  "subMetas": {}
+}

BIN
assets/resources/audio/star_1.mp3


+ 8 - 0
assets/resources/audio/star_1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "f6417321-5dcd-4b00-b4e7-79a8a1045fe4",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 4.959875,
+  "subMetas": {}
+}

BIN
assets/resources/audio/star_2.mp3


+ 8 - 0
assets/resources/audio/star_2.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "d6b4ecc4-c424-41cd-9c92-dbdd451ecc8c",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 4.959875,
+  "subMetas": {}
+}

BIN
assets/resources/audio/star_3.mp3


+ 8 - 0
assets/resources/audio/star_3.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "b02a2dfd-2acf-48cf-ad98-16e20269fc68",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 4.959875,
+  "subMetas": {}
+}

BIN
assets/resources/audio/star_hide.mp3


+ 8 - 0
assets/resources/audio/star_hide.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "e347f541-8380-4150-af0e-6d9c02c2aed7",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.677333,
+  "subMetas": {}
+}

+ 20 - 0
assets/resources/configAudio.json

@@ -0,0 +1,20 @@
+[
+    "audio/button_touch",
+    "audio/clock",
+    "audio/error_good_0",
+    "audio/error_good_1",
+    "audio/error_touch",
+    "audio/good_move",
+    "audio/good_touch",
+    "audio/handTip",
+    "audio/particle_0",
+    "audio/particle_1",
+    "audio/right_0",
+    "audio/right_1",
+    "audio/right_2",
+    "audio/right_3",
+    "audio/star_1",
+    "audio/star_2",
+    "audio/star_3",
+    "audio/star_hide"
+]

+ 6 - 0
assets/resources/configAudio.json.meta

@@ -0,0 +1,6 @@
+{
+  "ver": "1.0.2",
+  "uuid": "5a8eb15b-62b0-4c2f-94ca-e31074ffecb0",
+  "importer": "json",
+  "subMetas": {}
+}

+ 13 - 0
assets/resources/prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "95d20073-5de4-4072-9aea-4517b661e736",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 1155 - 0
assets/resources/prefab/popUp.prefab

@@ -0,0 +1,1155 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "",
+    "_objFlags": 0,
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "asyncLoadAssets": false,
+    "readonly": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "pageMap",
+    "_objFlags": 0,
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 5
+      },
+      {
+        "__id__": 27
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 30
+      },
+      {
+        "__id__": 31
+      }
+    ],
+    "_prefab": {
+      "__id__": 32
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 1920,
+      "height": 1080
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        960,
+        540,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "bg",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 3
+      }
+    ],
+    "_prefab": {
+      "__id__": 4
+    },
+    "_opacity": 60,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 2480,
+      "height": 1440
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91"
+    },
+    "_type": 0,
+    "_sizeMode": 0,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "35TA/wyBZC54/EB+ZsvMRZ",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "main",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 6
+      },
+      {
+        "__id__": 10
+      },
+      {
+        "__id__": 14
+      },
+      {
+        "__id__": 18
+      }
+    ],
+    "_active": true,
+    "_components": [],
+    "_prefab": {
+      "__id__": 26
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 0,
+      "height": 0
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "hanzimianban2",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 5
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 8
+      }
+    ],
+    "_prefab": {
+      "__id__": 9
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 596,
+      "height": 280
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        -8.17,
+        -25.292,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "2c2313dc-0d6c-4411-8298-d62f8c016f72"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 18,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": -25.292,
+    "_horizontalCenter": -8.17,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "ba0sVJm3JIhrHo+6Zr6Pva",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "hanzimianban1",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 5
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 11
+      },
+      {
+        "__id__": 12
+      }
+    ],
+    "_prefab": {
+      "__id__": 13
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 546,
+      "height": 228
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        8.178,
+        -9.723,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "11dbb996-fad4-4fad-881d-f66f1016d5de"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 18,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": -9.723,
+    "_horizontalCenter": 8.178,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "e5gO84BhlFJZFomZhvxtsr",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "luojigou-kuang",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 5
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 15
+      },
+      {
+        "__id__": 16
+      }
+    ],
+    "_prefab": {
+      "__id__": 17
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 227,
+      "height": 81
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        30.254,
+        122.986,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 14
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "5c5c4d3b-2c4e-4ad2-abd1-b94e122a4951"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 14
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 0,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": 0,
+    "_horizontalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "8dOLvm9ORDJbhyI+nizDbM",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "nodeLabel",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 5
+    },
+    "_children": [
+      {
+        "__id__": 19
+      },
+      {
+        "__id__": 22
+      }
+    ],
+    "_active": true,
+    "_components": [],
+    "_prefab": {
+      "__id__": 25
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 416,
+      "height": 29
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        1,
+        0.992,
+        0.992,
+        0.992
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "title",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 18
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 20
+      }
+    ],
+    "_prefab": {
+      "__id__": 21
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 142,
+      "g": 138,
+      "b": 117,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 300,
+      "height": 36.54
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        40,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 19
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_string": "弹窗",
+    "_N$string": "弹窗",
+    "_fontSize": 29,
+    "_lineHeight": 29,
+    "_enableWrapText": true,
+    "_N$file": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_batchAsBitmap": false,
+    "_styleFlags": 0,
+    "_underlineHeight": 0,
+    "_N$horizontalAlign": 1,
+    "_N$verticalAlign": 1,
+    "_N$fontFamily": "Arial",
+    "_N$overflow": 3,
+    "_N$cacheMode": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "2ceozZHAFNLoE2IUB1Y6pU",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "content",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 18
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 23
+      }
+    ],
+    "_prefab": {
+      "__id__": 24
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 90,
+      "g": 189,
+      "b": 203,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 159.5,
+      "height": 36.54
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        0,
+        -10,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 22
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_string": "xxxxxxxxxxx",
+    "_N$string": "xxxxxxxxxxx",
+    "_fontSize": 29,
+    "_lineHeight": 29,
+    "_enableWrapText": true,
+    "_N$file": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_batchAsBitmap": false,
+    "_styleFlags": 0,
+    "_underlineHeight": 0,
+    "_N$horizontalAlign": 1,
+    "_N$verticalAlign": 1,
+    "_N$fontFamily": "Arial",
+    "_N$overflow": 0,
+    "_N$cacheMode": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "2fccHyuYxNXps/kfDSGmak",
+    "sync": false
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "8dTEneaylPxa/LWOjWBlQd",
+    "sync": false
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "68dJuv9bBF/p2isQ0gunQe",
+    "sync": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "nodeBtn",
+    "_objFlags": 0,
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 28
+      }
+    ],
+    "_prefab": {
+      "__id__": 29
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 68,
+      "height": 72
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_trs": {
+      "__type__": "TypedArray",
+      "ctor": "Float64Array",
+      "array": [
+        296.639,
+        110.059,
+        0,
+        0,
+        0,
+        0,
+        1,
+        1,
+        1,
+        1
+      ]
+    },
+    "_eulerAngles": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_skewX": 0,
+    "_skewY": 0,
+    "_is3DNode": false,
+    "_groupIndex": 0,
+    "groupIndex": 0,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 27
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "86b29e40-f75b-481b-8130-1d5eefd22a9a"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "d66pkMDZxDc4iMh/vYxu3M",
+    "sync": false
+  },
+  {
+    "__type__": "99062b6TtVBeZUutnKcfziL",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "background": {
+      "__id__": 2
+    },
+    "main": {
+      "__id__": 5
+    },
+    "titleLabel": {
+      "__id__": 20
+    },
+    "contentLabel": {
+      "__id__": 23
+    },
+    "confirmBtn": {
+      "__id__": 27
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "alignMode": 1,
+    "_target": null,
+    "_alignFlags": 45,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_verticalCenter": 0,
+    "_horizontalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 1920,
+    "_originalHeight": 1080,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "7c9c015e-a06d-4ed5-89f7-a26af8df9253"
+    },
+    "fileId": "",
+    "sync": false
+  }
+]

+ 9 - 0
assets/resources/prefab/popUp.prefab.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.3.2",
+  "uuid": "7c9c015e-a06d-4ed5-89f7-a26af8df9253",
+  "importer": "prefab",
+  "optimizationPolicy": "AUTO",
+  "asyncLoadAssets": false,
+  "readonly": false,
+  "subMetas": {}
+}

+ 15 - 21
assets/src/audioUitls/AudioCB.ts

@@ -19,7 +19,7 @@ export default class AudioCB {
     private _handlers: any = {};
     private _currTimer: number = 0;
 
-    public static get instance(): AudioCB {
+    public static getInstance(): AudioCB {
         if (AudioCB._instance == null) {
             AudioCB._instance = new AudioCB();
         }
@@ -38,33 +38,27 @@ export default class AudioCB {
     public onEnterFrame(): void {
         if (this._pool.length > 0) {
             let first: AudioHandler = this._pool.shift();
-            this.removeQueue();
             if (first.order == AudioOrder.Add) {
-                common.log('音频回调-添加: ', first.name);
                 this._handlers[first.name] = first;
+                common.log('音频回调-添加 队列:', Object.keys(this._handlers));
+            }
+            else if(first.order == AudioOrder.Del){
+                this.removeQueue();
+                common.log('音频回调-清除 队列:', Object.keys(this._handlers));
             }
         }
 
         this._currTimer = Date.now();
-        if (this._currTimer >= this._handlers.exeTime) {
-            let method: Function = this._handlers.method;
-            let args: any[] = this._handlers.args;
-            method.apply(this._handlers.thisObj, args);
-            this._handlers.clear();
-            this._handlers = null;
-        }
-
         for (const key in this._handlers) {
-            if (Object.prototype.hasOwnProperty.call(this._handlers, key)) {
-                const handler: AudioHandler = this._handlers[key];
-                if (this._currTimer >= handler.exeTime) {
-                    let method: Function = handler.method;
-                    let args: any[] = handler.args;
-                    method.apply(handler.thisObj, args);
-                    common.log('音频回调-执行: ', handler.name);
-                    handler.clear();
-                    delete this._handlers[key];
-                }
+            if (key === "undefined") continue;
+            const handler: AudioHandler = this._handlers[key];
+            if (this._currTimer >= handler.exeTime) {
+                let method: Function = handler.method;
+                let args: any[] = handler.args;
+                method.apply(handler.thisObj, args);
+                common.log('音频回调-执行: ', handler.name);
+                handler.clear();
+                delete this._handlers[key];
             }
         }
     }

+ 43 - 0
assets/src/audioUitls/AudioManager.ts

@@ -0,0 +1,43 @@
+import Loader from "../config/Loader";
+
+export default class AudioManager {
+    private static _instance: AudioManager;
+    public static getInstance(): AudioManager {
+        if (!this._instance) {
+            this._instance = new AudioManager();
+        }
+        return this._instance;
+    };
+
+    /** 音效缓存池 */
+    private static _soundPool: Map<string, cc.AudioClip> = new Map<string, cc.AudioClip>();
+
+    /** 根据配置文件加载音频 */ 
+    async loadAudios(){
+        let config: cc.JsonAsset = await Loader.loadResLoacl('configAudio');
+        if (!config) {
+            return;
+        }
+        let data: string[] = config.json;
+        for (let index = 0; index < data.length; index++) {
+            let path = data[index];
+            let audio: cc.AudioClip = await Loader.loadResLoacl(path);
+            AudioManager._soundPool.set(path, audio);
+        }
+    };
+
+    /** 播放音频 */
+    async playEffect(path: string, loop?: boolean){
+        let audio = AudioManager._soundPool.get(path);
+        if (!audio) {
+            audio = await Loader.loadResLoacl(path);
+            AudioManager._soundPool.set(path, audio);
+        }
+        cc.audioEngine.playEffect(audio, loop ? true : false);
+    };
+
+    /** 停止音频 */
+    stopEffect(){
+        cc.audioEngine.stopAllEffects();
+    };
+};

+ 1 - 1
assets/src/http/IHttpSystem.ts.meta → assets/src/audioUitls/AudioManager.ts.meta

@@ -1,6 +1,6 @@
 {
   "ver": "1.1.0",
-  "uuid": "daece82d-2845-4292-b484-b82999c3ce88",
+  "uuid": "e3afea5a-e35b-46e0-b636-f53436abac69",
   "importer": "typescript",
   "isPlugin": false,
   "loadPluginInWeb": true,

+ 0 - 1
assets/src/common/CConst.ts

@@ -25,7 +25,6 @@ class CConst{
     EVENT_GAME_START = "event_game_start"; // 开始游戏
     EVENT_ENTER_UNIT = "event_enter_unit"; // 切换游戏单元
     EVENT_ENTER_GAME = "event_enter_game"; // 下一个游戏
-    EVENT_READY_TO_PLAY = "event_ready_to_play"; // 准备完成
     EVENT_SHOW_TIP = "event_show_tip"; // 提示
     EVENT_COLLISION_ENTER = "collision_enter"; // 碰撞
     EVENT_COLLISION_EXIT = "collision_exit"; // 碰撞

+ 32 - 5
assets/src/common/GameBase.ts

@@ -1,4 +1,5 @@
 import DownCount from "../../res/downCount/src/DownCount";
+import AudioManager from "../audioUitls/AudioManager";
 
 const { ccclass, property } = cc._decorator;
 @ccclass
@@ -23,7 +24,7 @@ export default class GameBase extends cc.Component {
             let script = downCount.getComponent(DownCount);
             script.downCountInit();
         }
-    }
+    };
 
     /** 倒计时-启动 */
     countLunch(): void {
@@ -32,7 +33,7 @@ export default class GameBase extends cc.Component {
             let script = downCount.getComponent(DownCount);
             script.downCountLunch();
         }
-    }
+    };
 
     /** 倒计时-停止 */
     countStop(): void {
@@ -41,7 +42,7 @@ export default class GameBase extends cc.Component {
             let script = downCount.getComponent(DownCount);
             script.downCountStop();
         }
-    }
+    };
 
     /** 倒计时-错误 */
     countError(): void {
@@ -50,7 +51,7 @@ export default class GameBase extends cc.Component {
             let script = downCount.getComponent(DownCount);
             script.errorAdd();
         }
-    }
+    };
 
     /** 倒计时-错误 */
     getCountStar(): number {
@@ -61,5 +62,31 @@ export default class GameBase extends cc.Component {
             starNum = script.getStarCount();
         }
         return starNum;
-    }
+    };
+
+    playAudioGoodTouch(){
+        AudioManager.getInstance().playEffect('audio/good_touch');
+    };
+
+    playAudioGoodMove(){
+        AudioManager.getInstance().playEffect('audio/good_move');
+    };
+
+    playAudioRight(){
+        let random = Math.floor(Math.random()*2) + 2; 
+        AudioManager.getInstance().playEffect('audio/right_' + 3);
+    };
+
+    playAudioErrorYao(){
+        AudioManager.getInstance().playEffect('audio/error_good_0');
+    };
+
+    playAudioErrorReset(){
+        AudioManager.getInstance().playEffect('audio/error_good_1');
+    };
+
+    playAudioParticle(){
+        let random = Math.floor(Math.random()*2)
+        AudioManager.getInstance().playEffect('audio/particle_' + 1);
+    };
 }

+ 26 - 10
assets/src/common/Tools.ts

@@ -1,4 +1,5 @@
 import AudioCB, { AudioOrder } from "../audioUitls/AudioCB";
+import common, { UitlData } from "./common";
 
 class Tools {
     private static _instance: Tools;
@@ -12,15 +13,15 @@ class Tools {
 
     /**
      * 动作帧混合
-     * @param spineSkeleton 
+     * @param skeleton 
      * @param animationList 
      */
-    spineSetMix(spineSkeleton: sp.Skeleton, animationList: string[]) {
+    spineSetMix(skeleton: sp.Skeleton, animationList: string[]) {
         const duration = 0.3;
         for (let i = 0; i < animationList.length; i++) {
             for (let k = 0; k < animationList.length; k++) {
-                if (animationList[i] === animationList[k]) continue
-                spineSkeleton.setMix(animationList[i], animationList[k], duration)
+                if (animationList[i] === animationList[k]) continue;
+                skeleton.setMix(animationList[i], animationList[k], duration);
             }
         }
     }
@@ -34,9 +35,8 @@ class Tools {
      */
     playEffect(audio: cc.AudioClip, loop: boolean = false, cb: Function = null): Promise<void> {
         return new Promise((resolve) => {
-            this.stopEffects();
             cc.audioEngine.playEffect(audio, loop);
-            AudioCB.instance.addQueue(AudioOrder.Add, audio.name, audio.duration * 1000, () => {
+            AudioCB.getInstance().addQueue(AudioOrder.Add, audio.name, audio.duration * 1000, () => {
                 if (cb) {
                     cb();
                 }
@@ -51,8 +51,8 @@ class Tools {
      */
     playEffectArr(audios: cc.AudioClip[], cb: Function = null): Promise<void> {
         return new Promise(async resolve => {
-            for (const iterator of audios) {
-                await this.playEffect(iterator);
+            for (const audio of audios) {
+                await this.playEffect(audio);
             }
             if (cb) {
                 cb();
@@ -63,7 +63,7 @@ class Tools {
 
     stopEffects() {
         cc.audioEngine.stopAllEffects();
-        AudioCB.instance.addQueue(AudioOrder.Del);
+        AudioCB.getInstance().addQueue(AudioOrder.Del);
     }
 
     /** 从节点上获取数组 */
@@ -389,7 +389,7 @@ class Tools {
      * @param value
      */
     setLocalStorage(key, value) {
-        cc.sys.localStorage.setItem(key, "" + value);
+        cc.sys.localStorage.setItem(key, value);
     };
 
     /**
@@ -410,6 +410,22 @@ class Tools {
         return data;
     };
 
+    /** 从网络地址信息 */
+    getNetLocationInfo(): UitlData {
+        let http = window.location.href;
+        let arrHttp = http.split("?");
+        let json = new UitlData();
+        if (arrHttp && arrHttp.length > 1) {
+            let arrObj = arrHttp[1].split("&");
+            for (let index = 0; index < arrObj.length; index++) {
+                let arrInfo = arrObj[index].split("=");
+                json[arrInfo[0]] = arrInfo[1];
+            }
+        }
+        console.log('网络地址信息:', JSON.stringify(json, null, 4));
+        return json;
+    };
+
     /**
      * 判断是否为json类型
      * @param {*} str 

+ 140 - 10
assets/src/common/common.ts

@@ -1,4 +1,6 @@
-export class AttributeUnit {
+import Tools from "./Tools";
+
+export class AttributeUnit {
     /** 名字-单元资源包 */
     bundleName: string;
     /** 名字-单元配置文件 */
@@ -10,12 +12,18 @@
 }
 
 export class AttributeGame {
-     /** 名字-视频 */
-     videoName?: string;
-     /** 名字-预制体 */
-     prefabName?: string;
-     /** 名字-脚本 */
-     scriptName: string;
+    /** 名字-视频 */
+    videoName?: string;
+    /** 名字-预制体 */
+    prefabName?: string;
+    /** 名字-脚本 */
+    scriptName: string;
+}
+
+export class UitlData {
+    url: string;
+    modelId?: number;
+    itemId?: string;
 }
 
 class common {
@@ -30,10 +38,33 @@ class common {
     };
 
     isDebug: boolean = false;
-    unitCur: number = 14;// 第几集,从1开始
-    pageCur: number = 8;// 第几个游戏,从1开始
+    project: string = "luojigou_model";
+    itemId: string = '';
+    unitCur: number = 1;// 第几集,从1开始
+    pageCur: number = 1;// 第几个游戏,从1开始
     isCanPlayVideo = false;
     attributeMap: any = {};// 内部形式为 { "0" : AttributeUtil } 
+    urlToken: string = 'https://open.api.luojigou.vip/mall/mobile/common/verify/token';// 验证token的地址;
+    urlOver: string = 'https://open.api.luojigou.vip/app/app/gameCourse/record/12321312';// 当前集游戏完结,上报地址;
+    urlClass: string = 'https://luojigou.vip/ac/#/courseDetail?id=1568062284888866817&mode=luojigou';// 课程页
+    objRes: any = {};//通用音频
+    timeStart: number = 0;
+
+    getTimeStart() {
+        return this.timeStart;
+    };
+
+    setTimeStart() {
+        this.timeStart = new Date().getTime();
+    };
+
+    getItemId(){
+        return this.itemId;
+    };
+
+    setItemId(id){
+        this.itemId = id;
+    };
 
     getUnitNum() {
         return this.unitCur > 0 ? this.unitCur : 1;
@@ -51,9 +82,108 @@ class common {
         this.pageCur = pageNum;
     };
 
+    //隐藏页面loading
+    hideLoading() {
+        var splash = document.getElementById('splash');
+        splash.style.visibility = 'hidden';
+        console.log("--hideLoading--: 隐藏加载界面");
+    }
+
+    /** 获取当前游戏的本地数据 */
+    getGameFormLocal(): number {
+        let objLocal: any = Tools.getLocalStorage(this.project, null);
+        objLocal = JSON.parse(objLocal);
+        if (!objLocal) return -1;
+        if (!objLocal.objUnit) return -1;
+        let unitOne = objLocal.objUnit[this.getUnitNum()];
+        if (!unitOne) return -1;
+        let gameOne = unitOne[this.getPageNum()];
+        return Number(gameOne);
+    };
+
+    /** 设置当前游戏标志 */
+    setGameToLocal(): void {
+        let unit = this.getUnitNum();
+        let page = this.getPageNum();
+        let objLocal: any = Tools.getLocalStorage(this.project, null);
+        objLocal = JSON.parse(objLocal);
+        if (objLocal) {
+            if (!objLocal.objUnit) {
+                objLocal.objUnit = {};
+            }
+            if (!objLocal.objUnit[unit]) {
+                objLocal.objUnit[unit] = {};
+            }
+            if (objLocal.objUnit[unit][page]) {
+                return;
+            }
+            else {
+                objLocal.objUnit[unit][page] = page;
+            }
+        }
+        else {
+            objLocal = {};
+            objLocal.project = this.project;
+            objLocal.objUnit = {};
+            objLocal.objUnit[unit] = {};
+            objLocal.objUnit[unit][page] = page;
+        }
+        Tools.setLocalStorage(this.project, JSON.stringify(objLocal));
+    };
+
+    /** token验证 */
+    httpCheckToken(): Promise<boolean> {
+        return new Promise((resolve) => {
+            let xhr = new XMLHttpRequest();
+            xhr.open("GET", this.urlToken, true);
+            xhr.setRequestHeader('token', Tools.getLocalStorage('token', null));
+            xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) {
+                    let json = JSON.parse(xhr.responseText);
+                    resolve(json.status == 200);
+                }
+            };
+            xhr.onerror = function () {
+                resolve(false);
+            }
+            xhr.send();
+        });
+    }
+
+    /** 数据上报 */
+    httpReportdata(): Promise<boolean> {
+        let util = this.getUnitNum();
+        let page = this.getPageNum();
+        let attribute: AttributeUnit = this.attributeMap[util];
+        let length = attribute.config.length;
+        let isFinish = page < length ? 0 : 1;
+        let timeStart = this.getTimeStart();
+        let playTime = Math.ceil((new Date().getTime() - timeStart)*0.001);
+        // 组合地址
+        let url = this.urlOver;
+        url += '/' + this.getItemId();
+        url += '/' + playTime;
+        url += '/' + page;
+        url += '/' + isFinish;
+        return new Promise((resolve) => {
+            let xhr = new XMLHttpRequest();
+            xhr.open("GET", url, true);
+            xhr.setRequestHeader('token', Tools.getLocalStorage('token', null));
+            xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) {
+                    resolve(true);
+                }
+            };
+            xhr.onerror = function () {
+                resolve(false);
+            }
+            xhr.send();
+        });
+    }
+
     /** cocos日志打印 */
     log(...params: any) {
-        // if (!CC_DEBUG) return;
+        if (!CC_DEBUG) return;
 
         var logContent = [];
         for (var i in params) {

+ 3 - 2
assets/src/config/Loader.ts

@@ -29,11 +29,12 @@ class Loader {
         });
     }
 
-    loadResLoacl(path){
+    loadResLoacl(path): Promise<any>{
         return new Promise((resolve) => {
-            cc.resources.load(path, cc.Asset, function (err, asset) {
+            cc.resources.load(path, function (err, asset: any) {
                 if (err) {
                     common.log("加载失败:", path);
+                    resolve(null);
                 }
                 else {
                     common.log("加载资源:", path);

+ 0 - 243
assets/src/http/Http.ts

@@ -1,243 +0,0 @@
-import { HttpStateMap } from "./HttpState";
-
-export class Http {
-    public static readonly GET: string = "get";
-    public static readonly POST: string = "post";
-
-    private static readonly UNSENT: number = 0; // Client has been created. open() not called yet.
-    private static readonly OPENED: number = 1; // open() has been called.
-    private static readonly HEADERS_RECEIVED: number = 2; // send() has been called, and headers and status are available.
-    private static readonly LOADING: number = 3; // Downloading; responseText holds partial data.
-    private static readonly DONE: number = 4; // The operation is complete.
-
-
-    private xhr: XMLHttpRequest;
-    private _onComplete: Function;
-    private _onError: Function;
-    private method: string;
-    private target: any;
-    private data: any;
-    private url: string;
-
-    public constructor() {
-        try {
-            if (window["XMLHttpRequest"]) {
-                this.xhr = new window["XMLHttpRequest"]();
-            } else {
-                // @ts-ignore
-                this.xhr = new ActiveXObject("MSXML2.XMLHTTP");
-            }
-            this.xhr.timeout = 3000;
-        } catch (e) {
-            console.error("Http create error", e);
-        }
-    }
-
-    /**
-     * 打开连接
-     * @param {string} url 文件在服务器上的位置
-     * @param {string} method 请求的类型,GET 或 POST,默认GET
-     * @param data 数据,对象或字符
-     * @returns {Http}
-     */
-    public open(url: string, method: string = Http.GET, data?: any): Http {
-        this.method = method || "get";
-        if (this.method == "get" && data) {
-            url = this.spliceUrl(url, data);
-        }
-        this.url = url;
-        this.data = data;
-        this.xhr.open(method, url, true);
-        return this;
-    }
-
-    /**
-     * get方法
-     * @param {string} url 文件在服务器上的位置
-     * @param data 对象或字符
-     * @returns {Http}
-     */
-    public openGet(url: string, data?: any): Http {
-        this.open(url, Http.GET, data);
-        return this;
-    }
-
-    /**
-     * post方法
-     * @param {string} url 文件在服务器上的位置
-     * @param data 对象或字符
-     * @returns {Http}
-     */
-    public openPost(url: string, data?: any): Http {
-        this.open(url, Http.POST, data)
-        return this;
-    }
-
-    /**
-     * 返回的结果,包括错误
-     * @param {Function} callback
-     * @param target this指针
-     * @returns {Http}
-     */
-    public onComplete(callback: Function, target?: any): Http {
-        this.target = target;
-        this._onComplete = callback;
-        return this;
-    }
-
-    /**
-     * 错误回调
-     * @param {Function} callback
-     * @param target this指针
-     * @returns {Http}
-     */
-    public onError(callback: Function, target?: any): Http {
-        this.target = target;
-        this._onError = callback;
-        return this;
-    }
-
-    /**
-     * 将请求发送到服务器。
-     * @param data 可以是对象|字符,仅用于 POST 请求
-     */
-    public send(data?: any): void {
-        data = data || this.data;
-        if (typeof data === "object") {
-            try {
-                data = JSON.stringify(data);
-            } catch (e) {
-                console.error(e);
-            }
-        }
-        this.xhr.onreadystatechange = this.onReadyStateChange.bind(this);
-        console.log(`body = ${data}`)
-        this.xhr.send(data);
-    }
-
-    /**
-     * 如果请求已经被发送,则立刻中止请求.
-     */
-    public abort(): void {
-        if (this.xhr) {
-            this.xhr.abort();
-        }
-    }
-
-    /**
-     * 向请求添加 HTTP 头。
-     * @example {token:A1BC,name:guess}
-     * @param data 键值对形式都好分割
-     * @returns {Http}
-     */
-    public setRequestHeader(data?: any): Http {
-        try {
-            for (let key in data) {
-                this.xhr.setRequestHeader(key, data[key]);
-            }
-        } catch (e) {
-            console.error(e);
-        }
-        return this;
-    }
-
-    /**
-     * 返回所有响应头信息(响应头名和值), 如果响应头还没接受,则返回"".
-     */
-    public getAllResponseHeaders(): string {
-        if (!this.xhr) {
-            return "";
-        }
-        let result: string = this.xhr.getAllResponseHeaders();
-        return result ? result : "";
-    }
-
-    public onDestroy(): void {
-        // TODO 清空其他数据
-        this.xhr = null;
-    }
-
-    private spliceUrl(url: string, data: any): string {
-        let dataStr: string = "";
-        for (let key in data) {
-            dataStr += key + "=" + data[key] + "&";
-        }
-        dataStr = dataStr.substr(0, dataStr.length - 1);
-        if (dataStr.length > 2) {
-            url += url.indexOf("?") < 0 ? "?" + dataStr : url + dataStr;
-        }
-        return url;
-    }
-
-    private onReadyStateChange(): void {
-        let xhr = this.xhr;
-        if (xhr.readyState == 4) {
-            let ioError = xhr.status >= 400 || xhr.status == 0;
-            let url = this.url;
-            let self = this;
-            if (ioError) {
-                if (this._onError) {
-                    let response = null;
-                    if (this.xhr.response) {
-                        response = JSON.parse(this.xhr.response)
-                    }
-                    this._onError(this.xhr.status, HttpStateMap.instance.getErrorInfoById(this.xhr.status), response); // TODO 返回错误码对应的含义
-                    // this._onError(this.xhr.status, HttpStateMap.instance.getErrorInfoById(this.xhr.status)); //TODO 返回错误码对应的含义
-                }
-            } else {
-                if (this.xhr.readyState == Http.DONE) {
-                    if (this.xhr.status >= 200 && this.xhr.status < 400) {
-                        this._onComplete.call(this.target ? this.target : null, JSON.parse(this.xhr.response));
-                    } else {
-                        this._onComplete.call(this.target ? this.target : null, HttpStateMap.instance.getErrorInfoById(this.xhr.status) // 返回错误码对应的含义
-                        );
-                    }
-                }
-            }
-        }
-    }
-    private static stringifyPrimitive(v: any) {
-        switch (typeof v) {
-            case 'string':
-                return v
-            case 'boolean':
-                return v ? 'true' : 'false'
-            case 'number':
-                return isFinite(v) ? v : ''
-            default:
-                return ''
-        }
-    }
-
-    private static stringify(obj, sep?: string, eq?: string, name?: string) {
-        sep = sep || '&'
-        eq = eq || '='
-        if (obj === null) {
-            obj = undefined
-        }
-
-        if (typeof obj === 'object') {
-            return Object.keys(obj).map(function (k) {
-                let ks = encodeURIComponent(Http.stringifyPrimitive(k)) + eq
-                if (Array.isArray(obj[k])) {
-                    return obj[k].map(function (v) {
-                        return ks + encodeURIComponent(Http.stringifyPrimitive(v))
-                    }).join(sep)
-                } else {
-                    return ks + encodeURIComponent(Http.stringifyPrimitive(obj[k]))
-                }
-            }).join(sep)
-
-        }
-
-        if (!name) { return '' }
-        return encodeURIComponent(Http.stringifyPrimitive(name)) + eq +
-            encodeURIComponent(Http.stringifyPrimitive(obj))
-    };
-
-    public static getUrl(url: string, params?: any) {
-        let s = Http.stringify(params)
-        let sep = url.indexOf('?') > -1 ? '&' : '?'
-        return url + (s ? sep + s : '')
-    }
-}

+ 0 - 141
assets/src/http/HttpSystem.ts

@@ -1,141 +0,0 @@
-import { Http } from "./Http";
-
-/**
- * # HTTP工具包
- * 封装http请求,兼容IE5 和 IE6。
- * ## 使用示例
- * * 快捷调用
- * ```
- * HttpSystem.httpGet("www.baidu.com");
- * HttpSystem.httpPost("www.baidu.com",{name:"fb",age:33});
- * ```
- * * 常规调用
- * ```
- * let req = new HttpSystem();
- * req.open("baidu.com", "get", {cointype: 8, gameid: GlobalConfig.GAME_ID, group: 1});
- * req.onResult(resultHandler);
- * req.setRequestHeader({"Content-Type": "application/x-www-form-urlencoded", "token": token});
- * req.send();
- * ```
- * * 链式调用
- * ```
- * let req = new HttpSystem();
- * req.open(AppConfig.getInstance().shop_list_URL, "get", {cointype: 8, gameid: GlobalConfig.GAME_ID, group: 1}).onResult(resultHandler).setRequestHeader({"Content-Type": "application/x-www-form-urlencoded", "token": token}).send();
- * ```
- * 
- * * Promise
- * ```
- * let result = await HttpSystem.httpGet(`/api/m-course?contentId=24`);
- * ```
- * ```
- * HttpSystem.httpPost("api/dosomething",{name:1,age:20}).then(res=>{}).catch(e => false);
- * ```
- * ## HTTP请求方法
-
- * 方法    | 描述
- * --- | ---
- * GET | 请求指定的页面信息,并返回实体主体。
- * HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
- * POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
- * PUT  | 从客户端向服务器传送的数据取代指定的文档的内容。
- * DELETE | 请求服务器删除指定的页面。
- * CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
- * OPTIONS | 允许客户端查看服务器的性能。
- * TRACE | 回显服务器收到的请求,主要用于测试或诊断。
- *
- * @version 1.0
- */
-export default class HttpSystem {
-    private static _instance: HttpSystem;
-    private outAdapter: Function;
-
-    public static get instance(): HttpSystem {
-        if (HttpSystem._instance == null) {
-            HttpSystem._instance = new HttpSystem();
-        }
-        return HttpSystem._instance;
-    }
-
-    /**
-     * @param {Function} outAdapter 发生错误的回调
-     * @memberof HttpSystem
-     */
-    public async init(outAdapter: Function): Promise<void> {
-        return new Promise((res) => {
-            this.outAdapter = outAdapter;
-            res();
-        })
-    }
-
-    public release(): void {
-        this.outAdapter = null;
-        HttpSystem._instance = null;
-    }
-    /**
-     * 发送get请求
-     * @param url 地址
-     * @param params url参数
-     */
-    public httpGet(url: string, params?: object, header?: string): Promise<any> {
-        console.log(`httpget:url = ${url}`)
-        return new Promise((resolve, reject) => {
-            let headerJson = { 'Content-Type': 'application/json; charset=utf-8' };
-            if (header && header != "") {
-                let json = JSON.parse(header);
-                for (let key in json) {
-                    headerJson[key] = json[key];
-                }
-            }
-            let xhr: Http = new Http();
-            xhr.onComplete(resolve);
-            xhr.onError((error, errInfo, response) => {
-                if (this.outAdapter) {
-                    this.outAdapter(`网络错误 ${error},${url}`, errInfo, response);
-                }
-                reject()
-            });
-            xhr.openGet(Http.getUrl(url, params));
-            xhr.setRequestHeader(headerJson);
-            xhr.send();
-        }).catch(reason => {
-            if (this.outAdapter) {
-                this.outAdapter(reason && reason.message || '网络错误' + url);
-            }
-        })
-    }
-
-    /**
-     * 发送一个post请求
-     * @param url 地址
-     * @param body 包体
-     * @param params url参数
-     */
-    public httpPost(url: string, body?: any, params?: object, header?: string,): Promise<any> {
-        console.log(`httpPost:url = ${Http.getUrl(url, params)}`)
-        return new Promise((resolve, reject) => {
-            let headerJson = { 'Content-Type': 'application/json; charset=utf-8' };
-            if (header && header != "") {
-                let json = JSON.parse(header);
-                for (let key in json) {
-                    headerJson[key] = json[key];
-                }
-            }
-
-            let xhr: Http = new Http();
-            xhr.onComplete(resolve);
-            xhr.onError((error, errInfo, response) => {
-                if (this.outAdapter) {
-                    this.outAdapter(`网络错误 ${error},${url}`, errInfo, response);
-                }
-                reject()
-            });
-            xhr.openPost(Http.getUrl(url, params));
-            xhr.setRequestHeader(headerJson);
-            xhr.send(body);
-        }).catch(reason => {
-            if (this.outAdapter) {
-                this.outAdapter(reason && reason.message || '网络错误' + url);
-            }
-        })
-    }
-}

+ 0 - 53
assets/src/http/IHttpSystem.ts

@@ -1,53 +0,0 @@
-export default interface IHttpSystem {
-
-    /**
-     * 初始化
-     * @param outAdapter 
-     */
-    init(outAdapter: Function): Promise<void> | void;
-    /**
-     * 释放时
-     */
-    release(): void;
-    /**
-     * 回调形式的HTTP get 请求,注意第3个参数为回调方法
-     * 发送get请求
-     * @param url 地址
-     * @param params url参数
-     * @param result_handler 回调方法
-     * @param type 类型
-     * @param retry_count 重试次数
-     * @param type_not_set_to_open 把type不作为openGet的参数,之前竟然把type作为onComplete参数的同时,也作为openGet的参数
-     */
-    httpGetWithCallBack(url: string, params?: object, result_handler?: Function, type?: string, retry_count?: number, type_not_set_to_open?: boolean): void;
-    /**
-     * 发送get请求
-     * @param url 地址
-     * @param params url参数
-     * @param type 类型
-     * @param retry_count 重试次数
-     * 
-     * @param type_not_set_to_open 把type不作为openGet的参数,之前竟然把type作为onComplete参数的同时,也作为openGet的参数
-     */
-    httpGet(url: string, params?: object, type?: string, retry_count?: number, result_handler?: Function, type_not_set_to_open?: boolean): Promise<any>;
-
-    /**
-    * 发送一个post请求
-    * @param url 地址
-    * @param body 包体
-    * @param params url参数
-    * @param retryCount 重试次数
-    * @param resultHandler 
-    */
-    httpPost(url: string, body?: any, params?: object, retryCount?: number, resultHandler?: Function): Promise<any>;
-
-    /**
-     * 回调的方式发送一个post请求,注意第4个参数为回调方法
-     * @param url 地址
-     * @param body 包体
-     * @param resultHandler 
-     * @param params url参数
-     * @param retryCount 重试次数
-     */
-    httpPostWithCallBack(url: string, body?: any, params?: object, resultHandler?: Function, retryCount?: number): void;
-}

+ 13 - 0
assets/src/popUp.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "76eb5ad3-2288-4979-a593-e69dd545af72",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 57 - 0
assets/src/popUp/ConfirmPopup.ts

@@ -0,0 +1,57 @@
+import PopupBase from "./PopupBase";
+
+const { ccclass, property } = cc._decorator;
+
+/**
+ * 确认弹窗(PopupBase 使用示例)
+ */
+@ccclass
+export default class ConfirmPopup extends PopupBase<ConfirmPopupOptions> {
+
+    @property(cc.Label)
+    private titleLabel: cc.Label = null;
+
+    @property(cc.Label)
+    private contentLabel: cc.Label = null;
+
+    @property(cc.Node)
+    private confirmBtn: cc.Node = null;
+
+    protected onLoad() {
+        this.registerEvent();
+    }
+
+    protected onDestroy() {
+        this.unregisterEvent();
+    }
+
+    private registerEvent() {
+        this.confirmBtn.on(cc.Node.EventType.TOUCH_END, this.onConfirmBtnClick, this);
+    }
+
+    private unregisterEvent() {
+        this.confirmBtn.targetOff(this);
+    }
+
+    protected init() {
+
+    }
+
+    protected updateDisplay(options: ConfirmPopupOptions): void {
+        this.titleLabel.string = options.title;
+        this.contentLabel.string = options.content;
+    }
+
+    protected onConfirmBtnClick() {
+        this.options.confirmCallback && this.options.confirmCallback();
+        this.hide();
+    }
+
+}
+
+/** 确认弹窗选项 */
+export interface ConfirmPopupOptions {
+    title: string;
+    content: string;
+    confirmCallback: Function;
+}

+ 1 - 1
assets/src/http/HttpSystem.ts.meta → assets/src/popUp/ConfirmPopup.ts.meta

@@ -1,6 +1,6 @@
 {
   "ver": "1.1.0",
-  "uuid": "e007fdc6-92bf-48c4-973e-151e23d9e362",
+  "uuid": "990626fa-4ed5-4179-952e-b6729c7f388b",
   "importer": "typescript",
   "isPlugin": false,
   "loadPluginInWeb": true,

+ 144 - 0
assets/src/popUp/PopupBase.ts

@@ -0,0 +1,144 @@
+const { ccclass, property } = cc._decorator;
+
+/**
+ * 弹窗基类
+ * @see PopupBase.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/components/popups/PopupBase.ts
+ * @see PopupManager.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/core/PopupManager.ts
+ * @version 20210409
+ */
+@ccclass
+export default class PopupBase<Options = any> extends cc.Component {
+
+    @property({ type: cc.Node, tooltip: CC_DEV && '背景遮罩' })
+    public background: cc.Node = null;
+
+    @property({ type: cc.Node, tooltip: CC_DEV && '弹窗主体' })
+    public main: cc.Node = null;
+
+    /** 展示/隐藏动画的时长 */
+    public animDuration: number = 0.3;
+
+    /** 用于拦截点击的节点 */
+    protected blocker: cc.Node = null;
+
+    /** 弹窗选项 */
+    protected options: Options = null;
+
+    /**
+     * 展示弹窗
+     * @param options 弹窗选项
+     * @param duration 动画时长
+     */
+    public show(options?: Options, duration: number = this.animDuration) {
+        return new Promise<void>(res => {
+            // 储存选项
+            this.options = options;
+            // 初始化节点
+            const background = this.background;
+            const main = this.main;
+            this.node.active = true;
+            background.active = true;
+            background.opacity = 0;
+            main.active = true;
+            main.scale = 0.5;
+            main.opacity = 0;
+            // 初始化
+            this.init(this.options);
+            // 更新样式
+            this.updateDisplay(this.options);
+            // 播放背景遮罩动画
+            cc.tween(background)
+                .to(duration * 0.8, { opacity: 200 })
+                .start();
+            // 播放弹窗主体动画
+            cc.tween(main)
+                .to(duration, { scale: 1, opacity: 255 }, { easing: 'backOut' })
+                .call(() => {
+                    // 弹窗已完全展示
+                    this.onShow && this.onShow();
+                    // Done
+                    res();
+                })
+                .start();
+        });
+    }
+
+    /**
+     * 隐藏弹窗
+     * @param suspended 是否被挂起
+     * @param duration 动画时长
+     */
+    public hide(suspended: boolean = false, duration: number = this.animDuration) {
+        return new Promise<void>(res => {
+            const node = this.node;
+            // 动画时长不为 0 时拦截点击事件(避免误操作)
+            if (duration !== 0) {
+                let blocker = this.blocker;
+                if (!blocker) {
+                    blocker = this.blocker = new cc.Node('blocker');
+                    blocker.addComponent(cc.BlockInputEvents);
+                    blocker.setParent(node);
+                    blocker.setContentSize(node.getContentSize());
+                }
+                blocker.active = true;
+            }
+            // 播放背景遮罩动画
+            cc.tween(this.background)
+                .delay(duration * 0.2)
+                .to(duration * 0.8, { opacity: 0 })
+                .start();
+            // 播放弹窗主体动画
+            cc.tween(this.main)
+                .to(duration, { scale: 0.5, opacity: 0 }, { easing: 'backIn' })
+                .call(() => {
+                    // 关闭拦截
+                    this.blocker && (this.blocker.active = false);
+                    // 关闭节点
+                    node.active = false;
+                    // 弹窗已完全隐藏(动画完毕)
+                    this.onHide && this.onHide(suspended);
+                    // Done
+                    res();
+                    // 弹窗完成回调
+                    this.finishCallback && this.finishCallback(suspended);
+                })
+                .start();
+        });
+    }
+
+    /**
+     * 初始化(派生类请重写此函数以实现自定义逻辑)
+     */
+    protected init(options: Options) { }
+
+    /**
+     * 更新样式(派生类请重写此函数以实现自定义样式)
+     * @param options 弹窗选项
+     */
+    protected updateDisplay(options: Options) { }
+
+    /**
+     * 弹窗已完全展示(派生类请重写此函数以实现自定义逻辑)
+     */
+    protected onShow() { }
+
+    /**
+     * 弹窗已完全隐藏(派生类请重写此函数以实现自定义逻辑)
+     * @param suspended 是否被挂起
+     */
+    protected onHide(suspended: boolean) { }
+
+    /**
+     * 弹窗流程结束回调(注意:该回调为 PopupManager 专用,重写 hide 函数时记得调用该回调)
+     */
+    protected finishCallback: (suspended: boolean) => void = null;
+
+    /**
+     * 设置弹窗完成回调(该回调为 PopupManager 专用)
+     * @param callback 回调
+     */
+    public setFinishCallback(callback: (suspended: boolean) => void) {
+        this.finishCallback = callback;
+    }
+
+}

+ 1 - 1
assets/src/http/Http.ts.meta → assets/src/popUp/PopupBase.ts.meta

@@ -1,6 +1,6 @@
 {
   "ver": "1.1.0",
-  "uuid": "fff1f89b-5112-4420-b6b1-e121fc45db3f",
+  "uuid": "f9d6bf94-a906-4b3c-b588-214ecb2c5e14",
   "importer": "typescript",
   "isPlugin": false,
   "loadPluginInWeb": true,

+ 434 - 0
assets/src/popUp/PopupManager.ts

@@ -0,0 +1,434 @@
+import PopupBase from "./PopupBase";
+
+/** 弹窗缓存模式 */
+export enum PopupCacheMode {
+    /** 一次性的(立即销毁节点,预制体资源随即释放) */
+    Once = 1,
+    /** 正常的(立即销毁节点,但是缓存预制体资源) */
+    Normal,
+    /** 频繁的(只关闭节点,且缓存预制体资源) */
+    Frequent
+}
+
+/** 弹窗请求结果 */
+export enum PopupShowResult {
+    /** 展示成功(已关闭) */
+    Done = 1,
+    /** 展示失败(加载失败) */
+    Failed,
+    /** 等待中(已加入等待队列) */
+    Waiting
+}
+
+/**
+ * 弹窗管理器
+ * @see PopupManager.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/core/PopupManager.ts
+ * @see PopupBase.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/components/popups/PopupBase.ts
+ * @version 20210524
+ */
+export default class PopupManager {
+
+    /** 预制体缓存 */
+    public static get prefabCache() { return this._prefabCache; }
+    private static _prefabCache: Map<string, cc.Prefab> = new Map<string, cc.Prefab>();
+
+    /** 节点缓存 */
+    public static get nodeCache() { return this._nodeCache; }
+    private static _nodeCache: Map<string, cc.Node> = new Map<string, cc.Node>();
+
+    /** 当前弹窗请求 */
+    public static get current() { return this._current; }
+    private static _current: PopupRequest = null;
+
+    /** 等待队列 */
+    public static get queue() { return this._queue; }
+    private static _queue: PopupRequest[] = [];
+
+    /** 被挂起的弹窗队列 */
+    public static get suspended() { return this._suspended; }
+    private static _suspended: PopupRequest[] = [];
+
+    /** 锁定状态 */
+    private static locked: boolean = false;
+
+    /** 用于存放弹窗节点的容器节点(不设置则默认为当前 Canvas) */
+    public static container: cc.Node = null;
+
+    /** 连续展示弹窗的时间间隔(秒) */
+    public static interval: number = 0.05;
+
+    /** 弹窗缓存模式 */
+    public static get CacheMode() { return PopupCacheMode; }
+
+    /** 弹窗请求结果 */
+    public static get ShowResult() { return PopupShowResult; }
+
+    public static cacheMode = PopupCacheMode;
+    public static showResult = PopupShowResult;
+    public static Base = PopupBase;
+    /**
+     * 弹窗动态加载开始回调
+     * @example
+     * PopupManager.loadStartCallback = () => {
+     *     LoadingTip.show();
+     * };
+     */
+    public static loadStartCallback: () => void = null;
+
+    /**
+     * 弹窗动态加载结束回调
+     * @example
+     * PopupManager.loadFinishCallback = () => {
+     *     LoadingTip.hide();
+     * };
+     */
+    public static loadFinishCallback: () => void = null;
+
+    /**
+     * 展示弹窗,如果当前已有弹窗在展示中则加入等待队列
+     * @param path 弹窗预制体相对路径(如:prefabs/MyPopup)
+     * @param options 弹窗选项(将传递给弹窗的组件)
+     * @param params 弹窗展示参数
+     * @example
+     * const options = {
+     *     title: 'Hello',
+     *     content: 'This is a popup!'
+     * };
+     * const params = {
+     *     mode: PopupCacheMode.Normal
+     * };
+     * PopupManager.show('prefabs/MyPopup', options, params);
+     */
+    public static show<Options>(targetNode: cc.Node, options?: Options, params?: PopupParams): Promise<PopupShowResult> {
+        let path: string = targetNode.uuid;
+        if (!targetNode.active) {
+            targetNode.active = true;
+        }
+        if (!this._nodeCache.has(path)) {
+            this._nodeCache.set(path, targetNode);
+        }
+        return new Promise(async (res) => {
+            // 解析处理参数
+            params = this.parseParams(params);
+            // 当前已有弹窗在展示中则加入等待队列
+            if (this._current || this.locked) {
+                // 是否立即强制展示
+                if (params && params.immediately) {
+                    this.locked = false;
+                    // 挂起当前弹窗
+                    await this.suspend();
+                } else {
+                    // 将请求推入等待队列
+                    this.push(targetNode, options, params);
+                    res(PopupShowResult.Waiting);
+                    return;
+                }
+            }
+            // 保存为当前弹窗,阻止新的弹窗请求
+            this._current = {
+                path:targetNode,
+                options,
+                params
+            };
+            // 先在缓存中获取弹窗节点
+            let node = this.getNodeFromCache(path);
+            // 缓存中没有,动态加载预制体资源
+            if (!cc.isValid(node)) {
+                // 开始回调
+                this.loadStartCallback && this.loadStartCallback();
+                // 等待加载
+                const prefab = await this.load(path);
+                // 完成回调
+                this.loadFinishCallback && this.loadFinishCallback();
+                // 加载失败(一般是路径错误导致的)
+                if (!cc.isValid(prefab)) {
+                    cc.warn('[PopupManager]', '弹窗加载失败', path);
+                    this._current = null;
+                    res(PopupShowResult.Failed);
+                    return;
+                }
+                // 实例化节点
+                node = cc.instantiate(prefab);
+            }
+            // 获取继承自 PopupBase 的弹窗组件
+            const popup = node.getComponent(PopupBase);
+            if (!popup) {
+                cc.warn('[PopupManager]', '未找到弹窗组件', path);
+                this._current = null;
+                res(PopupShowResult.Failed);
+                return;
+            }
+            // 保存组件引用
+            this._current.popup = popup;
+            // 保存节点引用
+            this._current.node = node;
+            // 添加到场景中
+            node.setParent(this.container || cc.Canvas.instance.node);
+            // 显示在最上层
+            node.setSiblingIndex(cc.macro.MAX_ZINDEX);
+            // 设置完成回调
+            const finishCallback = async (suspended: boolean) => {
+                if (suspended) {
+                    return;
+                }
+                // 是否需要锁定
+                this.locked = (this._suspended.length > 0 || this._queue.length > 0);
+                // 回收
+                this.recycle(path, node, params.mode);
+                this._current = null;
+                res(PopupShowResult.Done);
+                // 延迟一会儿
+                await new Promise((_res) => {
+                    cc.Canvas.instance.scheduleOnce(_res, this.interval);
+                });
+                // 下一个弹窗
+                this.next();
+            }
+            popup.setFinishCallback(finishCallback);
+            // 展示
+            popup.show(options);
+        });
+    }
+
+    /**
+     * 隐藏当前弹窗
+     */
+    public static hide() {
+        if (this._current && this._current.popup) {
+            this._current.popup.hide();
+        }
+    }
+
+    /**
+     * 从缓存中获取节点
+     * @param path 弹窗路径
+     */
+    private static getNodeFromCache(path: string): cc.Node {
+        // 从节点缓存中获取
+        const nodeCache = this._nodeCache;
+        if (nodeCache.has(path)) {
+            const node = nodeCache.get(path);
+            if (cc.isValid(node)) {
+                return node;
+            }
+            // 删除无效引用
+            nodeCache.delete(path);
+        }
+        // 从预制体缓存中获取
+        const prefabCache = this._prefabCache;
+        if (prefabCache.has(path)) {
+            const prefab = prefabCache.get(path);
+            if (cc.isValid(prefab)) {
+                return cc.instantiate(prefab);
+            }
+            // 删除无效引用
+            prefabCache.delete(path);
+        }
+        // 无
+        return null;
+    }
+
+    /**
+     * 展示挂起或等待队列中的下一个弹窗
+     */
+    private static next() {
+        if (this._current ||
+            (this._suspended.length === 0 && this._queue.length === 0)) {
+            return;
+        }
+        // 取出一个请求
+        let request: PopupRequest = null;
+        if (this._suspended.length > 0) {
+            // 挂起队列
+            request = this._suspended.shift();
+        } else {
+            // 等待队列
+            request = this._queue.shift();
+        }
+        // 解除锁定
+        this.locked = false;
+        // 已有实例
+        if (cc.isValid(request.popup)) {
+            // 设为当前弹窗
+            this._current = request;
+            // 直接展示
+            request.popup.show(request.options);
+            return;
+        }
+        // 加载并展示
+        this.show(request.path, request.options, request.params);
+    }
+
+    /**
+     * 添加一个弹窗请求到等待队列中,如果当前没有展示中的弹窗则直接展示该弹窗。
+     * @param path 弹窗预制体相对路径(如:prefabs/MyPopup)
+     * @param options 弹窗选项
+     * @param params 弹窗展示参数
+     */
+    private static push<Options>(path: cc.Node, options?: Options, params?: PopupParams) {
+        // 直接展示
+        if (!this._current && !this.locked) {
+            this.show(path, options, params);
+            return;
+        }
+        // 加入队列
+        this._queue.push({ path, options, params });
+        // 按照优先级从小到大排序
+        this._queue.sort((a, b) => (a.params.priority - b.params.priority));
+    }
+
+    /**
+     * 挂起当前展示中的弹窗
+     */
+    private static async suspend() {
+        if (!this._current) {
+            return;
+        }
+        const request = this._current;
+        // 将当前弹窗推入挂起队列
+        this._suspended.push(request);
+        // 关闭当前弹窗(挂起)
+        await request.popup.hide(true);
+        // 置空当前
+        this._current = null;
+    }
+
+    /**
+     * 回收弹窗
+     * @param path 弹窗路径
+     * @param node 弹窗节点
+     * @param mode 缓存模式
+     */
+    private static recycle(path: string, node: cc.Node, mode: PopupCacheMode) {
+        switch (mode) {
+            // 一次性
+            case PopupCacheMode.Once:
+                node.destroy();
+                this._nodeCache.delete(path);
+                this.release(path);
+                break;
+            // 正常
+            case PopupCacheMode.Normal:
+                node.destroy();
+                this._nodeCache.delete(path);
+                break;
+            // 频繁
+            case PopupCacheMode.Frequent:
+                node.removeFromParent(false);
+                this._nodeCache.set(path, node);
+                break;
+        }
+    }
+
+    /**
+     * 加载并缓存弹窗预制体资源
+     * @param path 弹窗路径
+     */
+    public static load(path: string): Promise<cc.Prefab> {
+        return new Promise((res) => {
+            const prefabMap = this._prefabCache;
+            // 先看下缓存里有没有,避免重复加载
+            if (prefabMap.has(path)) {
+                const prefab = prefabMap.get(path);
+                // 缓存是否有效
+                if (cc.isValid(prefab)) {
+                    res(prefab);
+                    return;
+                } else {
+                    // 删除无效引用
+                    prefabMap.delete(path);
+                }
+            }
+            // 动态加载
+            cc.resources.load(path, (error: Error, prefab: cc.Prefab) => {
+                if (error) {
+                    res(null);
+                    return;
+                }
+                // 缓存预制体
+                prefabMap.set(path, prefab);
+                // 增加引用计数
+                prefab.addRef();
+                res(prefab);
+            });
+        });
+    }
+
+    /**
+     * 尝试释放弹窗资源(注意:弹窗内部动态加载的资源请自行释放)
+     * @param path 弹窗路径
+     */
+    public static release(path: string) {
+        // 移除节点
+        const nodeCache = this._nodeCache;
+        let node = nodeCache.get(path);
+        if (node) {
+            nodeCache.delete(path);
+            if (cc.isValid(node)) {
+                node.destroy();
+            }
+            node = null;
+        }
+        // 移除预制体
+        const prefabCache = this._prefabCache;
+        let prefab = prefabCache.get(path);
+        if (prefab) {
+            prefabCache.delete(path);
+            prefab.decRef();
+            prefab = null;
+        }
+    }
+
+    /**
+     * 解析参数
+     * @param params 参数
+     */
+    private static parseParams(params: PopupParams) {
+        if (params == undefined) {
+            return new PopupParams();
+        }
+        // 是否为对象
+        if (Object.prototype.toString.call(params) !== '[object Object]') {
+            cc.warn('[PopupManager]', '弹窗参数无效,使用默认参数');
+            return new PopupParams();
+        }
+        // 缓存模式
+        if (params.mode == undefined) {
+            params.mode = PopupCacheMode.Normal;
+        }
+        // 优先级
+        if (params.priority == undefined) {
+            params.priority = 0;
+        }
+        // 立刻展示
+        if (params.immediately == undefined) {
+            params.immediately = false;
+        }
+        return params;
+    }
+
+}
+
+/** 弹窗展示参数 */
+export class PopupParams {
+    /** 缓存模式 */
+    public mode?: PopupCacheMode = PopupCacheMode.Normal;
+    /** 优先级(优先级大的优先展示) */
+    public priority?: number = 0;
+    /** 立刻展示(将会挂起当前展示中的弹窗) */
+    public immediately?: boolean = false;
+}
+
+/** 弹窗展示请求 */
+export interface PopupRequest {
+    /** 弹窗预制体相对路径 */
+    path: cc.Node;
+    /** 弹窗选项 */
+    options: any;
+    /** 缓存模式 */
+    params: PopupParams,
+    /** 弹窗组件 */
+    popup?: PopupBase,
+    /** 弹窗节点 */
+    node?: cc.Node
+}

+ 10 - 0
assets/src/popUp/PopupManager.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "060683e5-ac91-4a43-afb8-9aafd2d3934a",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}