소스 검색

萨满消方块

zh 1 년 전
커밋
9c8b6128cb
100개의 변경된 파일7441개의 추가작업 그리고 0개의 파일을 삭제
  1. 12 0
      assets/Script.meta
  2. 12 0
      assets/Script/Common.meta
  3. 86 0
      assets/Script/Common/Constant.ts
  4. 9 0
      assets/Script/Common/Constant.ts.meta
  5. 114 0
      assets/Script/Common/Global.ts
  6. 9 0
      assets/Script/Common/Global.ts.meta
  7. 23 0
      assets/Script/Common/LogMgr.ts
  8. 9 0
      assets/Script/Common/LogMgr.ts.meta
  9. 121 0
      assets/Script/Common/ShowConfig.ts
  10. 9 0
      assets/Script/Common/ShowConfig.ts.meta
  11. 23 0
      assets/Script/Common/Test.ts
  12. 9 0
      assets/Script/Common/Test.ts.meta
  13. 650 0
      assets/Script/Common/Tools.ts
  14. 9 0
      assets/Script/Common/Tools.ts.meta
  15. 12 0
      assets/Script/Common/manage.meta
  16. 408 0
      assets/Script/Common/manage/ActionMgr.ts
  17. 9 0
      assets/Script/Common/manage/ActionMgr.ts.meta
  18. 12 0
      assets/Script/Common/manage/Api.meta
  19. 199 0
      assets/Script/Common/manage/Api/QgApi.ts
  20. 9 0
      assets/Script/Common/manage/Api/QgApi.ts.meta
  21. 147 0
      assets/Script/Common/manage/Api/QgBanner.ts
  22. 9 0
      assets/Script/Common/manage/Api/QgBanner.ts.meta
  23. 67 0
      assets/Script/Common/manage/Api/QgIntersAd.ts
  24. 9 0
      assets/Script/Common/manage/Api/QgIntersAd.ts.meta
  25. 107 0
      assets/Script/Common/manage/Api/QgNative.ts
  26. 9 0
      assets/Script/Common/manage/Api/QgNative.ts.meta
  27. 95 0
      assets/Script/Common/manage/Api/QgRewardedAd.ts
  28. 9 0
      assets/Script/Common/manage/Api/QgRewardedAd.ts.meta
  29. 56 0
      assets/Script/Common/manage/AudioMgr.ts
  30. 9 0
      assets/Script/Common/manage/AudioMgr.ts.meta
  31. 299 0
      assets/Script/Common/manage/CacheMgr.ts
  32. 9 0
      assets/Script/Common/manage/CacheMgr.ts.meta
  33. 12 0
      assets/Script/Common/manage/Emit.meta
  34. 22 0
      assets/Script/Common/manage/Emit/Emit.ts
  35. 9 0
      assets/Script/Common/manage/Emit/Emit.ts.meta
  36. 92 0
      assets/Script/Common/manage/Emit/EmitBase.ts
  37. 9 0
      assets/Script/Common/manage/Emit/EmitBase.ts.meta
  38. 18 0
      assets/Script/Common/manage/Emit/EmitData.ts
  39. 9 0
      assets/Script/Common/manage/Emit/EmitData.ts.meta
  40. 22 0
      assets/Script/Common/manage/GameLogMgr.ts
  41. 9 0
      assets/Script/Common/manage/GameLogMgr.ts.meta
  42. 12 0
      assets/Script/Common/manage/Layer.meta
  43. 15 0
      assets/Script/Common/manage/Layer/LayerMgr.ts
  44. 9 0
      assets/Script/Common/manage/Layer/LayerMgr.ts.meta
  45. 43 0
      assets/Script/Common/manage/Layer/LayerPanel.ts
  46. 9 0
      assets/Script/Common/manage/Layer/LayerPanel.ts.meta
  47. 179 0
      assets/Script/Common/manage/Layer/LayerUI.ts
  48. 9 0
      assets/Script/Common/manage/Layer/LayerUI.ts.meta
  49. 222 0
      assets/Script/Common/manage/LoadMgr.ts
  50. 9 0
      assets/Script/Common/manage/LoadMgr.ts.meta
  51. 168 0
      assets/Script/Common/manage/PanelMgr.ts
  52. 9 0
      assets/Script/Common/manage/PanelMgr.ts.meta
  53. 107 0
      assets/Script/Common/manage/PondMgr.ts
  54. 9 0
      assets/Script/Common/manage/PondMgr.ts.meta
  55. 56 0
      assets/Script/Common/manage/StorageMgr.ts
  56. 9 0
      assets/Script/Common/manage/StorageMgr.ts.meta
  57. 31 0
      assets/Script/Common/manage/TimerMgr.ts
  58. 9 0
      assets/Script/Common/manage/TimerMgr.ts.meta
  59. 12 0
      assets/Script/Moudle.meta
  60. 12 0
      assets/Script/Moudle/View.meta
  61. 193 0
      assets/Script/Moudle/View/EndView.ts
  62. 9 0
      assets/Script/Moudle/View/EndView.ts.meta
  63. 212 0
      assets/Script/Moudle/View/GameInfoView.ts
  64. 9 0
      assets/Script/Moudle/View/GameInfoView.ts.meta
  65. 1571 0
      assets/Script/Moudle/View/GameView.ts
  66. 9 0
      assets/Script/Moudle/View/GameView.ts.meta
  67. 98 0
      assets/Script/Moudle/View/HomeView.ts
  68. 9 0
      assets/Script/Moudle/View/HomeView.ts.meta
  69. 189 0
      assets/Script/Moudle/View/NativeView.ts
  70. 9 0
      assets/Script/Moudle/View/NativeView.ts.meta
  71. 116 0
      assets/Script/Moudle/View/ShortageView.ts
  72. 9 0
      assets/Script/Moudle/View/ShortageView.ts.meta
  73. 12 0
      assets/Script/Moudle/View/logic.meta
  74. 12 0
      assets/Script/Moudle/View/logic/common.meta
  75. 173 0
      assets/Script/Moudle/View/logic/common/config.ts
  76. 9 0
      assets/Script/Moudle/View/logic/common/config.ts.meta
  77. 17 0
      assets/Script/Moudle/View/logic/common/text.ts
  78. 9 0
      assets/Script/Moudle/View/logic/common/text.ts.meta
  79. 12 0
      assets/Script/Moudle/View/logic/game.meta
  80. 63 0
      assets/Script/Moudle/View/logic/game/shop.ts
  81. 9 0
      assets/Script/Moudle/View/logic/game/shop.ts.meta
  82. 141 0
      assets/Script/Moudle/View/logic/game/sign.ts
  83. 9 0
      assets/Script/Moudle/View/logic/game/sign.ts.meta
  84. 12 0
      assets/Script/SDK.meta
  85. 161 0
      assets/Script/SDK/JiuWuSDK.ts
  86. 9 0
      assets/Script/SDK/JiuWuSDK.ts.meta
  87. 12 0
      assets/Script/Scene.meta
  88. 47 0
      assets/Script/Scene/Game.ts
  89. 9 0
      assets/Script/Scene/Game.ts.meta
  90. 94 0
      assets/Script/Scene/Loading.ts
  91. 9 0
      assets/Script/Scene/Loading.ts.meta
  92. 12 0
      assets/View.meta
  93. 20 0
      assets/View/end.meta
  94. 143 0
      assets/View/end/coin.prefab
  95. 8 0
      assets/View/end/coin.prefab.meta
  96. 119 0
      assets/View/end/huodejinbi.prefab
  97. 8 0
      assets/View/end/huodejinbi.prefab.meta
  98. 24 0
      assets/View/endView.meta
  99. 12 0
      assets/View/endView/end.meta
  100. 143 0
      assets/View/endView/end/coin.prefab

+ 12 - 0
assets/Script.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "2e5367c8-4af9-48c6-a839-9c76491ceb8b",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Common.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "83110f0c-2ed8-4400-9091-875d9b59fb22",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 86 - 0
assets/Script/Common/Constant.ts

@@ -0,0 +1,86 @@
+import GameLogMgr from "./manage/GameLogMgr";
+
+/**
+ * 常量配置
+ */
+export default class Constant {
+
+    public static REWARDED_VIDEO_END_TYPE = {
+        END: 1, // 播放完整
+        NOT_END: 2, // 未播放完整
+        ERROR: 3, // 报错
+        // INSERT_SCREEN: 4, //插屏代替
+        // SHARE: 5, //分享代替
+    };
+
+    // 分享类型
+    public static UNLOCK_TYPE = {
+        PASS_GAME: 1, // 跳过
+        TIPS: 2, // 双倍金币
+        GET_STRENGTH: 3, // 获取体力
+        DOUBLE_STRENGTH: 4, // 双倍体力
+        NEXT_LEVEL: 5, // 下一关卡
+        GET_GOLD: 6, // 获取体力
+        DOUBLE: 7, //
+        TRY_SKIN: 8
+    };
+
+    public static GAME_BOX_TWEEN_TYPE = {
+        SHAKE_STOP: 1,
+        SHAKE_FOREVER: 2,
+        SCALE_MOVE: 3
+    };
+
+    //?
+    public static LOGIN_CODE = {
+        1: '本地环境不予后台进行交互;',
+        2: '微信接口调用失败;',
+        3: '微信登录接口调用成功,但 Code 为空;',
+        4: "用户后台登录失败 code != 200;",
+        5: '用户后台登录失败!',
+        6: '更新用户数据失败, Code != 200;',
+        7: '更新用户数据失败;',
+        8: '获取游戏配置失败, Code != 200;',
+        9: '获取游戏配置失败;',
+        10: '获取游戏导出失败, Code != 200;',
+        11: '获取游戏导出失败;',
+        12: '上报游戏导出失败, Code != 200;',
+        13: '上报游戏导出失败;',
+    }
+
+    public static VIDEO_TYPE = {
+        POP: 1, // 弹窗型试用广告,
+        GET_PROPS: 2, // 获取道具,
+        GET_POWER: 3, // 获取体力,
+        GET_GOLD: 4, // 获取金币,
+        GET_DOUBLE: 5, // 双倍领取,
+        UNLOCK: 6, //解锁关卡,
+        GET_SKIN: 7, // 获取皮肤
+        ENFORCE: 8, // 强拉视频
+        PLAY_END: 9, //播放完成
+        PLAY_CLOSE: 10, //播放到一半没了
+    }
+    //4
+    public static BOTTOM_TYPE = {
+        NEW_BANNER_SHOW: 1, //新banner展示完成
+        OLD_BANNER_SHOW: 2, //旧banner展示完成
+        NEW_CUSTOM_SHOW: 3, //新自定义广告展示完成
+        OLD_CUSTOM_SHOW: 4, //旧自定义广告展示完成
+    }
+
+    //5  导出成功记录
+    public static EXPORT_TYPE = {
+        FORCE: 1,      //强制导出
+        RAND_FORCE: 2, //随机一个
+        GAME_BOX_ONE: 3,   //ONE BOX
+        GAME_BOX_TWO: 5,  //TWO BOX
+        GAME_BOX_THREE: 6, //THREE BOX
+        GAME_BOX_FOUR: 11, //FOUR BOX
+        GAME_BOX_SLIDER: 7,// SLIDER BOX  侧边栏导出
+        OPEN_DATA: 8,  //开放数据域
+        VIEW_BOX: 9, //页面导出
+        BANNER_BOX: 10, //banner导出
+    }
+
+
+}

+ 9 - 0
assets/Script/Common/Constant.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "7ecf2e5d-4982-44f2-9ef5-eb4902d6b5d3",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 114 - 0
assets/Script/Common/Global.ts

@@ -0,0 +1,114 @@
+/**
+ * 全局变量
+ */
+
+export default class Global {
+    public static isVivo = false;
+
+    public static allData: any;
+
+    public static configData: any;
+
+    public static fromAppId: string = '';
+
+    public static config = {
+        homeConfig: {
+            startVideo: 1,
+            videoPer: 100,
+            startNative: 1,
+            nativePer: 100,
+            nativeConfig: {
+                type: 1,
+                labelType: 1,
+                time: 0
+            },
+            startIntersAd: 1,
+            intersAdPer: 100,
+            bannerShow: 1, //是否显示Banner
+        },
+        gameConfig: {
+            startVideo: 1,
+            videoPer: 100,
+            startNative: 1,
+            nativePer: 100,
+            nativeConfig: {
+                type: 1,
+                labelType: 1,
+                time: 0
+            },
+            startIntersAd: 1,
+            intersAdPer: 100,
+            bannerShow: 1, //是否显示Banner
+        },
+        endConfig: {
+            startVideo: 1,
+            videoPer: 100,
+            startNative: 1,
+            nativePer: 100,
+            nativeConfig: {
+                type: 1,
+                labelType: 1,
+                time: 0
+            },
+            startIntersAd: 1,
+            intersAdPer: 100,
+            bannerShow: 1, //是否显示Banner
+        },
+        advertisingConfig: {
+            rewardedVideoAdId: [
+                "180d657c8ca14c4ea2089385ab85cc4c"
+            ],
+            interstitialAdId: [
+                "e1a55af9ad0240d58063373c019eac8b"
+            ],
+            bannerAdId: [
+                "e3c3b01217a843fe8c695ec0ad053ed8"
+            ],
+            nativeAdId: [
+                "d8bfb3dc126748388d86311af35c4d00"
+            ]
+        },
+        gameInfo: {
+            animation: 0.5,
+            maxStamina: 10,
+            autoAddStaminaTime: 1,
+            autoAddStaminaNum: 1
+        },
+        addInfo: {
+            gold: 100,
+            diamond: 2,
+            stamina: 2
+        },
+        bannerRefreshTime: 10, //banner刷新时间 (单位:秒/s,“最小 30”)
+        isLog: 1, //log  0 : 不
+    };
+}
+
+/**
+ * 导出数据
+ */
+export interface ExportData {
+    appId: string // appID
+    id: number // 后台导出ID
+    adImg: string // 广告图URL
+    exportSrc: string // 导出路劲
+    gameOriginId: number // 原游戏ID
+    gameTargetId: number
+    gameTargetName: string // 分享游戏名称
+    iconImg: string
+    isLike: number
+    isOffline: number
+    isPopular: number
+    sort: number
+    isTripart: number
+    pageType: number
+}
+
+export interface UIConfig {
+    banner_probability: number,    //banner 显示概率
+    gameBox_probability: number,  //gameBox 显示概率
+    chest_probability: number,   //误触宝箱
+    insert_probability: number,  //插屏
+    video_probability: number,   // 强拉视频
+    export_show: number[],      //显示时候的导出
+}

+ 9 - 0
assets/Script/Common/Global.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "09dc93be-ff5c-47b8-bc6e-a1797cc7e333",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 23 - 0
assets/Script/Common/LogMgr.ts

@@ -0,0 +1,23 @@
+import Global from "./Global";
+
+export default class LogMgr {
+
+    public static log(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.log.apply(cc.log, args);
+        }
+    }
+
+    public static warn(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.warn.apply(cc.warn, args);
+        }
+    }
+
+    public static error(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.error.apply(cc.error, args);
+        }
+    }
+
+}

+ 9 - 0
assets/Script/Common/LogMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "05e787cd-bc93-48dd-a7f6-0466b9bf41e0",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 121 - 0
assets/Script/Common/ShowConfig.ts

@@ -0,0 +1,121 @@
+import Global from "./Global";
+import LogMgr from "./LogMgr";
+import Tools from "./Tools";
+import Emit from "./manage/Emit/Emit";
+import EmitData from "./manage/Emit/EmitData";
+import QgBanner from "./manage/Api/QgBanner";
+
+export default class ShowConfig {
+
+    private static str: string = '';
+
+    private static showResolve: any = null;
+
+    public static initEmit() {
+        Emit.instance().on(EmitData.IN_NATIVE_NEXT, this.inNativeNext, this);
+    }
+
+
+    public static show(str: string) {
+        return new Promise((resolve) => {
+            this.showResolve = resolve;
+            if (!Global.isVivo) {
+                this.showResolve(false);
+                this.showResolve = null;
+                return;
+            }
+
+            if (!str || !Global.config[str]) {
+                LogMgr.error('参数为空或者config中不存在该配置:str:' + str);
+                this.showResolve(false);
+                this.showResolve = null;
+                return
+            }
+            LogMgr.log('检测配置信息');
+
+            this.str = str;
+
+
+            if (Global.config[this.str].nativeConfig.type == 2) {
+                QgBanner.hideBanner();
+            }
+
+            console.log('AAA>>>>>>')
+            this.playVideo().then(() => {
+                console.log('BBB>>>>>>')
+                return this.openNative();
+            }).then((res) => {
+                if (!res) {
+                    this.inNativeNext();
+                }
+            })
+        })
+
+    }
+
+    private static playVideo() {
+        return new Promise((resolve) => {
+            if (Global.config[this.str].startVideo == 0) {
+                Global.config[this.str].startVideo = 1;
+                resolve(true);
+                return
+            }
+
+            if (Tools.checkPer(Global.config[this.str].videoPer)) {
+                Tools.handleVideo().then(() => {
+                    resolve(true);
+                })
+            } else {
+                resolve(true);
+            }
+        })
+    }
+
+    private static openNative() {
+        return new Promise((resolve) => {
+            console.log('CCC>>>>>>');
+            if (Global.config[this.str].startNative == 0) {
+                Global.config[this.str].startNative = 1;
+                resolve(false);
+                return
+            }
+
+            if (Tools.checkPer(Global.config[this.str].nativePer)) {
+                Tools.showNative(Global.config[this.str].nativeConfig.type, Global.config[this.str].nativeConfig.labelType, Global.config[this.str].nativeConfig.time).then((res) => {
+                    resolve(res);
+                });
+            } else {
+                resolve(false);
+            }
+        })
+    }
+
+    private static openIntersAd() {
+        return new Promise((resolve) => {
+            console.log('DDD>>>>>>')
+            if (Global.config[this.str].startIntersAd == 0) {
+                Global.config[this.str].startIntersAd = 1;
+                resolve(false);
+                return
+            }
+
+            if (Tools.checkPer(Global.config[this.str].intersAdPer)) {
+                Tools.handlerInters().then((res) => {
+                    resolve(res);
+                })
+            } else {
+                resolve(false);
+            }
+        })
+    }
+
+
+    private static inNativeNext() {
+        this.openIntersAd().then((res) => {
+            console.log('EEE>>>>>>')
+            this.showResolve(true);
+            this.showResolve = null;
+        })
+    }
+
+}

+ 9 - 0
assets/Script/Common/ShowConfig.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "a4d84ca0-92d6-43da-97e1-036ff5dacf08",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 23 - 0
assets/Script/Common/Test.ts

@@ -0,0 +1,23 @@
+import GameLogMgr from "./manage/GameLogMgr";
+
+export default class TestMgr {
+    private static timeData: Map<string, number> = new Map<string, number>()
+
+    public static start(flag: string) {
+        if (this.timeData.has(flag)) {
+            GameLogMgr.warn("TestMgr 重复 flag ", flag)
+            return
+        }
+        this.timeData.set(flag, new Date().getTime())
+    }
+
+    public static end(flag: string) {
+        if (!this.timeData.has(flag)) {
+            GameLogMgr.warn("flag不存在, 无法计算时差", flag)
+            return
+        }
+        GameLogMgr.log(flag, new Date().getTime() - this.timeData.get(flag))
+        this.timeData.delete(flag)
+    }
+
+}

+ 9 - 0
assets/Script/Common/Test.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "b5633709-eb20-4509-bd91-22e6fd583b2d",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 650 - 0
assets/Script/Common/Tools.ts

@@ -0,0 +1,650 @@
+import Global, {ExportData} from "./Global";
+import LoadMgr from "./manage/LoadMgr";
+import CacheMgr from "./manage/CacheMgr";
+import GameLogMgr from "./manage/GameLogMgr";
+import JiuWuSDK from "../SDK/JiuWuSDK";
+import Game from "../Scene/Game";
+import PanelMgr, {Layer} from "./manage/PanelMgr";
+import ShortageView from "../Moudle/View/ShortageView";
+import isNumber = cc.js.isNumber;
+import QgNative from "./manage/Api/QgNative";
+import LogMgr from "./LogMgr";
+import NativeView from "../Moudle/View/NativeView";
+import QgRewardedAd from "./manage/Api/QgRewardedAd";
+import QgIntersAd from "./manage/Api/QgIntersAd";
+import AudioMgr from "./manage/AudioMgr";
+
+export default class Tools {
+
+    public static subStr(str, n) {
+        let r = /[^\x00-\xff]/g;
+        if (str.replace(r, "mm").length <= n) {
+            return str;
+        }
+        let m = Math.floor(n / 2);
+        for (let i = m; i < str.length; i++) {
+            if (str.substr(0, i).replace(r, "mm").length >= n) {
+                return str.substr(0, i) + "...";
+            }
+        }
+        return str;
+    }
+
+    /**
+     * 短震动
+     * light  轻震动
+     * medium 中震动
+     * heavy  重震动
+     */
+    public static vibrateShort(type: string = 'heavy', number: number = 10) {
+        // @ts-ignore
+        if (!window.qg) {
+            return
+        }
+        for (let index = 0; index < number; index++) {
+            // @ts-ignore
+            qg.vibrateShort();
+        }
+    }
+
+    /**
+     * 短震动
+     */
+    public static vibrateLong() {
+        // @ts-ignore
+        if (!window.qg) {
+            return
+        }
+        // @ts-ignore
+        qg.vibrateLong();
+    }
+
+    //判断一个值是否在一个数组中
+    public static JudgeValueInArr(value: any, arr: Array<any>) {
+        let flag = false
+        for (let i = 0; i < arr.length; i++) {
+            if (arr[i] === value) {
+                flag = true
+                break
+            }
+        }
+        return flag
+    }
+
+    /**
+     * 对象深拷贝
+     * @param obj
+     */
+    public static deepClone(obj) {
+        try {
+            return JSON.parse(JSON.stringify(obj));
+        } catch (e) {
+            return obj;
+        }
+    }
+
+
+    /**
+     * 获取整数随机值
+     * @param maxValue
+     * @return [0, max)
+     */
+    public static getRandomMax(maxValue: number) {
+        return Math.floor(Math.random() * maxValue)
+    }
+
+    /**
+     * 获取数组随机值
+     * @param array
+     */
+    public static getRandomByArray(array: any) {
+        try {
+            return array[this.getRandomMax(array.length)];
+        } catch (e) {
+            GameLogMgr.error('获取数组随机值异常', e);
+        }
+        return {};
+    }
+
+    /**
+     * 获取整数随机值
+     * @param minValue
+     * @param maxValue
+     * @return [min, max)
+     */
+    public static getRandom(minValue: number, maxValue: number): number {
+        return Math.floor(Math.random() * (maxValue - minValue) + minValue);
+    }
+
+    /**
+     * 获取随机值
+     * @param minValue
+     * @param maxValue
+     * @return (min, max]
+     */
+    public static getRealRandom(minValue: number, maxValue: number): number {
+        return Math.random() * (maxValue - minValue) + minValue;
+    }
+
+    public static sort(arr: any[], begin: number = 0, end: number = arr.length): Array<number> {
+        if (end <= begin)
+            return arr;
+        let i = begin;
+        let j = end;
+        let key = arr[begin].sort;
+        while (true) {
+            while (true) {
+                if (i == j) break;
+                if (arr[j].sort < key) {
+                    let temp = arr[j];
+                    arr[j] = arr[i];
+                    arr[i] = temp;
+                    break;
+                }
+                j--;
+            }
+            while (true) {
+                if (i == j) break;
+                if (arr[i].sort > key) {
+                    let temp = arr[i];
+                    arr[i] = arr[j];
+                    arr[j] = temp;
+                    break;
+                }
+                i++;
+            }
+            if (i == j)
+                break;
+        }
+        if (end - j > 1) {
+            arr = Tools.sort(arr, j + 1, end);
+        }
+        if (i - begin > 1) {
+            arr = Tools.sort(arr, begin, i);
+        }
+        return arr;
+    }
+
+    /**
+     * 快速排序导出信息:
+     * @param arr 需要进行快速排序的数组
+     * @returns {*[]|*}
+     */
+    public static quickExportSort(arr: ExportData[]) {
+        arr.sort(() => {
+            return 0.5 - Math.random()
+        })
+        if (CacheMgr.earlyExportTripPart.length > 0) {
+            let arr2 = []
+            for (let i = arr.length - 1; i >= 0; i--) {
+                if (this.judgeValueInArr(arr[i].appId, CacheMgr.earlyExportTripPart)) {
+                    arr2.push(Tools.deepClone(arr[i]))
+                    arr.splice(i, 1)
+                }
+            }
+            for (let i = 0; i < arr2.length; i++) {
+                arr.push(arr2[i])
+            }
+        }
+        return arr
+    }
+
+    /**
+     * 改变节点位置的 y 为 banner 位置的 y (骗点用)
+     * @param node
+     */
+    public static changeNodePosition(node: cc.Node) {
+        let banner = Game.Ins.banner;
+        node.y = banner.y + banner.height / 2;
+    }
+
+    /**
+     * 调整按钮位置到 banner上方
+     * @param button
+     */
+    public static setExportPos(button: cc.Node) {
+        let banner = Game.Ins.banner;
+        this.changeNodePosition(button);
+        button.y = button.y + banner.height / 2 + button.height / 2;
+    }
+
+
+    /**
+     * 骗点结束移动 按钮
+     * @param time
+     * @param button
+     */
+    public static setExportPos_Animation(time: number, button: cc.Node) {
+        let banner = Game.Ins.banner
+        this.changeNodePosition(button);
+        cc.tween(button)
+            .to(time, {y: button.y + banner.height / 2 + button.height / 2}, {easing: "smooth"})
+            .start();
+    }
+
+    /**
+     * 判断百分比
+     * @param per
+     */
+    public static checkPer(per: number) {
+        if (!per) {
+            return false;
+        }
+        return Tools.getRandomMax(100) <= per;
+    }
+
+    /**
+     * 游戏链接后台,资源加载, 初始化 gameBox
+     */
+    public static model_initModel(f: Function): number {
+        let functions: Function[] = [
+            () => {
+                let names = ["sub","homeView","gameView"]
+                LoadMgr.loadBundle(names).then(() => {
+                    f()
+                })
+            },
+            () => {
+                f();
+            },
+        ]
+
+        for (let i = 0; i < functions.length; i++) {
+            functions[i]();
+        }
+        return functions.length;
+    }
+
+    /**
+     *  播放视频, resolve 返回 true 为获得奖励, false 为未获得奖励
+     */
+    public static handleVideo() {
+        return new Promise((resolve, reject) => {
+            if (!Global.isVivo) {
+                resolve(true);
+                return
+            }
+            AudioMgr.backMusic(false) ;
+            QgRewardedAd.showRewardedVideo().then((res) => {
+                let boolean : boolean = res == 1 ;
+                AudioMgr.backMusic() ;
+                resolve(boolean);
+            })
+        })
+    }
+
+    /**
+     * 打开或关闭 碰撞系统功能
+     * @param isOpen 碰撞系统
+     * @param draw debug 绘制
+     * @param bounding 包围盒
+     */
+    public static getCollision(isOpen: boolean = true, draw: boolean = false, bounding: boolean = false) {
+        let Manager = cc.director.getCollisionManager();
+        Manager.enabled = isOpen;
+        Manager.enabledDebugDraw = draw;
+        Manager.enabledDrawBoundingBox = bounding;
+    }
+
+    /**
+     * 打开或关闭 物理系统
+     * @param isOpen
+     * @param draw
+     */
+    public static getPhysics(isOpen: boolean = true, draw: boolean = false) {
+        let Manager = cc.director.getPhysicsManager();
+        Manager.enabled = true;
+        if (draw) {
+            cc.director.getPhysicsManager().debugDrawFlags =
+                cc.PhysicsManager.DrawBits.e_aabbBit
+                |
+                cc.PhysicsManager.DrawBits.e_jointBit
+                |
+                cc.PhysicsManager.DrawBits.e_shapeBit
+            ;
+        }
+    }
+
+    /**
+     *  注册一组 touch 事件
+     * @param node
+     * @param start
+     * @param move
+     * @param end
+     * @param cancel
+     * @param target
+     * @param bool
+     */
+    public static onTouchAll(node: cc.Node, start: Function, move: Function, end: Function, cancel: Function, target: any, bool: boolean = true) {
+        if (node) {
+            if (bool) {
+                node.on(cc.Node.EventType.TOUCH_START, start, target);
+                node.on(cc.Node.EventType.TOUCH_MOVE, move, target);
+                node.on(cc.Node.EventType.TOUCH_END, end, target);
+                node.on(cc.Node.EventType.TOUCH_CANCEL, cancel, target);
+            } else {
+                node.off(cc.Node.EventType.TOUCH_START, start, target);
+                node.off(cc.Node.EventType.TOUCH_MOVE, move, target);
+                node.off(cc.Node.EventType.TOUCH_END, end, target);
+                node.off(cc.Node.EventType.TOUCH_CANCEL, cancel, target);
+            }
+        }
+    }
+
+    /**
+     * 获取节点所在父节点的下标
+     *  @param node
+     */
+    public static getChildrenIndex(node: cc.Node): number {
+        let parent = node.parent;
+        for (let i = 0; i < parent.children.length; i++) {
+            let value = parent.children[i];
+            if (node === value) {
+                return i;
+            }
+        }
+    }
+
+    /**
+     * 该位置是否在节点中
+     * @param point 位置
+     * @param node 节点
+     */
+    public static getPointInNode(point: cc.Vec2, node: cc.Node): boolean {
+        return node.getBoundingBoxToWorld().contains(point);
+    }
+
+    /**
+     * 获取比较奇怪的时间字符串 (特定的一天) 20210203
+     */
+    public static date_getTimeNum(date: Date) {
+        return date.getFullYear() * 10000 + (date.getMonth() + 1) * 100 + date.getDate()
+    }
+
+    /**
+     * 获取两个时间的时间差
+     * @param start1   比较靠后的时间
+     * @param start2   比较靠前的时间
+     * @param type     获取的时间差类型  0 day  1 hour 2 minuter 3 second
+     */
+    public static date_getTimeDifference(start1: Date | number, start2: Date | number, type: number): any {
+        if (isNumber(start1)) {
+            start1 = new Date(start1)
+        }
+        if (isNumber(start2)) {
+            start2 = new Date(start2)
+        }
+
+        if (start1 instanceof Date && start2 instanceof Date) {
+            let distance = start1.getTime() - start2.getTime(); //时间差秒
+            switch (type) {
+                case 0:
+                    return {
+                        distance: Math.floor(distance / (24 * 60 * 60 * 1000)),
+                        distance_real: distance,
+                    }
+                case 1 :
+                    return {
+                        distance: Math.floor(distance / (60 * 60 * 1000)),
+                        distance_real: distance,
+                    }
+                case 2 :
+                    return {
+                        distance: Math.floor(distance / (60 * 1000)),
+                        distance_real: distance,
+                    }
+                case 3  :
+                    return {
+                        distance: Math.floor(distance / (1000)),
+                        distance_real: distance,
+                    }
+            }
+        }
+    }
+
+    /**
+     * 获取当前主机地址
+     */
+    public static getHost(): string {
+        return JiuWuSDK.url.host;
+    }
+
+    /**
+     * 根据一个矩形 ,创建一个节点
+     */
+    public static getNodeForRect(rect: cc.Rect): cc.Node {
+        let node = new cc.Node();
+        node.width = rect.width;
+        node.height = rect.height;
+        node.setPosition(cc.v3(rect.center));
+        return node;
+    }
+
+    /**
+     * 获取一个节点四个点的位置 (未经旋转 这种操作)
+     * @param node
+     */
+    //获取一个节点四个点的位置 (未经旋转 这种操作)
+    public static getNodeFourPoint(node: cc.Node) {
+        let anchor = node.getAnchorPoint()
+        return {
+            left_down: cc.v2(node.position.x - anchor.x * node.width, node.position.y - anchor.y * node.height),
+            left_top: cc.v2(node.position.x - anchor.x * node.width, node.position.y + (1 - anchor.y) * node.height),
+            right_down: cc.v2(node.position.x + (1 - anchor.x) * node.width, node.position.y - anchor.y * node.height),
+            right_top: cc.v2(node.position.x + (1 - anchor.x) * node.width, node.position.y + (1 - anchor.y) * node.height)
+        }
+    }
+
+
+    //判断一个值是否在一个数组中
+    public static judgeValueInArr(value: any, arr: Array<any>) {
+        let flag = false
+        for (let i = 0; i < arr.length; i++) {
+            if (arr[i] === value) {
+                flag = true
+                break
+            }
+        }
+        return flag
+    }
+
+
+    //判断两个数组是否相交
+    public static judgeArraySame(arr1: number[], arr2: number[]) {
+        let flag = false
+        for (let i = 0; i < arr1.length; i++) {
+            for (let j = 0; j < arr2.length; j++) {
+                if (arr1[i] == arr2[j]) {
+                    flag = true
+                    return flag
+                }
+            }
+        }
+        return flag
+    }
+
+
+    //banner根据节点适配
+    public static getRealSize(node: cc.Node, resize_width = null, resize_height = null): {
+        width: number,
+        height: number,
+        left: number,
+        top: number
+    } {
+        //获取屏幕设计尺寸
+        let canvas = node.parent
+        let size = canvas.getContentSize()
+        let data = Tools.getNodeFourPoint(canvas)
+        let pc = data.left_top.sub(cc.v2(Tools.getNodeFourPoint(node).left_top))
+        let screen = cc.view.getFrameSize();
+        let scaleX = screen.width / size.width
+        let scaleY = screen.height / size.height
+
+        if (resize_width && resize_height) {
+            node.width = resize_width / scaleX
+            node.height = resize_height / scaleY
+        }
+        // console.log("scaleX", scaleX, "scaleY", scaleY)
+        return {
+            width: node.width * scaleX,
+            height: node.height * scaleY,
+            left: -pc.x * scaleX,
+            top: pc.y * scaleY,
+        }
+    }
+
+    /**
+     * 修改体力 , 如果体力不足 ,修改失败的话 ,会自动弹出体力不足框
+     * @param num 需要改动的体力
+     * @param callBack
+     */
+    public static changeStamina(num: number, callBack?: Function): boolean {
+        if (CacheMgr.stamina + num < 0) {
+            PanelMgr.INS.openPanel({
+                panel: ShortageView,
+                layer: Layer.gameLayer,
+                param: {
+                    type: "stamina",
+                    callBack: callBack,
+                    price: Math.abs(num),
+                }
+            })
+            return false;
+        } else {
+            if (callBack) {
+                callBack();
+            }
+        }
+        CacheMgr.stamina = CacheMgr.stamina + num;
+        return true;
+    }
+
+    /**
+     * 修改金币 , 如果金币不足 ,修改失败的话 ,会自动弹出金币不足框
+     * @param num
+     * @param callBack   成功回调 (包括领取金币成功)
+     */
+    public static changeGold(num: number, callBack?: Function): boolean {
+        if (CacheMgr.gold + num < 0) {
+            PanelMgr.INS.openPanel({
+                panel: ShortageView,
+                layer: Layer.gameLayer,
+                param: {
+                    type: "gold",
+                    callBack: callBack,
+                    price: Math.abs(num),
+                }
+            })
+            return false
+        } else {
+            if (callBack) {
+                callBack();
+            }
+        }
+        CacheMgr.gold = CacheMgr.gold + num
+        return true
+    }
+
+    /**
+     * 判断体力 , 如果体力不足 ,修改失败的话 ,会自动弹出体力不足框
+     * @param num 需要改动的体力
+     * @param callBack
+     */
+    public static judgeStamina(num: number, callBack?: Function): boolean {
+        if (CacheMgr.stamina + num < 0) {
+            PanelMgr.INS.openPanel({
+                panel: ShortageView,
+                layer: Layer.gameLayer,
+                param: {
+                    type: "stamina",
+                    callBack: callBack,
+                    price: 0,
+                }
+            })
+            return false;
+        } else {
+            if (callBack) {
+                callBack();
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 判断金币 , 如果金币不足 ,修改失败的话 ,会自动弹出金币不足框
+     * @param num
+     * @param callBack   成功回调 (包括领取金币成功)
+     */
+    public static judgeGold(num: number, callBack?: Function): boolean {
+        if (CacheMgr.gold + num < 0) {
+            PanelMgr.INS.openPanel({
+                panel: ShortageView,
+                layer: Layer.gameLayer,
+                param: {
+                    type: "gold",
+                    callBack: callBack,
+                    price: num,
+                }
+            })
+            return false
+        } else {
+            if (callBack) {
+                callBack();
+            }
+        }
+        return true
+    }
+
+    /**
+     * 已知圆心,半径,角度,求圆上的点坐标 (坐标需要自己转)
+     * @param center
+     * @param r
+     * @param angle
+     */
+    public static getCirclePoint(center: cc.Vec3, r: number, angle: number): cc.Vec3 {
+        return cc.v3(
+            center.x + r * Math.cos(angle * 3.14 / 180),
+            center.y + r * Math.sin(angle * 3.14 / 180)
+        )
+    }
+
+    public static handlerInters() {
+        return new Promise((resolve) => {
+            if (!Global.isVivo) {
+                resolve(true);
+                return
+            }
+            QgIntersAd.showInters();
+            resolve(true);
+        })
+    }
+
+    /**
+     * 判断原生广告显示
+     */
+    public static showNative(type, labelType, time) {
+        return new Promise((resolve) => {
+            if (QgNative.nativeMessage == null) {
+                QgNative.loadNative().then((res) => {
+                    if (res == false) {
+                        LogMgr.error("原生广告拉取失败......")
+                        resolve(false);
+                        return
+                    }
+                })
+            }
+            PanelMgr.INS.openPanel({
+                panel: NativeView,
+                layer: Layer.nativeLayer,
+                param: {
+                    type: type,
+                    labelType: labelType,
+                    time: time
+                }
+            })
+            resolve(true);
+        })
+    }
+}
+
+

+ 9 - 0
assets/Script/Common/Tools.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "b484dca5-bdb1-4433-aac4-7081fb124ce9",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Common/manage.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "fbba0956-983b-472a-b808-25c0d8c7a1e0",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 408 - 0
assets/Script/Common/manage/ActionMgr.ts

@@ -0,0 +1,408 @@
+/**
+ * 动画效果类
+ */
+
+import easeInOut = cc.easeInOut;
+import GameLog from "./GameLogMgr";
+import Tween = cc.Tween;
+import tween = cc.tween;
+
+export default class ActionMgr {
+
+    //疯狂抖动手指
+    public static shakeHand(node: cc.Node) {
+        tween(node)
+            .by(0.05, {y: 20})
+            .by(0.05, {y: -20})
+            .union()
+            .repeatForever()
+            .start()
+    }
+
+
+    public static scaleNode(node: cc.Node, scale: number, time = 0.5) {
+        try {
+            cc.tween(node)
+                .to(0, {scale: scale, y: -node.height * (1 - scale)})
+                .to(time, {scale: 1, y: 0})
+                .start()
+        } catch (e) {
+            node.scale = 1;
+            node.y = 0;
+            GameLog.log('shake动画异常', e);
+        }
+    }
+
+    public static moveUpDownForever(node: cc.Node, runTime = 0.2, diff = 10) {
+        cc.tween(node).repeatForever(
+            cc.sequence(
+                cc.moveBy(runTime, new cc.Vec2(0, diff)),
+                cc.moveBy(runTime, new cc.Vec2(0, -diff)),
+            )
+        ).start();
+    }
+
+    /**
+     * 旋转节点
+     * @param node
+     * @param duration
+     */
+    public static rotate(node: cc.Node, duration = 3) {
+        try {
+            cc.tween(node).repeatForever(
+                cc.sequence(
+                    cc.rotateTo(duration, 180),
+                    cc.rotateTo(duration, 360),
+                )
+            ).start();
+
+        } catch (e) {
+            GameLog.error('shakeNode异常', e, node);
+
+        }
+    }
+
+
+    /**
+     * 放大缩小 node
+     * @param node
+     * @param timeRun
+     * @param timeStop
+     * @param scale
+     * @param count
+     * @param endScale
+     * @constructor
+     */
+    public static scaleStop(node: cc.Node, timeRun = 0.1, timeStop = 10, scale = 0.3, count = 1, endScale = 1) {
+        try {
+            if (!node) {
+                return;
+            }
+            node.scale = endScale;
+            cc.tween(node)
+                .repeatForever(
+                    cc.tween()
+                        .repeat(count,
+                            cc.tween()
+                                .to(timeRun, {scale: 1 + scale}, {easing: "smooth"})
+                                .to(timeRun, {scale: endScale}, {easing: "smooth"})
+                        )
+                        .to(timeRun, {angle: 0})
+                        .delay(timeStop)
+                )
+                .start()
+
+
+        } catch (e) {
+            GameLog.error('shakeNode异常', e, node);
+
+        }
+    }
+
+    public static shakeNode(node: cc.Node, timeRun = 0.3, dstAngle: number = 10, count: number = 5) {
+        cc.tween(node)
+            .repeat(count,
+                cc.tween()
+                    .to(timeRun, {angle: -dstAngle})
+                    .to(timeRun, {angle: dstAngle})
+            ).to(timeRun, {angle: 0}).start();
+    }
+
+    /**
+     * 摇动node
+     * @param node
+     * @param duration
+     * @param dstAngle
+     * @constructor
+     */
+    public static shakeNodeForever(node: cc.Node, duration = 4, dstAngle = 10) {
+        try {
+            cc.tween(node).repeatForever(
+                cc.sequence(
+                    cc.rotateTo(duration, -dstAngle),
+                    cc.rotateTo(duration, dstAngle),
+                )
+            ).start();
+
+        } catch (e) {
+            GameLog.error('shakeNode异常', e, node);
+
+        }
+    }
+
+    /**
+     * node晃动后停止,一段时间后继续晃动
+     * @param node 动作的节点
+     * @param timeRun 单次晃动到左右任一边的时间
+     * @param timeStop 停止的时间
+     * @param dstAngle 晃动的角度
+     * @param shakeCount 晃动的次数
+     */
+    public static shakeStop(node: cc.Node, timeRun = 0.1, timeStop = 10, dstAngle = 10, shakeCount = 5) {
+        try {
+            cc.tween(node)
+                .repeatForever(
+                    cc.tween()
+                        .delay(timeStop)
+                        .repeat(shakeCount,
+                            cc.tween()
+                                .to(timeRun, {angle: -dstAngle})
+                                .to(timeRun, {angle: dstAngle})
+                        )
+                        .to(timeRun, {angle: 0})
+                )
+                .start()
+
+        } catch (e) {
+
+            GameLog.error('shakeStop异常', e, node);
+        }
+    }
+
+    public static scaleMove(node: cc.Node, delayTime: number = 3, repeatCount: number = 2,) {
+        cc.tween(node)
+            .repeatForever(
+                cc.tween()
+                    .delay(delayTime)
+                    .repeat(repeatCount,
+                        cc.tween()
+                            .to(0.3, {scale: 1.1})
+                            .to(0, {scale: 1})
+                            .to(0.3, {scale: 1.2})
+                            .to(0, {scale: 1})
+                    )
+                // .repeat(repeatCount,
+                //     cc.tween()
+                // )
+            )
+            .start();
+    }
+
+    /**
+     * 界面缩放进入
+     * @param node
+     * @param duration
+     */
+    public static moveBigIn(node: cc.Node, duration = 0.3) {
+        if (!node) {
+            return false;
+        }
+        try {
+            node.scale = 2;
+            cc.tween(node)
+                .to(duration, {scale: 1}, easeInOut(1))
+                .start();
+
+        } catch (e) {
+            node.scale = 1;
+            GameLog.error('moveIn 异常', e, node);
+
+        }
+    }
+
+
+    /**
+     * 界面缩放进入
+     * @param node
+     * @param duration
+     * @param beginSale
+     */
+    public static moveIn(node: cc.Node, duration: number = 0.4, beginSale: number = 0) {
+        node.scale = beginSale;
+        cc.tween(node)
+            .to(duration, {scale: 1}, {easing: 'backOut'})
+            .start();
+    }
+
+    /**
+     * 界面从上推下
+     */
+    public static moveTop(node: cc.Node, time: number = 0.4) {
+        node.y = node.height / 2;
+        cc.tween(node)
+            .to(time,{y: 0}, {easing: "smooth"})
+            .start()
+    }
+
+    /**
+     * 界面缩放退出
+     * @param node
+     * @param duration
+     * @param endScale
+     */
+    public static moveOut(node: cc.Node, duration = 0.4, endScale = 0) {
+        if (!node) {
+            return false;
+        }
+        try {
+            node.scale = 1;
+            cc.tween(node)
+                .to(duration, {scale: endScale})
+                .start();
+        } catch (e) {
+            node.scale = 0;
+            GameLog.error('moveOut 异常', e, node);
+        }
+    }
+
+    public static TWEEN_FROM_SIDE = {
+        TOP: 1,
+        DOWN: 2,
+        LEFT: 3,
+        RIGHT: 4
+    };
+
+    private static _moveSideNodePosition = {};
+
+    /**
+     * 从画布外进入, 不能重复调用
+     * @param node 动作的节点
+     * @param beginSide 界面进入的边
+     * @param time 动作进行的时间/s
+     * @param delay 动作延迟进行的时间/s
+     */
+    public static moveInSide(node: cc.Node, beginSide = this.TWEEN_FROM_SIDE.TOP, time = 0.5, delay = 0) {
+        if (!node) {
+            return false;
+        }
+        if (!this._moveSideNodePosition.hasOwnProperty(node.uuid)) {
+            this._moveSideNodePosition[node.uuid] = node.position.clone();
+        }
+        try {
+            let resultPos = this._getSideResultPos(node, beginSide);
+            node.position = resultPos;
+            GameLog.log("节点", node.name, "界面外坐标为:", resultPos);
+            cc.tween(node)
+                .delay(delay)
+                .to(time, {position: this._moveSideNodePosition[node.uuid].clone()}, {easing: 'quartIn'})
+                .start();
+        } catch (e) {
+            node.position = this._moveSideNodePosition[node.uuid].clone();
+            GameLog.log("move In Side 异常", e, node);
+        }
+
+    }
+
+    /**
+     * 移出画布外, 不能重复调用
+     * @param node 动作的节点
+     * @param endSide 界面移出的边
+     * @param time 动作进行的时间/s
+     */
+    public static moveOutSide(node: cc.Node, endSide = this.TWEEN_FROM_SIDE.TOP, time = 0.5) {
+        if (!node) {
+            return false;
+        }
+        if (!this._moveSideNodePosition.hasOwnProperty(node.uuid)) {
+            this._moveSideNodePosition[node.uuid] = node.position;
+        }
+        try {
+            let resultPos = this._getSideResultPos(node, endSide);
+            cc.tween(node)
+                .to(time, {position: resultPos}, {easing: 'quartIn'})
+                .call(() => {
+                    node.position = this._moveSideNodePosition[node.uuid].clone();
+                    GameLog.log('end move out side', node.position);
+                })
+                .start();
+        } catch (e) {
+            node.position = this._moveSideNodePosition[node.uuid].clone();
+            GameLog.log("move Out Side 异常", e, node);
+        }
+
+    }
+
+    private static _getSideResultPos(node: cc.Node, side) {
+        //获取屏幕尺寸
+        let winSize = cc.winSize;
+        let windowHeight = winSize.height;
+        let windowWidth = winSize.width;
+        GameLog.log("屏幕尺寸大小为:", windowHeight, windowWidth);
+        //根据节点移动方向获取坐标
+        let pos;
+        switch (side) {
+            case ActionMgr.TWEEN_FROM_SIDE.TOP:
+                pos = new cc.Vec2(node.x, windowHeight + node.height);
+                break;
+            case ActionMgr.TWEEN_FROM_SIDE.DOWN:
+                pos = new cc.Vec2(node.x, -windowHeight - node.height);
+                break;
+            case ActionMgr.TWEEN_FROM_SIDE.LEFT:
+                pos = new cc.Vec2(-windowWidth - node.width, node.y);
+                break;
+            case ActionMgr.TWEEN_FROM_SIDE.RIGHT:
+                pos = new cc.Vec2(windowWidth + node.width, node.y);
+                break;
+        }
+        return pos;
+    }
+
+    /**
+     * 左右移动
+     * @param node 运动的节点
+     * @param direction 运动的方向
+     * @param disMove 运动的距离
+     * @param timeMove 运动的时间/s
+     */
+    public static moveLeftRight(node: cc.Node, direction, disMove: number, timeMove: number) {
+        try {
+            let lessPos;
+            let morePos;
+            switch (direction) {
+                case ActionMgr.TWEEN_FROM_SIDE.LEFT:
+                case ActionMgr.TWEEN_FROM_SIDE.RIGHT:
+                    lessPos = new cc.Vec2(node.x - disMove, node.y);
+                    morePos = new cc.Vec2(node.x + disMove, node.y);
+                    break;
+                case ActionMgr.TWEEN_FROM_SIDE.TOP:
+                case ActionMgr.TWEEN_FROM_SIDE.DOWN:
+                    lessPos = new cc.Vec2(node.x, node.y - disMove);
+                    morePos = new cc.Vec2(node.x, node.y + disMove);
+                    break;
+            }
+            cc.tween(node).repeatForever(
+                cc.sequence(
+                    cc.moveTo(timeMove, lessPos),
+                    cc.moveTo(timeMove, morePos)
+                )
+            ).start();
+
+        } catch (e) {
+            GameLog.error('moveLeftRight异常', e, node);
+        }
+    }
+
+    public static showGradually(node: cc.Node, duration = 1, delay = 0, endOpacity = 255, starOpacity = 0) {
+        try {
+            cc.tween(node)
+                .call(() => {
+                    node.opacity = starOpacity;
+                    node.active = true;
+                })
+                .delay(delay)
+                .to(duration, {opacity: endOpacity})
+                .start()
+        } catch (e) {
+            node.opacity = endOpacity;
+            GameLog.error('showGradually异常', e, node);
+        }
+    }
+
+    public static hideGradually(node: cc.Node, duration = 1, delay = 0, endOpacity = 50) {
+        try {
+            node.active = true;
+            cc.tween(node)
+                .delay(delay)
+                .to(duration, {opacity: endOpacity}, {easing: 'quartIn'})
+                .call(() => {
+                    node.active = false;
+                    node.opacity = 255;
+                })
+                .start()
+
+        } catch (e) {
+            node.opacity = endOpacity;
+            GameLog.error('showGradually异常', e, node);
+        }
+    }
+}

+ 9 - 0
assets/Script/Common/manage/ActionMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "6f8c8ba8-14d2-49cc-b299-91d87a7a7f59",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Common/manage/Api.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "e911b0f7-6501-4bc3-85f8-5fca0668b62a",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 199 - 0
assets/Script/Common/manage/Api/QgApi.ts

@@ -0,0 +1,199 @@
+import fly from "flyio";
+import QgRewardedAd from "./QgRewardedAd";
+import QgIntersAd from "./QgIntersAd";
+import QgBanner from "./QgBanner";
+import Global from "../../Global";
+import QgNative from "./QgNative";
+import LogMgr from "../../LogMgr";
+
+export default class QgApi {
+
+
+    public static createAdv () {
+        if (!Global.isVivo)return ;
+        this.createVideo() ;
+        this.createInters() ;
+        this.createNative() ;
+    }
+
+    public static createBanner () {
+        if (!Global.isVivo)return ;
+        this.createBannerAd() ;
+    }
+
+    private static createVideo() {
+        QgRewardedAd.createRewardedVideo().then(()=>{
+            QgRewardedAd.loadRewardedVideo().then()
+        }).catch(()=>{
+            setTimeout(()=>{
+                if (!QgRewardedAd.isLoad_Rewarded) {
+                    this.createVideo() ;
+                }
+            },5000)
+        })
+    }
+
+    private static createInters() {
+        QgIntersAd.createInters().then().catch(()=>{
+            setTimeout(()=>{
+                if (!QgIntersAd.isLoad_Inters) {
+                    this.createInters() ;
+                }
+            },5000)
+        })
+    }
+
+    private static createNative() {
+        QgNative.createNative().then(()=>{
+            QgNative.loadNative().then() ;
+        }).catch(()=>{
+            setTimeout(()=>{
+                if (!QgNative.isLoad_Native) {
+                    this.createNative() ;
+                }
+            },5000)
+        })
+    }
+
+    private static createBannerAd() {
+        QgBanner.createBanner().then(()=>{
+            if (Global.config.gameConfig.bannerShow == 1) {
+                QgBanner.showBanner() ;
+            }
+        }).catch(()=>{
+            setTimeout(()=>{
+                if (!QgBanner.isLoad) {
+                    this.createBannerAd() ;
+                }
+            },5000)
+        })
+    }
+
+    /**
+     * 发起HTTPS网络请求
+     */
+    public static sponsorHttps(options) {
+        if (!options.hasOwnProperty("url")) {
+            console.warn("request param  url is  null")
+            return
+        }
+        let url = options.url
+        let data: any = null
+        let param: any = {}
+        if (!options.hasOwnProperty("method")) {
+            param.method = "GET"
+        } else {
+            param.method = options.method
+        }
+
+        if (options.hasOwnProperty("data")) {
+            data = options.data
+        }
+
+        if (options.hasOwnProperty("timeOut")) {
+            param.timeout = options.timeout
+        }
+
+        if (options.hasOwnProperty("header")) {
+            param.headers = options.header
+        }
+        param.pareseJson = true
+
+        fly.request(url, data, param).then(data => {
+            if (options.hasOwnProperty("success")) {
+                options.success(data)
+            }
+        }).catch(e => {
+            if (options.hasOwnProperty("fail")) {
+                options.fail(data)
+            }
+        })
+
+    }
+
+    /**
+     * 登录
+     */
+    public static login() {
+        return new Promise((resolve, reject) => {
+            // @ts-ignore
+            if (qg.getSystemInfoSync().platformVersionCode >= 1063) {
+                // @ts-ignore
+                window.qg.login().then((res) => {
+                    if (res.data.token) {
+                        console.log('登录成功!!', res.data.token)
+                        resolve(res.data.token);
+                    }
+                }, (err) => {
+                    resolve(false);
+                    console.error('登录失败' + JSON.stringify(err));
+                })
+            } else {
+                resolve(false);
+                console.error('版本号过低,无法登录')
+            }
+        })
+    }
+
+    /**
+     * 分享
+     */
+    public static share() {
+        // @ts-ignore
+        qg.share()
+    }
+
+    /**
+     * 判断是否已创建桌面图标
+     */
+    public static judgeShortIcon () {
+        return new Promise((resolve,reject)=>{
+            // @ts-ignore
+            qg.hasShortcutInstalled({
+                success : (res)=>{
+                    if (res) {
+                        resolve(false) ;
+                    }else {
+                        resolve(true) ;
+                    }
+                },
+                fail : (err)=>{
+                    LogMgr.log(err) ;
+                    reject(false) ;
+                }
+            })
+        })
+    }
+
+    /**
+     * 添加桌面图标
+     */
+    public static addShortcutIcon () {
+        return new Promise((resolve)=>{
+            this.judgeShortIcon().then((res)=>{
+                if (res) {
+                    // @ts-ignore
+                    qg.installShortcut({
+                        message : '创建桌面游戏图标,快捷进入游戏!',
+                        success : ()=>{
+                            LogMgr.log('创建成功') ;
+                            resolve(true) ;
+                        },
+                        fail : ()=>{
+                            LogMgr.error('创建失败') ;
+                            resolve(false) ;
+                        }
+                    })
+                }else {
+                    resolve(false) ;
+                    return
+                }
+            }).catch(()=>{
+                resolve(false) ;
+                return
+            })
+        })
+    }
+
+
+}

+ 9 - 0
assets/Script/Common/manage/Api/QgApi.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "cdd4dbf8-e597-4217-b591-a5c1bdafff78",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 147 - 0
assets/Script/Common/manage/Api/QgBanner.ts

@@ -0,0 +1,147 @@
+import Game from "../../../Scene/Game";
+import Tools from "../../Tools";
+import Global from "../../Global";
+import LogMgr from "../../LogMgr";
+
+export default class QgBanner {
+
+    public static isLoad: boolean = false; //加载状态
+
+    private static bannerAd: any; //banner对象
+
+    public static isShow: boolean = false; //显示状态
+
+    /**
+     * 创建banner
+     */
+    public static createBanner() {
+        return new Promise((resolve, reject) => {
+
+            if (!Global.isVivo) {
+                LogMgr.error('当前非vivo平台,无法创建Banner');
+                reject(false);
+                return
+            }
+
+            let unitId = Tools.getRandomByArray(Global.config.advertisingConfig.bannerAdId);
+            if (!unitId) {
+                LogMgr.error('BannerId获取失败:' + unitId);
+                reject(false);
+                return
+            }
+
+            let banner_exm = Game.Ins.banner
+            let size = Tools.getRealSize(banner_exm)
+            let refreshTime = 30 ;
+
+            if (Global.config.bannerRefreshTime >= 30) {
+                refreshTime = Global.config.bannerRefreshTime ;
+            }
+
+            let bannerParam = {
+                adUnitId: unitId,
+                style: {
+                    left: size.left,
+                    top: size.top,
+                },
+                adIntervals: refreshTime,
+            };
+
+            // @ts-ignore
+            this.bannerAd = qg.createBannerAd(bannerParam);
+
+            this.bannerAd.onLoad((res) => {
+                this.isLoad = true;
+                LogMgr.log('Banner广告加载完成-onload触发', JSON.stringify(res));
+                resolve(true);
+            })
+
+            this.bannerAd.onClose(()=>{
+                LogMgr.log('Banner关闭......')
+            })
+
+            this.bannerAd.onError((err) => {
+                LogMgr.error('Banner错误:err:', err);
+                reject(false);
+            })
+
+        })
+    }
+
+    /**
+     *展示Banner
+     */
+    public static showBanner() {
+
+        if (!this.isLoad) {
+            this.createBanner().then();
+            LogMgr.error('Banner未创建或未加载,无法显示')
+            return
+        }
+
+        if (this.isShow) {
+            LogMgr.error('Banner已显示,无法重复显示') ;
+            return
+        }
+
+        this.bannerAd.show().then(() => {
+            this.isShow = true;
+        }).catch((err) => {
+            LogMgr.error('Banner显示错误:', err);
+        })
+
+    }
+
+    /**
+     * 隐藏Banner
+     */
+    public static hideBanner() {
+        if (!this.isLoad) {
+            LogMgr.error('Banner未创建或未加载,无法隐藏')
+            return
+        }
+
+        if (!this.isShow) {
+            LogMgr.error('Banner未显示,无需隐藏')
+            return
+        }
+
+        this.bannerAd.hide();
+        this.isShow = false;
+    }
+
+    /**
+     * 销毁Banner实例
+     */
+    public static destroyBanner() {
+        return new Promise((resolve) => {
+            if (!this.bannerAd) {
+                LogMgr.error('Banner未创建>>>无法destroy()');
+                resolve(false);
+                return
+            }
+
+            this.bannerAd.destroy();
+            this.isLoad = false;
+            this.isShow = false;
+            resolve(true);
+        })
+    }
+
+    /**
+     * 刷新Banner
+     */
+    public static cutBanner() {
+        return new Promise((resolve) => {
+            this.destroyBanner().then((res) => {
+                if (res) {
+                    this.createBanner().then(()=>{
+                        this.showBanner();
+                    });
+                }
+                resolve(true);
+            })
+        })
+    }
+
+}

+ 9 - 0
assets/Script/Common/manage/Api/QgBanner.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "c28cd91b-de40-4222-b840-8244912909f7",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 67 - 0
assets/Script/Common/manage/Api/QgIntersAd.ts

@@ -0,0 +1,67 @@
+import Tools from "../../Tools";
+import Global from "../../Global";
+import LogMgr from "../../LogMgr";
+
+export default class QgIntersAd {
+
+    private static initInterstitialAd: any; //插屏对象
+    public static isLoad_Inters: boolean = false;
+
+    /**
+     * 创建插屏
+     */
+    public static createInters() {
+        return new Promise((resolve, reject) => {
+
+            if (!Global.isVivo) {
+                LogMgr.error('当前非vivo平台,无法创建插屏');
+                reject(false) ;
+                return
+            }
+
+            let unitId = Tools.getRandomByArray(Global.config.advertisingConfig.interstitialAdId);
+            if (!unitId) {
+                LogMgr.error('插屏Id获取失败:' + unitId)
+                reject(false) ;
+                return
+            }
+
+            // @ts-ignore
+            this.initInterstitialAd = window.qg.createInterstitialAd({adUnitId: unitId});
+
+            this.initInterstitialAd.onError((err) => { //监听插屏错误
+                LogMgr.error('插屏错误onError:', err);
+            })
+
+            this.initInterstitialAd.onLoad((res) => {
+                this.isLoad_Inters = true;
+                LogMgr.log('插屏广告加载完成-onload触发', JSON.stringify(res));
+            })
+
+            this.initInterstitialAd.onClose(() =>{
+                this.isLoad_Inters = false;
+                LogMgr.log('插屏关闭>>>>>>') ;
+                this.createInters().then() ;
+            })
+
+            resolve(true)
+        })
+    }
+
+    /**
+     * 展示插屏
+     */
+    public static showInters() {
+        if (!this.isLoad_Inters || !this.initInterstitialAd) {
+            LogMgr.error('插屏加载中......',this.isLoad_Inters,'rewardedAd:',this.initInterstitialAd);
+            this.createInters().then().catch() ;
+            return
+        }
+
+        this.initInterstitialAd.show().then(() => {
+
+        }).catch((err) => {
+            LogMgr.error('插屏广告展示失败', JSON.stringify(err));
+        })
+    }
+}

+ 9 - 0
assets/Script/Common/manage/Api/QgIntersAd.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "b70ea19f-acb6-4194-9f50-9f8dfef5f2ab",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 107 - 0
assets/Script/Common/manage/Api/QgNative.ts

@@ -0,0 +1,107 @@
+import Tools from "../../Tools";
+import Global from "../../Global";
+import LogMgr from "../../LogMgr";
+
+export default class QgNative {
+
+    private static nativeAd: any; //原生广告对象
+    public static isLoad_Native: boolean = false;
+    private static nativeResolve = null ;
+    public static nativeMessage : any = null ;
+
+
+    /**
+     * 创建原生广告
+     */
+    public static createNative () {
+        return new Promise((resolve, reject) => {
+
+            if (!Global.isVivo) {
+                LogMgr.error('当前非vivo平台,无法创建原生广告');
+                reject(false) ;
+                return
+            }
+
+            let unitId = Tools.getRandomByArray(Global.config.advertisingConfig.nativeAdId);
+            if (!unitId) {
+                LogMgr.error('原生ID获取失败:' + unitId);
+                reject(false) ;
+                return
+            }
+
+            // @ts-ignore
+            this.nativeAd = qg.createNativeAd({posId : unitId});
+
+            this.nativeAd.onLoad((res)=>{
+                if (res && res.adList) {
+                    LogMgr.log('原生广告拉取成功>>>>>>',res.adList) ;
+                    this.nativeMessage = res.adList[0] ;
+                    this.nativeResolve(res.adList[0]) ;
+                    this.isLoad_Native = true ;
+                }
+                this.nativeResolve = null ;
+            })
+
+            resolve(true);
+        })
+    }
+
+    /**
+     * 加载原生广告
+     */
+    public static loadNative () {
+        return new Promise((resolve)=>{
+            this.nativeResolve = resolve ;
+            if (!this.nativeAd) {
+                LogMgr.error('原生广告未创建,无法加载......')
+                this.createNative().then(()=>{}).catch() ;
+                this.nativeResolve(false) ;
+                this.nativeResolve = null ;
+                return
+            }
+
+            if (this.nativeMessage != null) {
+                this.nativeResolve(this.nativeMessage) ;
+                this.nativeResolve = null ;
+            }
+
+            this.nativeAd.load().then(()=>{
+
+            }).catch(()=>{
+                this.nativeResolve(false) ;
+            }) ;
+        })
+    }
+
+    /**
+     * 上报原生广告曝光
+     */
+    public static repAdShow (adId) {
+        if (!this.nativeAd) return ;
+        LogMgr.log('上报用户曝光>>>>>>')
+        this.nativeAd.reportAdShow({
+            adId: adId
+        }) ;
+    }
+
+    /**
+     * 上报原生广告点击
+     */
+    public static repAdClick (adId) {
+        if (!this.nativeAd) return ;
+        LogMgr.log('上报用户点击>>>>>>')
+        this.nativeAd.reportAdClick({
+            adId: adId
+        })
+    }
+
+    /**
+     * 重新拉去广告信息
+     */
+    public static anewLoad () {
+        this.nativeMessage = null ;
+        this.isLoad_Native = false ;
+        this.loadNative().then() ;
+    }
+
+}

+ 9 - 0
assets/Script/Common/manage/Api/QgNative.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "a17f9c2b-d538-49f8-8e8c-a51cb56dd6f2",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 95 - 0
assets/Script/Common/manage/Api/QgRewardedAd.ts

@@ -0,0 +1,95 @@
+import Tools from "../../Tools";
+import Global from "../../Global";
+import LogMgr from "../../LogMgr";
+
+export default class QgRewardedAd {
+
+    private static rewardedAd: any; //视频对象
+    public static isLoad_Rewarded: boolean = false;
+    private static rewardedVideoResolve = null; //视频状态返回 1 : 播放完成, 2 : 播放错误, 3 : 播放中途关闭
+
+    public static createRewardedVideo() {
+        return new Promise((resolve, reject) => {
+
+            if (!Global.isVivo) {
+                LogMgr.error('当前非vivo平台,无法创建视频') ;
+                reject(false);
+                return
+            }
+
+            let unitId = Tools.getRandomByArray(Global.config.advertisingConfig.rewardedVideoAdId);
+            if (!unitId) {
+                LogMgr.error('视频ID获取失败:' + unitId)
+                reject(false);
+                return
+            }
+
+            // @ts-ignore
+            this.rewardedAd = window.qg.createRewardedVideoAd({posId: unitId});
+
+            this.rewardedAd.onError(err => {
+                LogMgr.error("激励视频广告错误", err);
+                this.rewardedVideoResolve(2);
+                this.rewardedVideoResolve = null;
+            });
+
+            this.rewardedAd.onClose((isEnded) => { //开启关闭监听
+                if (isEnded.isEnded) {
+                    this.rewardedVideoResolve(1); //播放完成
+                } else {
+                    this.rewardedVideoResolve(3); //中途关闭
+                }
+                this.isLoad_Rewarded = false;
+                this.rewardedVideoResolve = null;
+                this.loadRewardedVideo().then() ;
+            })
+
+            this.rewardedAd.onLoad((res)=> {
+                this.isLoad_Rewarded = true;
+                LogMgr.log('激励视频广告加载完成-onload触发', JSON.stringify(res));
+            })
+
+            resolve(true);
+        })
+    }
+
+    /**
+     * 加载视频
+     */
+    public static loadRewardedVideo() {
+        return new Promise((resolve, reject) => {
+            if (!this.rewardedAd) {
+                LogMgr.error('视频未创建>>>无法load()')
+                this.createRewardedVideo().then()
+                reject(false)
+                return
+            }
+            this.rewardedAd.load().then(() => {
+                resolve(true);
+            }, (error) => {
+                LogMgr.error('视频加载失败:' + error);
+                reject(false) ;
+            });
+        })
+    }
+
+    /**
+     * show视频
+     */
+    public static showRewardedVideo() {
+        return new Promise((resolve) => {
+            this.rewardedVideoResolve = resolve;
+            if (!this.isLoad_Rewarded) {
+                this.rewardedVideoResolve(2);
+                this.loadRewardedVideo().then() ;
+                LogMgr.error('视频加载中......');
+                return
+            }
+            this.rewardedAd.show().then(() => {
+
+            }).catch((err) => {
+                LogMgr.error('激励视频广告展示失败', JSON.stringify(err));
+            })
+        })
+    }
+}

+ 9 - 0
assets/Script/Common/manage/Api/QgRewardedAd.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "358ca324-b651-47cf-bc2d-538ebbde9f6f",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 56 - 0
assets/Script/Common/manage/AudioMgr.ts

@@ -0,0 +1,56 @@
+/**
+ * 音乐管理器
+ */
+import Global from "../Global";
+import GameLog from "./GameLogMgr";
+import CacheMgr from "./CacheMgr";
+import LoadMgr from "./LoadMgr";
+
+const {ccclass} = cc._decorator;
+
+@ccclass
+export default class AudioMgr {
+
+    /**
+     * @param isStop
+     */
+    public static backMusic(isStop = true) {
+        if (CacheMgr.setting.setting.music === 0) {
+            cc.audioEngine.stopMusic();
+        } else if (!isStop) {
+            cc.audioEngine.stopMusic();
+        } else if (!cc.audioEngine.isMusicPlaying()) {
+            LoadMgr.load_AudioClip("bg").then((audio: cc.AudioClip) => {
+                cc.audioEngine.playMusic(audio, true);
+                cc.audioEngine.setMusicVolume(CacheMgr.setting.setting.music);
+            });
+        }
+    }
+
+    public static play(url: string, max: number = 1, loop: boolean = false) {
+        return new Promise((resolve, reject) => {
+            if (CacheMgr.setting.setting.audio === 0) {
+                GameLog.warn(" 当前音量静音 ");
+                resolve(false);
+            }
+
+            LoadMgr.load_AudioClip(url).then((audio: cc.AudioClip) => {
+                let id: number = 0;
+                cc.audioEngine.setEffectsVolume(max * CacheMgr.setting.setting.audio);
+                id = cc.audioEngine.playEffect(audio, loop)
+                resolve(id);
+            })
+
+            // Global.bundleList.audio.load(url, cc.AudioClip, (err: Error, audio: cc.AudioClip) => {
+            //     if (err) {
+            //         GameLog.error(' 音效播放错误 ', url);
+            //         reject(false);
+            //     }
+            //     let id: number = 0;
+            //     cc.audioEngine.setEffectsVolume(max * CacheMgr.setting.setting.audio);
+            //     id = cc.audioEngine.playEffect(audio, loop)
+            //     resolve(id);
+            // });
+        });
+    }
+}

+ 9 - 0
assets/Script/Common/manage/AudioMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "d1f55531-f9bc-4a04-be7c-50fabf197b21",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 299 - 0
assets/Script/Common/manage/CacheMgr.ts

@@ -0,0 +1,299 @@
+import JiuWuSDK from "../../SDK/JiuWuSDK";
+import Global from "../Global";
+import Tools from "../Tools";
+
+class CachesMgr {
+
+
+    constructor() {
+        let string = Object.keys(this)
+        for (let i = 0; i < string.length; i++) {
+            if (string[i][0] != "_") {
+                continue
+            }
+            this.getData(string[i])
+        }
+    }
+
+    private _userId: number = 0;
+    private _checkpoint: number = 0;  //关卡
+    private _gold: number = 0; //金币
+    private _diamond: number = 0; //钻石
+    private _stamina: number = 20;
+
+    private _user_code: string = "";
+    private _openId: string = "";
+
+    private _lastTimeLogin: number = 0;
+    private _hit: any[] = [] //提示字符串
+    private _userInfo: any = null;
+    private _newUser: boolean = false;
+
+    private _nowCheckPoint: number = -1;
+
+    private _isNeedHint: boolean = true;
+    private _isAuth: boolean = false;   // 玩家是否授权
+    private _setting: CustomData = {
+        signTime: 0,
+        hammerNum: 0,
+        spriteNum: 0,
+        lastSignNum: 0,
+        signNum: -1,
+        hintNum: 5,
+        setting: {
+            music: 1,
+            audio: 1,
+            vibrate: 1,
+        }
+    }
+
+    private _earlyExportTripPart: string [] = []
+    private _earlyExport: string [] = []
+    private _exportTime: number = 0
+
+
+    get earlyExportTripPart(): string[] {
+        return this._earlyExportTripPart;
+    }
+
+    set earlyExportTripPart(value: string[]) {
+        this.saveData("_earlyExportTripPart", value)
+        this._earlyExportTripPart = value;
+    }
+
+    get earlyExport(): string[] {
+        return this._earlyExport;
+    }
+
+    set earlyExport(value: string[]) {
+        this.saveData("_earlyExport", value)
+        this._earlyExport = value;
+    }
+
+    get exportTime(): number {
+        return this._exportTime;
+    }
+
+    set exportTime(value: number) {
+        this.saveData("_exportTime", value)
+        this._exportTime = value;
+    }
+
+    get isNeedHint(): boolean {
+        return this._isNeedHint;
+    }
+
+    set isNeedHint(value: boolean) {
+        this._isNeedHint = value;
+        this.saveData("_isNeedHint", value, false);
+    }
+
+    get isAuth(): boolean {
+        return this._isAuth;
+    }
+
+    set isAuth(value: boolean) {
+        this.saveData("_isAuth", value, false);
+        this._isAuth = value;
+    }
+
+    get userId(): number {
+        return this._userId;
+    }
+
+    set userId(value: number) {
+        this.saveData("_userId", value, false);
+        this._userId = value;
+    }
+
+    get setting(): CustomData {
+        return this._setting;
+    }
+
+    set setting(value: CustomData) {
+        this.saveData("_setting", value)
+        this._setting = value;
+    }
+
+    get userInfo(): any {
+        return this._userInfo;
+    }
+
+    set userInfo(value: any) {
+        this.saveData("_userInfo", value, false)
+        this._userInfo = value;
+    }
+
+    get newUser(): boolean {
+        return this._newUser;
+    }
+
+    set newUser(value: boolean) {
+        this.saveData("_newUser", value, false)
+        this._newUser = value;
+    }
+
+    get hit(): any[] {
+        return this._hit;
+    }
+
+    set hit(value: any[]) {
+        this.saveData("_hit", value, false)
+        this._hit = value;
+    }
+
+    get lastTimeLogin(): number {
+        return this._lastTimeLogin;
+    }
+
+    set lastTimeLogin(value: number) {
+        this.saveData("_lastTimeLogin", value, false)
+        this._lastTimeLogin = value;
+    }
+
+    get stamina(): number {
+        return this._stamina;
+    }
+
+    set stamina(value: number) {
+        if (value > Global.config.gameInfo.maxStamina) {
+            this._stamina = Global.config.gameInfo.maxStamina;
+        } else {
+            this._stamina = value;
+        }
+        this.saveData("_stamina", this._stamina);
+    }
+
+    get checkpoint(): number {
+        return this._checkpoint;
+    }
+
+    set checkpoint(value: number) {
+        this.saveData("_checkpoint", value);
+        this._checkpoint = value;
+    }
+
+    get gold(): number {
+        return this._gold;
+    }
+
+    set gold(value: number) {
+        this.saveData("_gold", value)
+        this._gold = value;
+    }
+
+    get diamond(): number {
+        return this._diamond;
+    }
+
+    set diamond(value: number) {
+        this.saveData("_diamond", value)
+        this._diamond = value;
+    }
+
+    get user_code(): string {
+        return this._user_code;
+    }
+
+    set user_code(value: string) {
+        this.saveData("_user_codes", value, false)
+        this._user_code = value;
+    }
+
+    get openId(): string {
+        return this._openId;
+    }
+
+    set openId(value: string) {
+        this.saveData("_openId", value, false)
+        this._openId = value;
+    }
+
+    //都用json 存储吧 ,不然太麻烦了
+    private saveData(key: string, value: any, isSend: boolean = true) {
+
+        if (value instanceof Map) {
+            localStorage.setItem(key, this._mapToJson(value))
+        } else {
+            localStorage.setItem(key, JSON.stringify(value))
+        }
+    }
+
+    private getData(key: string): boolean {
+        let result = true
+        let dataText = localStorage.getItem(key)
+        if (dataText == null || dataText == "" || dataText == undefined) {
+            result = false
+            this.saveData(key, this[key], false) //没有的话,先给他存进去
+            return
+        }
+        if (this[key] instanceof Map) {
+            this[key] = this._jsonToMap(dataText)
+        } else {
+            this[key] = JSON.parse(dataText)
+        }
+        return result
+    }
+
+    private _strMapToObj(strMap) {
+        let obj = Object.create(null);
+        strMap.forEach((v, k) => {
+            obj[k] = v;
+        })
+        return obj;
+    }
+
+    /**
+     *map转换为json
+     */
+    private _mapToJson(map) {
+        return JSON.stringify(this._strMapToObj(map));
+    }
+
+    private _objToStrMap(obj) {
+        let strMap = new Map();
+        for (let k of Object.keys(obj)) {
+            strMap.set(k, obj[k]);
+        }
+        return strMap;
+    }
+
+    /**
+     *json转换为map
+     */
+    private _jsonToMap(jsonStr) {
+        return this._objToStrMap(JSON.parse(jsonStr));
+    }
+
+    /**
+     * @private 同步信息到服务端
+     */
+    public updateData() {
+        let data = {
+            checkpoint: this._checkpoint,
+            diamond: this._diamond,
+            gold: this._gold,
+            setting: JSON.stringify(this._setting),
+            stamina: this.stamina,
+            userId: this.userId
+        }
+    }
+}
+
+export default new CachesMgr()
+
+interface Setting {
+    music: number,  // 音乐音量大小 0 -1
+    audio: number,  // 音效音量大小
+    vibrate: number // 是否震动
+}
+
+interface CustomData {
+    signTime: number  //上次签到时间
+    hammerNum: number //剩余锤子个数
+    spriteNum: number //剩余恶魔次数
+    lastSignNum: number //上次签到时间
+    signNum: number   //当前签到次数
+    hintNum: number  //免费提示数据
+    setting: Setting
+}

+ 9 - 0
assets/Script/Common/manage/CacheMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "26bdb81d-5bfd-40e8-a357-8c72876a44f6",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Common/manage/Emit.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "82995b90-6d47-4833-9755-0f8a405e157c",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 22 - 0
assets/Script/Common/manage/Emit/Emit.ts

@@ -0,0 +1,22 @@
+/**
+ * 事件管理器
+ */
+import EmitBase from "./EmitBase";
+
+export default class Emit extends EmitBase {
+
+    protected static _instance: EmitBase = new EmitBase();
+
+    public static instance(): EmitBase {
+        return this._instance;
+    }
+
+    constructor() {
+        super();
+        if (Emit._instance) {
+            return;
+        }
+        Emit._instance = this;
+    }
+
+}

+ 9 - 0
assets/Script/Common/manage/Emit/Emit.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "8d5e41a2-9dc1-4dbe-8930-9e27dcc713b6",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 92 - 0
assets/Script/Common/manage/Emit/EmitBase.ts

@@ -0,0 +1,92 @@
+//事件派发
+import GameLog from "../GameLogMgr";
+import isNumber = cc.js.isNumber;
+
+export default class EmitBase extends cc.EventTarget {
+    /**
+     *
+     * @param type
+     * @param handler
+     * @param target
+     * @param useCapture
+     */
+    public on<T extends Function>(type: string | number, handler: T, target: any, useCapture?: boolean): T {
+        if ((!type && type != 0) || !target) {
+            GameLog.error("事件对象|类型为空===> type = ", type, "target =", target);
+            return;
+        }
+        if (typeof type == "string") {
+            return super.on(type, handler, target, useCapture)
+        } else {
+            return super.on(type.toString(), handler, target, useCapture)
+        }
+    }
+
+    /**
+     * @param type
+     * @param handler
+     * @param target
+     */
+    public once(type: string | number, handler: (arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any) => void, target?: any): void {
+        if (!type || !target) {
+            GameLog.error("事件对象|类型为空===> type = ", type, "target =", target);
+            return;
+        }
+
+        if (typeof type == "string") {
+            return super.once(type, handler, target);
+        } else {
+            return super.once(type.toString(), handler, target);
+        }
+
+    }
+
+
+    /**
+     *
+     * @param type
+     * @param handler
+     * @param target
+     */
+    public off(type: string | number, handler: Function, target: any): void {
+        if (!type || !target) {
+            GameLog.error("事件对象|类型为空===> type = ", type, "target =", target);
+            return;
+        }
+
+        if (typeof type == "string") {
+            return super.off(type, handler, target);
+        } else {
+            return super.off(type.toString(), handler, target);
+        }
+    }
+
+    /**
+     *
+     * @param target
+     */
+    public targetOff(target: any) {
+        if (!target) {
+            GameLog.error("事件对象===>  target =", target);
+            return;
+        }
+        return super.targetOff(target);
+    }
+
+    /**
+     * 派发事件
+     * @param type  事件类型
+     * @param arg1
+     * @param arg2
+     * @param arg3
+     * @param arg4
+     * @param arg5
+     */
+    public emit(type: string | number, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any): void {
+        if (typeof type == "string") {
+            return super.emit(type, arg1, arg2, arg3, arg4, arg5)
+        } else {
+            return super.emit(type.toString(), arg1, arg2, arg3, arg4, arg5)
+        }
+    }
+}

+ 9 - 0
assets/Script/Common/manage/Emit/EmitBase.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "cc12af18-5355-41f9-a0b9-a2ea2d7b38b8",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 18 - 0
assets/Script/Common/manage/Emit/EmitData.ts

@@ -0,0 +1,18 @@
+/**
+ * 事件数据
+ */
+export default class EmitData {
+    public static IN_NATIVE_NEXT : string = 'inNative_Next' ;
+
+    public static CLOSE_NATIVE : string = 'closeNative' ;
+
+    public static LOAD_GAME_SCENE : string = 'load_game_scene'
+}
+
+export enum EventCode {
+    GetConfigOver, //获取配置信息成功
+    PanelMgrInitOK, //panel管理器初始化完成
+    BannerBoxInitOver, //bannerBox初始化成功
+    BannerOrGridInitOK, // banner或者格子初始化成功
+    GAME_BOX_UPDATE,  //gameBox需要刷新
+}

+ 9 - 0
assets/Script/Common/manage/Emit/EmitData.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "5a248e2f-120f-4d08-99c9-929ca6dbe4d2",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 22 - 0
assets/Script/Common/manage/GameLogMgr.ts

@@ -0,0 +1,22 @@
+import Global from "../Global";
+
+export default class GameLogMgr {
+
+    public static log(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.log.apply(cc.log, args);
+        }
+    }
+
+    public static warn(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.warn.apply(cc.warn, args);
+        }
+    }
+
+    public static error(...args: any[]): void {
+        if (Global.config.isLog == 1) {
+            console.error.apply(cc.error, args);
+        }
+    }
+}

+ 9 - 0
assets/Script/Common/manage/GameLogMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "84d83ce2-1996-4de0-b1f7-d160c4d52fe5",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Common/manage/Layer.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "7359c6b8-2eca-4c40-b94b-c4882cccd9de",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 15 - 0
assets/Script/Common/manage/Layer/LayerMgr.ts

@@ -0,0 +1,15 @@
+export default class LayerMgr {
+    //这里是初始化三个父节点而已 ,实在Main中调用的,之后可以用于 UIMgr openUI 的参数
+    public static init(param: any) {
+        this.gameLayer = param.gameLayer;
+        this.bannerLayer = param.bannerLayer;
+        this.gameInfoLayer = param.gameInfoLayer;
+    }
+
+    public static gameLayer: cc.Node = null;
+
+    public static bannerLayer: cc.Node = null;
+
+    public static gameInfoLayer: cc.Node = null;
+
+}

+ 9 - 0
assets/Script/Common/manage/Layer/LayerMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "91564035-4c5c-4f1e-9676-fe4ce270e3f0",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 43 - 0
assets/Script/Common/manage/Layer/LayerPanel.ts

@@ -0,0 +1,43 @@
+import LayerUI from "./LayerUI";
+import GameLog from "../GameLogMgr";
+
+const {ccclass} = cc._decorator;
+
+@ccclass
+export default abstract class LayerPanel extends LayerUI {
+    public static getUrl(): UrlInfo {
+        GameLog.error("需要重写getURL");
+        return null
+    }
+
+    //动态加载的资源  ,将需要清除的动态资源放在asset中,在该面板销毁的时候,会自动释放这些资源
+    public assets: cc.Asset [] = []
+
+    /**
+     *
+     *  面板初始化,第一次生成的时候调用
+     */
+    public abstract initUI();
+
+    /**
+     *
+     * 面板显示 每次显示都调用 可以进行相关初始化(UI、事件)会在onload,start之前调用
+     * @param param 面板显示参数
+     */
+    public abstract show(param: any): void;
+
+    /**
+     * 面板隐藏  每次因此都调用
+     */
+    public abstract hide();
+
+    public onDestroyDo() {
+
+    }
+}
+
+
+export interface UrlInfo {
+    bundle: string,
+    name: string,
+}

+ 9 - 0
assets/Script/Common/manage/Layer/LayerPanel.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "ee2965e8-a383-4b43-a34e-99c7622fb3db",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 179 - 0
assets/Script/Common/manage/Layer/LayerUI.ts

@@ -0,0 +1,179 @@
+import AudioMgr from "../AudioMgr";
+import GameLog from "../GameLogMgr";
+
+/**
+ * 这个是 封装了一些方法  ,例如 注册点击事件 销毁事件 等等
+ */
+const {ccclass} = cc._decorator;
+
+@ccclass
+export default class LayerUI extends cc.Component {
+
+    private _touchList: { [key: string]: { target, handler, callObj } } = {};
+    private _touchEndList: { [key: string]: { target, handler, callObj } } = {}
+
+    private _enableList: { [key: string]: { enabled: boolean, isGray: boolean } } = {};
+
+
+    /**
+     * 是否交互 需在target注册onTouch之后
+     * @param target
+     * @param v
+     * @param isGray
+     */
+    protected setInteractable(target: cc.Node, v: boolean, isGray: boolean = true) {
+        if (!target)
+            return;
+        let button: cc.Button = target.getComponent(cc.Button);
+        if (button) {
+            button.enableAutoGrayEffect = isGray;
+            button.interactable = v;
+        }
+        this._enableList[target.name] = {enabled: v, isGray};
+    }
+
+    /**
+     *  注册点击事件
+     * @param target    点击对象
+     * @param handler   触发事件
+     * @param sound     播放声音名称
+     * @param scale     缩放值
+     * @param stopEvent
+     */
+    protected onTouch(target: cc.Node, handler: Function, sound: string = "click", scale = 0.9, stopEvent = true) {
+        if (!target || !handler) {
+            GameLog.error("target || handler为空-->", target, handler);
+            return;
+        }
+
+        let targetName: string = target.name;
+        if (this._touchList[targetName] && this._touchList[targetName].target == target) {
+            GameLog.warn("重复设置-->", targetName);
+            return;
+        }
+
+        //添加一个button 动画
+        let button = target.getComponent(cc.Button);
+        if (scale != 1) {
+            if (!button) {
+                button = target.addComponent(cc.Button);
+                button.transition = cc.Button.Transition.SCALE;
+                button.zoomScale = scale;
+            }
+        }
+
+
+        let enabled = true;
+        let isGray = true;
+        if (this._enableList[target.name]) {
+            enabled = this._enableList[target.name].enabled;
+            isGray = this._enableList[target.name].isGray;
+        }
+
+        this.setInteractable(target, enabled, isGray);
+
+        let callObj = this;
+        let touchHandler = (event) => {
+            let {enabled = true} = this._enableList[target.name] || {};
+            if (!enabled) {
+                return;
+            }
+            if (stopEvent) {
+                event.stopPropagation();
+            }
+            if (sound && sound != "") {
+                // if (sound === "check") {
+                // sound = "piano/a" + Math.floor(Math.random() * (5 - 1) + 1);
+                // }
+                AudioMgr.play(sound).then();
+            }
+            handler.call(callObj, event);
+        };
+        target.on(cc.Node.EventType.TOUCH_START, touchHandler);
+        this._touchList[targetName] = {target: target, handler: touchHandler, callObj: callObj};
+    }
+
+    protected onTouchEnd(target: cc.Node, handler: Function) {
+        if (!target || !handler) {
+            GameLog.error("target || handle为空 ondTouchEnd -->", target, handler)
+            return
+        }
+        let targetName: string = target.name
+        if (this._touchEndList[targetName] && this._touchEndList[targetName].target == target) {
+            GameLog.warn("重复设置 --> onTouchEnd ", targetName)
+        }
+
+        let callObj = this;
+        let touchHandler = (event) => {
+            handler.call(callObj, event);
+        };
+        target.on(cc.Node.EventType.TOUCH_END, touchHandler);
+        target.on(cc.Node.EventType.TOUCH_CANCEL, touchHandler);
+
+        this._touchEndList[targetName] = {target: target, handler: touchHandler, callObj: callObj};
+    }
+
+    protected offTouchEnd(target: cc.Node) {
+        if (!target) {
+            GameLog.error("target 为空 ")
+            return
+        }
+        let targetName: string = target.name
+        if (this._touchEndList[targetName]) {
+            let handler = this._touchEndList[targetName].handler
+            target.off(cc.Node.EventType.TOUCH_END, handler)
+            target.off(cc.Node.EventType.TOUCH_CANCEL, handler)
+            delete this._touchEndList[targetName]
+        }
+    }
+
+    /**
+     * 移除对象点击事件
+     * @param target
+     */
+    protected offTouch(target: cc.Node) {
+        if (!target) {
+            GameLog.error("target 为空");
+            return
+        }
+        let targetName: string = target.name;
+        if (this._touchList[targetName]) {
+            let touchHandler = this._touchList[targetName].handler;
+            target.off(cc.Node.EventType.TOUCH_START, touchHandler);
+            delete this._touchList[targetName]
+        }
+        delete this._enableList[targetName]
+    }
+
+
+    protected clear() {
+        for (let key in this._touchList) {
+            this.offTouch(this._touchList[key].target)
+        }
+    }
+
+    onDestroy() {
+        this.clear()
+    }
+
+    /**
+     *
+     * @param path 路径或者名字
+     */
+    protected getNode(path: string): cc.Node {
+        let node: cc.Node = null;
+        if (path == "" || !path)
+            return null;
+        if (path.indexOf("/") != -1) {
+            node = cc.find(path, this.node);
+        } else {
+            node = this.node.getChildByName(path);
+        }
+
+        if (!node) {
+            GameLog.warn("未找到该节点  path=", path);
+        }
+        return node;
+    }
+
+}

+ 9 - 0
assets/Script/Common/manage/Layer/LayerUI.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "07b557ef-406c-47df-83c6-b54755c0afe8",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 222 - 0
assets/Script/Common/manage/LoadMgr.ts

@@ -0,0 +1,222 @@
+import Global from "../Global";
+import GameLog from "./GameLogMgr";
+import Texture2D = cc.Texture2D;
+import AudioClip = cc.AudioClip;
+import GameLogMgr from "./GameLogMgr";
+import TestMgr from "../Test";
+import Bundle = cc.AssetManager.Bundle;
+import url = cc.url;
+
+export default class LoadMgr {
+
+    private static _sprite = {};
+
+    private static alreadyLoadBundle: Map<string, Bundle> = new Map<string, Bundle>()
+
+    public static loadBundle(bundleNames: string[]) {
+        return new Promise((resolve, reject) => {
+            let functions: any[] = []
+            for (let i = 0; i < bundleNames.length; i++) {
+                let name = bundleNames[i]
+                if (!this.alreadyLoadBundle.has(name)) {
+                    functions.push(this.loadBundle_Single(name))
+                }
+            }
+            Promise.all(functions).then((data) => {
+                resolve(data)
+            }, () => {
+                reject(false)
+            })
+        })
+    }
+
+    public static loadBundle_Single(name: string) {
+        return new Promise((resolve1, reject1) => {
+            cc.assetManager.loadBundle(name, (err, data) => {
+                if (err) {
+                    GameLogMgr.error("加载分包失败!!!!!!!!!", err, "name :", name)
+                    reject1(false)
+                    return
+                }
+                this.alreadyLoadBundle.set(name, data)
+                resolve1(data)
+            })
+        })
+    }
+
+    public static judgeBundleLoad(name: string): boolean {
+        return this.alreadyLoadBundle.has(name)
+    }
+
+    public static getBundle(bundle_name: string): Bundle {
+        return this.alreadyLoadBundle.get(bundle_name)
+    }
+
+    //提前初始化所有分包
+    public static init_bundleMgr() {
+        this.loadBundle_Single("homeView").then()
+        this.loadBundle_Single("gameView").then()
+        this.loadBundle_Single("homeView").then()
+        this.loadBundle_Single("treaView").then()
+        this.loadBundle_Single("oneBox").then()
+    }
+
+    /**
+     * 加载图片
+     * @param sprite
+     * @param _url
+     * @param bundle 图片所在的分包
+     * @param needActive
+     */
+    public static loadSprite(sprite: cc.Sprite, _url: string, bundle: Bundle = this.getBundle("sub"), needActive = true) {
+        let id = bundle.name + "/" + _url
+        return new Promise((resolve, reject) => {
+            if (this._sprite.hasOwnProperty(id)) {
+                sprite.spriteFrame = this._sprite[id];
+                if (needActive) {
+                    sprite.node.active = true;
+                }
+                resolve(this._sprite[id]);
+                return;
+            }
+            bundle.load("image/" + _url, cc.SpriteFrame, (err: Error, spf: cc.SpriteFrame) => {
+                if (err) {
+                    GameLog.error(id, ' 图片加载错误 ', err);
+                    reject(false);
+                    return;
+                }
+                this._sprite[id] = spf;
+                sprite.spriteFrame = spf;
+                if (needActive) {
+                    sprite.node.active = true;
+                }
+                resolve(spf);
+            });
+        });
+    }
+
+    private static _remote_Sprite: Map<string, cc.SpriteFrame> = new Map<string, cc.SpriteFrame>();
+
+
+    public static loadRemoteSprite(_url: string, sprite: cc.Sprite = null, needActive: boolean = true) {
+        return new Promise((resolve, reject) => {
+            if (this._remote_Sprite.get(_url)) {
+                if (sprite) {
+                    sprite.spriteFrame = this._remote_Sprite.get(_url);
+                }
+                if (needActive) {
+                    if (sprite) {
+                        sprite.node.active = true;
+                    }
+                }
+                resolve(this._remote_Sprite.get(_url))
+            } else {
+                cc.assetManager.loadRemote(_url, Texture2D, (err, texture: Texture2D) => {
+                    if (texture.width == 0) {
+                        let path = cc.assetManager.cacheManager.getTemp(_url);
+                        cc.assetManager.loadRemote(path, (err, sp: cc.Texture2D) => {
+                            if (err) {
+                                GameLog.warn("第二次加载远程图片失败", err);
+                                reject(false);
+                                return;
+                            }
+                            this._remote_Sprite.set(_url, new cc.SpriteFrame(sp));
+                        });
+                        if (sprite) {
+                            sprite.spriteFrame = this._remote_Sprite.get(_url);
+                        }
+                        resolve(this._remote_Sprite.get(_url));
+                    } else {
+                        if (err) {
+                            GameLog.warn("加载远程图片失败", err);
+                            reject(false);
+                            return;
+                        }
+                        this._remote_Sprite.set(_url, new cc.SpriteFrame((texture)));
+                    }
+                    if (needActive) {
+                        if (sprite) {
+                            sprite.node.active = true;
+                            sprite.spriteFrame = this._remote_Sprite.get(_url);
+                            // sprite.spriteFrame = new cc.SpriteFrame(texture)
+                        }
+                    }
+                    resolve(this._remote_Sprite.get(_url));
+                });
+            }
+        });
+    }
+
+    private static _prefabCaches = {};
+
+    /**
+     * 加载 预制体
+     * @param _url
+     * @param bundle  预制体所在的分包
+     */
+    public static loadPrefab(_url: string, bundle: Bundle = this.getBundle("sub")) {
+        let id = bundle.name + "/" + _url
+        return new Promise((resolve, reject) => {
+            if (this._prefabCaches.hasOwnProperty(id)) {
+                resolve(this._prefabCaches[id]);
+                return;
+            }
+            bundle.load("prefab/" + _url, cc.Prefab, (err: Error, prefab: cc.Prefab) => {
+                if (err) {
+                    GameLog.error('setPrefab error', err, id);
+                    reject(false);
+                    return;
+                }
+                this._prefabCaches[id] = prefab;
+                resolve(prefab);
+            });
+        });
+    }
+
+    private static _audio_caches: Map<string, cc.AudioClip> = new Map<string, cc.AudioClip>();
+
+    public static load_AudioClip(_url: string, bundle: Bundle = this.getBundle("sub")) {
+        let id = bundle.name + "/" + _url
+        return new Promise((resolve, reject) => {
+            if (this._audio_caches.get(id)) {
+                let audioClip = this._audio_caches.get(id);
+                resolve(audioClip);
+            } else {
+                bundle.load("audio/" + _url, cc.AudioClip, (err, audio: AudioClip) => {
+                    if (err) {
+                        GameLog.error("加载音频失败", err, "url : ", id);
+                        reject(null);
+                        return;
+                    }
+                    this._audio_caches.set(id, audio);
+                    resolve(audio);
+                });
+            }
+        });
+    }
+
+    private static _AtlasCaches = {};
+
+    /**
+     * 加载 图集文件
+     * @private
+     */
+    public static loadAtlas(_url: string, bundle: Bundle = this.getBundle("sub")) {
+        let id = bundle.name + "/" + _url
+        return new Promise((resolve, reject) => {
+            if (this._AtlasCaches.hasOwnProperty(id)) {
+                resolve(this._AtlasCaches[id]);
+                return;
+            }
+            bundle.load("image/" + _url, cc.SpriteAtlas, (err: Error, atlas: cc.SpriteAtlas) => {
+                if (err) {
+                    GameLog.log('setAtlas error', err, id);
+                    reject(false);
+                    return;
+                }
+                this._AtlasCaches[id] = atlas;
+                resolve(atlas);
+            });
+        });
+    }
+}

+ 9 - 0
assets/Script/Common/manage/LoadMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "7f744521-4480-47c6-82b4-e42b152d366c",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 168 - 0
assets/Script/Common/manage/PanelMgr.ts

@@ -0,0 +1,168 @@
+import CacheMgr from "./CacheMgr";
+import LoadMgr from "./LoadMgr";
+import Emit from "./Emit/Emit";
+import {EventCode} from "./Emit/EmitData";
+import LayerPanel from "./Layer/LayerPanel";
+
+const {ccclass, property} = cc._decorator;
+@ccclass
+export default class PanelMgr extends cc.Component {
+    public static INS: PanelMgr
+    @property(
+        {
+            type: [cc.Node],
+            tooltip: "只要将Game中的场景layer按照顺序赋值即可, 如果存在修改,需要到PannerMgr.ts中修改枚举变量 Layer,也是需要按照绑定顺序"
+        }
+    )
+    public layers: cc.Node[] = []
+
+    //当前正在Loading 的面板
+    private LoadingList: Map<string, number> = new Map<string, number>()
+    //当前打开的面板数组
+    private openList: Map<string, cc.Node> = new Map<string, cc.Node>()
+    //当前关闭但是未摧毁的面板,存储在这里,下次打开该面板的时候,就会使用这里的面板
+    private hideList: Map<string, cc.Node> = new Map<string, cc.Node>()
+
+    onLoad() {
+        PanelMgr.INS = this
+        console.log('PanelMgr初始化完成')
+        Emit.instance().emit(EventCode.PanelMgrInitOK)
+    }
+
+    /**
+     * @param param{
+     *     layer : 在哪一个容器打开页面
+     *     panel: 打开面板
+     *     call : 打开成功回调 可选
+     *     param: 传递给下一个面板的参数
+     * }
+     */
+    openPanel(param: openParam) {
+        let layer = this.layers[param.layer]
+
+        console.log('param:',param,this.layers)
+        if (!layer) {
+            return
+        }
+
+        //加载分包
+        let urlInfo = param.panel.getUrl()
+
+        if (this.LoadingList.has(urlInfo.name)) {
+            return;
+        }
+
+        if (this.openList.has(param.panel.getUrl().name)) {
+            return;
+        }
+        this.LoadingList.set(urlInfo.name, 1) //添加一个加载标识, 防止重复添加
+        //todo  mask
+        let openPanelWay = () => {
+            let way = () => {
+                let panel: cc.Node = null
+                //判断有没有旧的panel可用,有的话就不重新实例化了
+                if (this.hideList.has(urlInfo.name)) {
+                    panel = this.hideList.get(urlInfo.name)
+                    panel.parent = layer
+                    panel.active = false
+                    // this.scheduleOnce(() => {
+                    this.openList.set(urlInfo.name, panel)
+                    this.showPanel(panel, param.param)
+                    this.LoadingList.delete(urlInfo.name)
+                    if (this.LoadingList.size == 0) {
+                        //todo mask
+                    }
+                    if (param.call) {
+                        param.call()
+                    }
+                    // }, 0)
+                } else {
+                    LoadMgr.loadPrefab(urlInfo.name, LoadMgr.getBundle(urlInfo.bundle)).then((prefab: cc.Prefab) => {
+                        panel = cc.instantiate(prefab)
+                        panel.parent = layer
+                        panel.active = false
+                        this.openList.set(urlInfo.name, panel)
+                        panel.getComponent(LayerPanel).initUI()
+                        this.showPanel(panel, param.param)
+                        this.LoadingList.delete(urlInfo.name)
+                        if (this.LoadingList.size == 0) {
+                            //todo mask
+                        }
+                        if (param.call) {
+                            param.call()
+                        }
+                    })
+                }
+            }
+
+            if (LoadMgr.judgeBundleLoad(urlInfo.name)) {
+                way()
+            } else {
+                LoadMgr.loadBundle_Single(urlInfo.bundle).then(() => {
+                    way()
+                })
+            }
+        }
+        //没有配置立即准备打开目标panel
+        openPanelWay()
+    }
+
+    private showPanel(panel: cc.Node, param: any) {
+        let script = panel.getComponent(LayerPanel)
+        script.show(param)
+        panel.active = true
+    }
+
+    /**
+     *
+     * @param panel 需要关闭的面板
+     * @param destroy 是否需要彻底销毁这个面板
+     */
+    closePanel(panel: typeof LayerPanel, destroy = true) {
+        let node = this.openList.get(panel.getUrl().name)
+        if (!node) {
+            return
+        }
+
+        node.getComponent(LayerPanel).hide() //这里可以做清除代码
+
+        node.getComponent(LayerPanel).unscheduleAllCallbacks() //取消所有定时器
+        if (panel.getUrl().name == "endView") { //如果是endView的化 ,需要同步数据
+            CacheMgr.updateData();
+        }
+
+        node.parent = null
+        this.openList.delete(panel.getUrl().name)
+        if (destroy) {
+            node.getComponent(LayerPanel).onDestroyDo() //这里可以做清除代码
+            node.destroy()
+        } else {
+            this.hideList.set(panel.getUrl().name, node)
+        }
+    }
+
+    getPanel(panel: typeof LayerPanel): cc.Node {
+        return this.openList.get(panel.getUrl().name)
+    }
+}
+
+export enum Layer {
+    gameLayer,
+    gameInfoLayer,
+    otherLayer,
+    nativeLayer,
+}
+
+export enum View {
+    endView,
+    gameView,
+    homeView,
+}
+
+export interface openParam {
+    layer: Layer,
+    panel: typeof LayerPanel,
+    call?: Function,
+    param?: any
+}
+

+ 9 - 0
assets/Script/Common/manage/PanelMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "a5e36250-d064-4161-89b9-3f90c1623542",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 107 - 0
assets/Script/Common/manage/PondMgr.ts

@@ -0,0 +1,107 @@
+import GameLog from "./GameLogMgr";
+import LoadMgr from "./LoadMgr";
+
+export default class PondMgr {
+
+    private static caches: { [key: string]: any } = {};
+
+    private static gamePool: { [key: string]: cc.NodePool } = {};   //对象池?
+
+    /**
+     * 新增对象池
+     * @param url 名称
+     * @param prefab 预制体
+     * @param cnt 个数
+     */
+    public static addToCaches(url: string, prefab: any, cnt: number = 1) {
+        if (url && prefab) {   //判断url 和预制体 是否为空
+            if (this.caches[url]) {
+                return false
+            }
+            this.caches[url] = prefab;
+            this.createToPool(url, cnt);
+            return true;
+        }
+    }
+
+    private static createToPool(url: string, cnt: number = 1) {
+        //判断 url是否为空,或者 内存中已经存在
+        if (!url || !this.caches[url]) {
+            return;
+        }
+
+        //如果 gamePool 中没有存在 的话 , 那么就创建一个 cc.Node
+        if (this.gamePool[url] == null) {
+            this.gamePool[url] = new cc.NodePool();
+        }
+
+        cnt -= this.gamePool[url].size();
+        for (let i = 0; i < cnt; i++) {
+            let item = cc.instantiate(this.caches[url]);
+            this.gamePool[url].put(item);
+        }
+    }
+
+    /**
+     * 放回对象池
+     */
+    public static putNodeToPool(url: string, item: cc.Node) {
+        if (item == null || url == "" || url == null) {
+            GameLog.warn('putNodeToPool fail', url, item);
+            return;
+        }
+
+        //该对象池不存在,重新创建
+        if (this.gamePool[url] == null) {
+            this.gamePool[url] = new cc.NodePool();
+        }
+        //清空父节点
+        item.parent = null;
+        this.gamePool[url].put(item);
+    }
+
+    /**
+     * 从对象池中获取一个节点
+     */
+    public static getNodeFromPool(url: string): cc.Node {
+        let item = null;
+        //如果对象池为空,则需要重新创建一下
+        if (this.gamePool[url] == null) {
+            this.gamePool[url] = new cc.NodePool();
+        }
+        if (this.gamePool[url].size() > 0) {
+            item = this.gamePool[url].get(); // 对象池 中如果已经存在这个节点了,直接去除就行
+        } else if (this.caches[url]) {
+            //没有存在这个节点的话 ,需要根据 caches 创建
+            item = cc.instantiate(this.caches[url]);
+        }
+        return item;
+    }
+
+    /**
+     * 异步获取节点
+     * @param url  节点路径
+     * @param callFun   获取到之后的回调函数
+     */
+    public static getAsyncNodeToPool(url: string, callFun: any) {
+        if (!url) {
+            GameLog.warn("getAsyncNodeToPool", "url为空");
+            return;
+        }
+        let item = this.getNodeFromPool(url);  // 先获取节点
+        if (item) {  //节点存在,调用回调
+            if (callFun) {
+                callFun(item);
+            }
+        } else {
+            //节点不存在,只能去加载咯 ,芜湖
+            LoadMgr.loadPrefab(url).then((prefab: cc.Prefab) => {
+                this.addToCaches(url, prefab);
+                item = this.getNodeFromPool(url);
+                if (callFun) {
+                    callFun(item);
+                }
+            })
+        }
+    }
+}

+ 9 - 0
assets/Script/Common/manage/PondMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "59aaee7e-729b-43d5-b6c2-5413acaadc2a",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 56 - 0
assets/Script/Common/manage/StorageMgr.ts

@@ -0,0 +1,56 @@
+/**
+ * 本地数据处理
+ */
+import GameLog from "./GameLogMgr";
+
+export default class StorageMgr {
+    /**
+     * 读取本地数据
+     * @param key
+     */
+    public static read(key: string) {
+        if (key != null) {
+            let result = cc.sys.localStorage.getItem(key);
+            if (result) {
+                result = JSON.parse(result);
+            }
+            GameLog.log('storage read', key, result);
+            return result;
+        }
+    }
+
+    /**
+     * 写入本地数据
+     * @param key
+     * @param value
+     */
+    public static save(key: string, value: any) {
+        try {
+            GameLog.log('storage save', key, value);
+            if (key != null) {
+                return cc.sys.localStorage.setItem(key, JSON.stringify(value));
+            }
+        } catch (error) {
+            GameLog.error(error);
+        }
+    }
+
+    /**
+     * 清空本地数据
+     */
+    public static clear() {
+        return cc.sys.localStorage.clear();
+    }
+
+    /**
+     * 删除本地数据
+     * @param key
+     */
+    public static rm(key: string) {
+        if (key != null) {
+            return cc.sys.localStorage.removeItem(key);
+        }
+    }
+
+}
+

+ 9 - 0
assets/Script/Common/manage/StorageMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "4b7f5309-2935-4327-bacd-a55b273aac4c",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 31 - 0
assets/Script/Common/manage/TimerMgr.ts

@@ -0,0 +1,31 @@
+import CacheMgr from "./CacheMgr";
+import Tools from "../Tools";
+import Emit from "./Emit/Emit";
+import {EventCode} from "./Emit/EmitData";
+
+/**
+ *  总定时器 , 用来 判断签到 或者恢复体力  每分钟判断
+ */
+class TimerMgr {
+    constructor() {
+        //每秒进行判断
+        window.setInterval(() => {
+            this.update()
+        }, 1000)
+    }
+
+    update() {
+        //每秒执行
+        let nowTime = new Date();
+        let dataNum = Tools.date_getTimeNum(nowTime)
+        if (dataNum != CacheMgr.exportTime) {
+            //新的一天 ,重置导出。。
+            CacheMgr.earlyExportTripPart = []
+            CacheMgr.earlyExport = []
+            Emit.instance().emit(EventCode.GAME_BOX_UPDATE)
+            CacheMgr.exportTime = dataNum
+        }
+    }
+}
+
+export default new TimerMgr();

+ 9 - 0
assets/Script/Common/manage/TimerMgr.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "e49b5065-a184-441d-91a0-99e72f6c9bf5",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Moudle.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "c9be8308-39f3-4714-aacb-69de732c9de5",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Moudle/View.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "3a7258b5-f12d-4619-9efe-19f49b90403b",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 193 - 0
assets/Script/Moudle/View/EndView.ts

@@ -0,0 +1,193 @@
+import HomeView from "./HomeView";
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import CacheMgr from "../../Common/manage/CacheMgr";
+import GameView from "./GameView";
+import LayerMgr from "../../Common/manage/Layer/LayerMgr";
+import AudioMgr from "../../Common/manage/AudioMgr";
+import PanelMgr, {Layer} from "../../Common/manage/PanelMgr";
+import ShowConfig from "../../Common/ShowConfig";
+import Global from "../../Common/Global";
+import QgBanner from "../../Common/manage/Api/QgBanner";
+import Emit from "../../Common/manage/Emit/Emit";
+import EmitData from "../../Common/manage/Emit/EmitData";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class EndView extends LayerPanel {
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "endView",
+            name: "endView"
+        }
+    }
+
+    private _paramData: any = {};
+
+    private _button: cc.Node = null;
+    @property(cc.Prefab)
+    private coinPrefab: cc.Prefab = null
+    coinPool: cc.NodePool = null;  //星星对象金币对象池
+    getGold: cc.Node = null
+    getScore: cc.Node = null
+    gameBox: cc.Node = null
+    maxScore: cc.Node = null
+    newMax: cc.Node = null
+    caiDai: cc.Node = null
+    home_btn: cc.Node = null
+    game_btn: cc.Node = null
+    isNewMax: boolean = false
+    score: number = null
+
+    public initUI() {
+        //todo logic
+        this.getGold = this.getNode("topUi/huodejinbi/getGlod")
+        this.gameBox = this.getNode("gameBox")
+        this.getScore = this.getNode("topUi/getNum")
+        this.maxScore = this.getNode("history/history_num")
+        this.newMax = this.getNode("xinjilu")
+        this.caiDai = this.getNode("caidai")
+        this.game_btn = this.getNode("bottomUI/continue")
+        this.onTouch(this.game_btn, this.handle_continue)
+        this.home_btn = this.getNode("bottomUI/home")
+        this.onTouch(this.home_btn, this.handle_home)
+        this.coinPool = new cc.NodePool();
+        this.initCoinPool();
+    }
+
+    public show(param: any) {
+        //todo 逻辑
+        this.isNewMax = param.isNewMax;
+        this.getScore.getComponent(cc.Label).string = param.score;
+        this.getGold.getComponent(cc.Label).string = "+" + param.score;
+        this.score = Number(param.score);
+        this.maxScore.getComponent(cc.Label).string = CacheMgr.checkpoint.toString();
+
+
+        ShowConfig.show('endConfig').then((res) => {
+            if (Global.config.endConfig.bannerShow == 1) {
+                QgBanner.showBanner();
+            } else {
+                QgBanner.hideBanner();
+            }
+        });
+    }
+
+    public hide() {
+        CacheMgr.updateData();
+        if (Global.config.gameConfig.nativeConfig.type == 2) {
+            Emit.instance().emit(EmitData.CLOSE_NATIVE) ;
+        }
+    }
+
+    //todo logic 方法
+    /** 初始化金币对象池 */
+    initCoinPool(count: number = 20) {
+        for (let i = 0; i < count; i++) {
+            let coin = cc.instantiate(this.coinPrefab);
+            this.coinPool.put(coin);
+        }
+    }
+
+    /** 播放动画 */
+    playAnim() {
+        AudioMgr.play("get_coins")
+
+        /** 随机金币数量 */
+        let randomCount = Math.random() * 15 + 10;
+        /** 起始位置 */
+        let startPos = this.node.convertToNodeSpaceAR(this.getGold.parent.parent.convertToWorldSpaceAR(this.getGold.parent.position))
+
+        /** 结束位置 */
+        let endPos = LayerMgr.gameInfoLayer.children[0].children[0].position
+        this.playCoinFlyAnim(randomCount, cc.v2(startPos), cc.v2(endPos));
+    }
+
+    /**
+     * 播放金币飞出动画
+     * @param count 金币数量
+     * @param startPos 起始位置
+     * @param endPos 结束位置
+     * @param r 半径
+     */
+    playCoinFlyAnim(count: number, startPos: cc.Vec2, endPos: cc.Vec2, r: number = 200) {
+        //确保当前节点池有足够的金币
+        const poolSize = this.coinPool.size();
+        const reCreateCoinCount = poolSize > count ? 0 : count - poolSize;
+        this.initCoinPool(reCreateCoinCount);
+        //生成园, 并且对圆上的点进行排序
+        let points = this.getCirclePoints(r, startPos, count);
+        let coinNodeList = points.map(pos => {
+            let coin = this.coinPool.get();
+            coin.setPosition(startPos);
+            this.node.addChild(coin);
+            return {
+                node: coin,
+                startPos: startPos,
+                mdPos: pos,
+                endPos: endPos,
+                /** sub 用于把字符串显示为下标 */
+                dis: (pos as any).sub(endPos).mag()
+            };
+        });
+        coinNodeList = coinNodeList.sort((a, b) => {
+            if (a.dis - b.dis > 0) return 1;
+            if (a.dis - b.dis < 0) return -1;
+            return 0;
+        })
+
+        //执行金币落袋的动画
+        coinNodeList.forEach((item, index) => {
+            item.node.runAction(
+                cc.sequence(
+                    cc.moveTo(0.3, item.mdPos),
+                    cc.delayTime(index * 0.01),
+                    cc.moveTo(0.5, item.endPos),
+                    cc.callFunc(() => {
+                        this.coinPool.put(item.node);
+                    })
+                )
+            );
+        });
+    }
+
+    /**
+     *
+     * @param r 半径
+     * @param pos 圆心坐标
+     * @param count 等分点数量
+     * @param randomScope 等分点的随机播动范围
+     */
+    getCirclePoints(r: number, pos: cc.Vec2, count: number, randomScope: number = 60): cc.Vec2[] {
+        let points = [];
+        //弧度
+        let radians = (Math.PI / 180) * Math.round(360 / count);
+        for (let i = 0; i < count; i++) {
+            let x = pos.x + r * Math.sin(radians * i);
+            let y = pos.y + r * Math.cos(radians * i);
+            points.unshift(cc.v3(x + Math.random() * randomScope, y + Math.random() * randomScope, 0));
+        }
+        return points;
+    }
+
+
+    handle_home() {
+        PanelMgr.INS.openPanel({
+            panel : HomeView,
+            layer : Layer.gameLayer,
+            call : ()=>{
+                PanelMgr.INS.closePanel(EndView) ;
+            }
+        })
+    }
+
+    handle_continue() {
+        PanelMgr.INS.openPanel({
+            panel : GameView,
+            layer : Layer.gameLayer,
+            call : ()=>{
+                PanelMgr.INS.closePanel(EndView) ;
+            }
+        })
+    }
+}

+ 9 - 0
assets/Script/Moudle/View/EndView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "67db6fa9-5de8-4bc1-8969-7923c80a1aac",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 212 - 0
assets/Script/Moudle/View/GameInfoView.ts

@@ -0,0 +1,212 @@
+import CacheMgr from "../../Common/manage/CacheMgr";
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import Global from "../../Common/Global";
+import ShortageView from "./ShortageView";
+import PanelMgr, {Layer} from "../../Common/manage/PanelMgr";
+import property = cc._decorator.property;
+import Tools from "../../Common/Tools";
+import tween = cc.tween;
+
+const {ccclass} = cc._decorator;
+
+@ccclass
+export default class GameInfoView extends LayerPanel {
+
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "gameInfoView",
+            name: "gameInfoView"
+        }
+    }
+
+    @property(cc.Prefab)
+    private fly_gold: cc.Prefab = null //执行飞金币动画的图片
+    @property(cc.Integer)
+    private boomTime: number = 0.5 //金币爆开时长
+    @property(cc.Integer)
+    private flyTime: number = 1  //金币飞行时间
+    @property(cc.Integer)
+    private radius_min: number = 50 //最小半径
+    @property(cc.Integer)
+    private radius_max: number = 100 //最大半径
+    @property(cc.Integer)
+    private fly_gold_min: number = 4
+    @property(cc.Integer)
+    private fly_gold_max: number = 10
+    @property(cc.Integer)
+    private gold_scale_min: number = 0.9
+    @property(cc.Integer)
+    private gold_scale_max: number = 1.2
+
+    private goldPool: cc.NodePool = new cc.NodePool() //
+
+    private fly_end: cc.Vec3 = null
+
+    private gold: cc.Node = null;
+    private diamond: cc.Node = null;
+
+    private gold_add_button: cc.Node = null;
+
+    private animationTime: number = null;
+    private gold_num: number = null;
+    private diamond_num: number = 0;
+    private timeouts: Map<string, number[]> = new Map<string, number[]>();
+
+    private static gameInfoViewIns: GameInfoView = null;
+
+    public static INS(): GameInfoView {
+        return this.gameInfoViewIns;
+    }
+
+    initUI(): void {
+        GameInfoView.gameInfoViewIns = this;
+        this.gold_num = CacheMgr.gold;
+        this.diamond_num = CacheMgr.diamond;
+        this.animationTime = Global.config.gameInfo.animation;
+        this.gold = this.getNode("gold/num");
+        this.gold_add_button = this.getNode("gold/add");
+
+        this.timeouts.set("gold", []);
+        this.timeouts.set("diamond", []);
+
+        let gold = this.getNode("gold")
+        let gold_icon = this.getNode("gold/icon")
+
+        this.initPool()
+        this.scheduleOnce(() => {
+            let wp = gold.convertToWorldSpaceAR(gold_icon.position)
+            this.fly_end = this.node.convertToNodeSpaceAR(wp)
+        }, 0)
+    }
+
+    show(param: any): void {
+        this.gold.getComponent(cc.Label).string = this.gold_num.toString();
+
+        this.onTouch(this.gold_add_button, () => {
+            PanelMgr.INS.openPanel({
+                panel: ShortageView,
+                layer: Layer.gameLayer,
+                param: {
+                    type: "gold",
+                }
+            })
+        });
+
+    }
+
+    hide() {
+
+    }
+
+    //初始化节点池
+    private initPool() {
+        if (this.fly_gold) {
+            for (let i = 0; i < this.fly_gold_max; i++) {
+                let gold = cc.instantiate(this.fly_gold)
+                this.goldPool.put(gold)
+            }
+        }
+    }
+
+    /**
+     * 监听金币是否改变
+     * @param dt
+     * @protected
+     */
+    protected update(dt: number) {
+        let newGold = CacheMgr.gold;
+        if (this.gold_num != newGold) {
+            this.changeAnimation("gold", newGold - this.gold_num);
+        }
+    }
+
+
+    /**
+     * 修改金币动画
+     * @param type
+     * @param num
+     * @private
+     */
+    private changeAnimation(type: string, num: number) {
+        this.clearTimeOut(type);
+        let num_bas = Math.abs(num);
+        let time = this.animationTime / num_bas;
+        let allTime = 0;   //累计耗时间
+        let num_ = this[type + "_num"];
+        this[type + "_num"] += num;
+        for (let i = 1; i <= num_bas; i++) {
+            if (num < 0) {
+                let arr = this.timeouts.get(type);
+                arr[i] = window.setTimeout(() => {
+                    this[type].getComponent(cc.Label).string = (num_ - i).toString();
+                }, allTime * 1000);
+                allTime += time;
+            } else {
+                let arr = this.timeouts.get(type);
+                arr[i] = window.setTimeout(() => {
+                    this[type].getComponent(cc.Label).string = (num_ + i).toString();
+                }, allTime * 1000);
+                allTime += time;
+            }
+        }
+    }
+
+    /**
+     * 清空所有动画
+     * @param type
+     * @private
+     */
+    private clearTimeOut(type: string) {
+        //停止所有关于 该类型改变的值
+        let timeouts = this.timeouts.get(type);
+        for (let i = 0; i < timeouts.length; i++) {
+            if (this.timeouts[i]) {
+                window.clearTimeout(timeouts[i]);
+            }
+        }
+        this[type].getComponent(cc.Label).string = this[type + "_num"].toString();   //直接赋值
+        this.timeouts.set(type, []);
+    }
+
+    /**
+     * @param point 需要飞金币的起始点(世界坐标)
+     * @private
+     */
+    public fly_gold_animation(pointPosition: cc.Vec3) {
+        pointPosition = this.node.convertToNodeSpaceAR(pointPosition)
+        return new Promise((resolve, reject) => {
+            let num = Tools.getRandom(this.fly_gold_min, this.fly_gold_max - 1)
+            if (num > this.goldPool.size()) {
+                resolve(true)
+                return
+            }
+            let p: any [] = []
+            for (let i = 0; i < num; i++) {
+                let pro = new Promise((resolve, reject) => {
+                    let gold = this.goldPool.get()
+                    gold.position = cc.v3(pointPosition)
+                    this.node.addChild(gold)
+                    let scale = Tools.getRealRandom(this.gold_scale_min, this.gold_scale_max)
+                    gold.scale = scale
+                    //随机角度, 随机半径
+                    let angle = Tools.getRandom(0, 360)
+                    let r = Tools.getRandom(this.radius_min, this.radius_max + 1)
+                    let boomPoint = Tools.getCirclePoint(pointPosition, r, angle)
+                    tween(gold)
+                        .to(this.boomTime, {position: boomPoint}, {easing: "quadOut"})
+                        .to(this.flyTime, {position: this.fly_end}, {easing: "quadOut"})
+                        .call(() => {
+                            this.goldPool.put(gold)
+                            resolve(true)
+                        })
+                        .start()
+                })
+                p.push(pro)
+            }
+            Promise.all(p).then(() => {
+                resolve(true)
+            })
+        })
+    }
+
+}

+ 9 - 0
assets/Script/Moudle/View/GameInfoView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "f41d6979-d147-4bb4-9917-d85d223fb884",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 1571 - 0
assets/Script/Moudle/View/GameView.ts

@@ -0,0 +1,1571 @@
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import Tools from "../../Common/Tools";
+import EndView from "./EndView";
+import Text from "./logic/common/text";
+import gameConfig from "./logic/common/config";
+import HomeView from "./HomeView";
+import CacheMgr from "../../Common/manage/CacheMgr";
+import AudioMgr from "../../Common/manage/AudioMgr";
+import LoadMgr from "../../Common/manage/LoadMgr";
+import Constant from "../../Common/Constant";
+import PanelMgr, {Layer} from "../../Common/manage/PanelMgr";
+import tween = cc.tween;
+import ShowConfig from "../../Common/ShowConfig";
+import Global from "../../Common/Global";
+import QgBanner from "../../Common/manage/Api/QgBanner";
+import Emit from "../../Common/manage/Emit/Emit";
+import EmitData from "../../Common/manage/Emit/EmitData";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class GameView extends LayerPanel {
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "gameView",
+            name: "gameView"
+        }
+    }
+    private _paramData: any = {};
+
+    private _button: cc.Node = null;
+
+    //test
+    private testMakeBottomBlock: cc.Node = null
+    private testReadyMakeBottomBlock: cc.Node = null
+    //logic
+    @property(cc.SpriteFrame)
+    public graySpriteFrame: cc.SpriteFrame = null
+    @property(cc.SpriteFrame)
+    public whiteSpriteFrame: cc.SpriteFrame = null
+    @property(cc.SpriteFrame)
+    public hintBlockSpriteFrame: cc.SpriteFrame = null
+    @property(cc.Prefab)
+    public text_prefab: cc.Prefab = null
+    @property(cc.Prefab)
+    public hammer_prefab: cc.Prefab = null
+    @property(cc.Prefab)
+    public sprite_prefab: cc.Prefab = null
+    @property([cc.SpriteFrame])
+    public sprite_spriteFrame: cc.SpriteFrame[] = []
+
+    @property(cc.SpriteFrame)
+    public hint_1_spriteFrame: cc.SpriteFrame = null
+    @property(cc.SpriteFrame)
+    public hint_2_spriteFrame: cc.SpriteFrame = null
+
+    @property(cc.Prefab)
+    public start_prefab: cc.Prefab = null
+    @property(cc.Prefab)
+    public hardUp_prefab: cc.Prefab = null
+    @property(cc.Prefab)
+    public nice_prefab: cc.Prefab = null
+    @property(cc.Prefab)
+    public get_prefab: cc.Prefab = null
+
+
+    private _startPoint: cc.Node = null
+    private _content: cc.Node = null
+    private _hintUI: cc.Node = null
+    private _whiteHint: cc.Node = null
+    private _textHint: cc.Node = null
+    private _hardLevelLabel: cc.Label = null
+    private _scoreLabel: cc.Label = null
+    private _mouth: cc.Node = null
+    private _mask: cc.Node = null
+    private _hammer: cc.Node = null
+    private _sprite: cc.Node = null
+    private _menu: cc.Node = null
+    private _menuPanel: cc.Node = null
+
+    private _hint_hammer: cc.Node = null
+    private _hint_sprite: cc.Node = null
+    private _hint_mask: cc.Node = null
+    private _hint_label: cc.Node = null
+    private _hint_hand: cc.Node = null
+
+    private _price_sprite: cc.Node = null
+    private _sprite_icon: cc.Node = null
+    private _hammer_sprite: cc.Node = null
+    private _hammer_icon: cc.Node = null
+
+
+    private _content_cover: cc.Node = null
+
+    private _lineDatas: lineData[] = [null]
+    private _hintData: lineData = null
+    private blockPool: cc.NodePool = null
+    private nextBlockInfo: nextBlockInfo [] = []
+    private touchEndFlag: boolean = false
+    private hardLevel: number = 1
+    private score: number = 0
+    private continueXiao: number = 0 // 当前连消
+    private allContinueXiao: number = 0//当前难度总消除
+    private moveX = -1
+    private sprite_color: number = 0 //精灵颜色
+    private hintFlag = true
+
+    public initUI() {
+        //todo 逻辑
+        this.testMakeBottomBlock = this.getNode("testUI/makeBottomBlock")
+        this.testReadyMakeBottomBlock = this.getNode("testUI/readymakeBottomBlock")
+        this.onTouch(this.testMakeBottomBlock, () => {
+            this.makeBottomBlock()
+        })
+        this.onTouch(this.testReadyMakeBottomBlock, () => {
+            this.readyMakeBottomBlock()
+        })
+        this._startPoint = this.getNode("startPoint")
+        this._content = this.getNode("content")
+        this._content_cover = this.getNode("content_cover")
+        this._hintUI = this.getNode("hintUI")
+        this._whiteHint = this.getNode("white_hint")
+        this._textHint = this.getNode("textHint")
+        this._mouth = this.getNode("content_cover/top/mouth")
+        this._mask = this.getNode("mask")
+        this._hammer_sprite = this.getNode("bottomUI/hammer/price")
+        this._hammer_icon = this.getNode("bottomUI/hammer/vedioIcon")
+        this._hammer_icon.active = false
+        this._price_sprite = this.getNode("bottomUI/sprite/price")
+        this._sprite_icon = this.getNode("bottomUI/sprite/vedioIcon")
+        this._sprite_icon.active = false
+        this._hint_mask = this.getNode("hint_mask")
+        this._hint_mask.active = false
+        this._hint_label = this.getNode("hint_label")
+        this._hint_label.active = false
+        this._hint_hand = this.getNode("hint_hand")
+        this._hint_hand.active = false
+
+        this._menu = this.getNode("bottomUI/menu")
+        this.onTouch(this._menu, this.handle_menu)
+        this._menuPanel = this.getNode("bottomUI/menuPanel")
+        this._menuPanel.active = false
+        this.onTouch(this._menuPanel.children[0], this.handle_restart)
+        this.onTouch(this._menuPanel.children[1], this.handle_return)
+
+        this._hammer = this.getNode("bottomUI/hammer")
+        // this._hammer.on(cc.Node.EventType.TOUCH_END, this.handle_hammer, this)
+        this.onTouch(this._hammer, this.handle_hammer)
+        this._sprite = this.getNode("bottomUI/sprite")
+        this.onTouch(this._sprite, this.handle_sprite)
+
+        this._hint_hammer = this.getNode("hint_hammer")
+        this._hint_hammer.active = false
+
+        this._hint_sprite = this.getNode("hint_sprite")
+        this._hint_sprite.active = false
+
+        this._hardLevelLabel = this.getNode("content_cover/top/hardLevel").getComponent(cc.Label)
+        this._scoreLabel = this.getNode("content_cover/top/scoreData").getComponent(cc.Label)
+
+
+        this.updateSprite()
+        //创建对象池
+        this.blockPool = new cc.NodePool()
+        let blockExm = new cc.Node()
+        blockExm.x = 0
+        blockExm.y = 0
+        blockExm.setAnchorPoint(0, 0)
+        let sprite = blockExm.addComponent(cc.Sprite)
+        sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM
+        for (let i = 0; i < 80; i++) {
+            let node = cc.instantiate(blockExm)
+            this.blockPool.put(node)
+        }
+        this.scheduleOnce(() => {
+            this._menuPanel.position = this._menu.position
+            let gridExm = new cc.Node()
+            gameConfig.gridSize = this._startPoint.height / 10
+            this._content.width = gameConfig.gridSize * 8
+            this._content.height = gameConfig.gridSize * 10
+            this._whiteHint.width = this._content.width
+            this._whiteHint.height = this._content.height
+            this._whiteHint.parent = this._content
+            gridExm.setAnchorPoint(0, 0)
+            gridExm.width = gameConfig.gridSize
+            gridExm.height = gameConfig.gridSize
+            gridExm.opacity = 200
+            this._hint_hand.width = gameConfig.gridSize
+            this._hint_hand.height = gameConfig.gridSize
+            this._hint_hand.setAnchorPoint(0, 0)
+            let lineContentExm = new cc.Node()
+            lineContentExm.setAnchorPoint(0.5, 0)
+            lineContentExm.width = gridExm.width * 8
+            lineContentExm.height = gridExm.height
+            this._hintUI.width = lineContentExm.width
+
+            let startPosition = this._startPoint.getPosition()
+            let gridColorTemp = 0   // 0 浅色   1  深色
+            for (let i = 10; i >= 1; i--) {
+                let lineContent = cc.instantiate(lineContentExm)
+                lineContent.name = i.toString()
+                lineContent.x = 0
+                lineContent.y = startPosition.y
+                startPosition.y += lineContent.height
+                this._content.addChild(lineContent)
+                let posData = Tools.getNodeFourPoint(lineContent)
+                lineContent.setAnchorPoint(0, 0)
+                lineContent.position = cc.v3(posData.left_down)
+                if (this._hintUI.x != lineContent.x) {
+                    this._hintUI.x = lineContent.x
+                    this._hintData = {
+                        blockNodes: [],
+                        line: this._hintUI,
+                        linePos: [-1]
+                    }
+                    let flagX = 0
+                    for (let i = 1; i <= 8; i++) {
+                        this._hintData.linePos[i] = flagX
+                        flagX += gameConfig.gridSize
+                    }
+                }
+                let flagX = 0
+                let linePosArr: number[] = [-1] //记录 x 轴
+                for (let j = 1; j <= 8; j++) {
+                    let grid = cc.instantiate(gridExm)
+                    grid.name = j.toString()
+                    let sprite = grid.addComponent(cc.Sprite)
+                    sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM
+                    if (gridColorTemp == 0) {
+                        if (j == 1 && i != 10) {
+                            sprite.spriteFrame = this.graySpriteFrame
+                        } else {
+                            gridColorTemp = 1
+                            sprite.spriteFrame = this.whiteSpriteFrame
+                        }
+                    } else {
+                        if (j == 1 && i != 1) {
+                            sprite.spriteFrame = this.whiteSpriteFrame
+                        } else {
+                            gridColorTemp = 0
+                            sprite.spriteFrame = this.graySpriteFrame
+                        }
+                    }
+                    grid.y = 0
+                    grid.x = flagX
+                    linePosArr.push(grid.x)
+                    flagX += grid.width
+                    lineContent.addChild(grid)
+                }
+                this._lineDatas[i] = {
+                    blockNodes: [],
+                    line: lineContent,
+                    linePos: linePosArr
+                }
+                if (i == 10) {
+                    this._whiteHint.x = lineContent.x
+                    this._whiteHint.y = lineContent.y
+                    this._whiteHint.active = false
+                }
+            }
+            this.adaptive()
+            lineContentExm.destroy()
+            gridExm.destroy()
+            this._startPoint.destroy()
+            this.text_start()
+            this.makeBottomBlock(true)
+        }, 0)
+    }
+
+    public show(param: any) {
+        //todo 逻辑
+
+        ShowConfig.show('gameConfig').then((res) => {
+            if (Global.config.gameConfig.bannerShow == 1) {
+                QgBanner.showBanner();
+            } else {
+                QgBanner.hideBanner();
+            }
+        });
+    }
+
+    public hide() {
+
+        if (Global.config.gameConfig.nativeConfig.type == 2) {
+            Emit.instance().emit(EmitData.CLOSE_NATIVE) ;
+        }
+    }
+
+    //todo logic 方法
+    private getBlock(size: number, color: number = -1): cc.Node {
+        let block = this.blockPool.get()
+        block.width = size * gameConfig.gridSize
+        block.height = gameConfig.gridSize
+        block.on(cc.Node.EventType.TOUCH_START, this.handle_block_start, this)
+        block.on(cc.Node.EventType.TOUCH_MOVE, this.handle_block_move, this)
+        block.on(cc.Node.EventType.TOUCH_END, this.handle_block_end, this)
+        block.on(cc.Node.EventType.TOUCH_CANCEL, this.handle_block_end, this)
+        LoadMgr.loadAtlas("view/gameView/block/p").then((p: cc.SpriteAtlas) => {
+            let id = ((color * 10) + size)
+            let spriteFrame = p.getSpriteFrame(id.toString())
+            block.getComponent(cc.Sprite).spriteFrame = spriteFrame
+        })
+        return block
+    }
+
+    //归还方块
+    private returnBlock(node: cc.Node) {
+        node.off(cc.Node.EventType.TOUCH_START, this.handle_block_start, this)
+        node.off(cc.Node.EventType.TOUCH_MOVE, this.handle_block_move, this)
+        node.off(cc.Node.EventType.TOUCH_END, this.handle_block_end, this)
+        node.off(cc.Node.EventType.TOUCH_CANCEL, this.handle_block_end, this)
+        node.parent = null
+        node.x = 0
+        node.y = 0
+        node.width = gameConfig.gridSize
+        node.height = gameConfig.gridSize
+        node.getComponent(cc.Sprite).spriteFrame = null
+        this.blockPool.put(node)
+        return
+    }
+
+    //预创建最低层的方块
+    private readyMakeBottomBlock() {
+        //先随机需要空出来几个
+        //判断是否需要新手提示
+        if (!CacheMgr.isNeedHint || gameConfig.hint_data.length == 0) {
+            let blankNum = Tools.getRandom(gameConfig.bottomBlankMin, gameConfig.bottomBlankMax + 1)
+            let blankColumns: number [] = []
+            while (true) {
+                let column = Tools.getRandom(1, 9)
+                let flag = Tools.JudgeValueInArr(column, blankColumns)
+                for (let i = 0; i < blankColumns.length; i++) {
+                    if (column == blankColumns[i]) {
+                        flag = true
+                    }
+                }
+                if (flag) {
+                    continue
+                }
+                blankColumns.push(column)
+                if (blankColumns.length >= blankNum) {
+                    break
+                }
+            }
+            //获取数组中连续的一段
+            let allContinueArr: number [] [] = []
+            let continueArr: number [] = []
+            for (let i = 1; i < 9; i++) {
+                if (Tools.JudgeValueInArr(i, blankColumns)) {
+                    if (continueArr.length > 0) {
+                        allContinueArr.push(Tools.deepClone(continueArr))
+                    }
+                    continueArr = []
+                } else {
+                    continueArr.push(i)
+                    if (i == 8) {
+                        allContinueArr.push(Tools.deepClone(continueArr))
+                    }
+                }
+            }
+            let allBlockInfo: nextBlockInfo[] = []
+            for (let i = 0; i < allContinueArr.length; i++) {
+                let blocInfos = this.definitionBlockType(Tools.deepClone(allContinueArr[i]))
+                blocInfos.forEach((value) => {
+                    allBlockInfo.push(value)
+                })
+            }
+            this.nextBlockInfo = allBlockInfo
+        } else {
+            this.nextBlockInfo = gameConfig.hint_data[0]
+            gameConfig.hint_data.shift()
+        }
+        this.updateHint()
+    }
+
+    //根据一个位置数组定义这一组方块类型
+    private definitionBlockType(arr: number []): nextBlockInfo[] {
+        let blockInfos: nextBlockInfo[] = []
+        while (true) {
+            let length = arr.length
+            if (arr.length == 0) {
+                break
+            }
+            if (length >= 4) {
+                if (Tools.checkPer(gameConfig.grade_of_difficulty_config[this.hardLevel].probability_4)) {
+                    blockInfos.push({
+                        column: arr [0],
+                        num: 4,
+                    })
+                    arr.splice(0, 4)
+                    continue
+                }
+            }
+            if (length >= 3) {
+                if (Tools.checkPer(gameConfig.grade_of_difficulty_config[this.hardLevel].probability_3)) {
+                    blockInfos.push({
+                        column: arr[0],
+                        num: 3
+                    })
+                    arr.splice(0, 3)
+                    continue
+                }
+            }
+            if (length >= 2) {
+                if (Tools.checkPer(gameConfig.grade_of_difficulty_config[this.hardLevel].probability_2)) {
+                    blockInfos.push({
+                        column: arr[0],
+                        num: 2,
+                    })
+                    arr.splice(0, 3)
+                    continue
+                }
+            }
+            if (length >= 1) {
+                if (Tools.checkPer(gameConfig.grade_of_difficulty_config[this.hardLevel].probability_1)) {
+                    blockInfos.push({
+                        column: arr[0],
+                        num: 1,
+                    })
+                    arr.splice(0, 1)
+                }
+            }
+        }
+        return blockInfos
+    }
+
+    //刷新提示
+    private updateHint() {
+        this._hintUI.removeAllChildren()
+        for (let i = 0; i < this.nextBlockInfo.length; i++) {
+            let info = this.nextBlockInfo[i]
+            let hintBlock = new cc.Node("hintBlock")
+            hintBlock.setAnchorPoint(0, 0)
+            let sprite = hintBlock.addComponent(cc.Sprite)
+            sprite.type = cc.Sprite.Type.SLICED
+            sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM
+            sprite.spriteFrame = this.hintBlockSpriteFrame
+            hintBlock.width = info.num * gameConfig.gridSize
+            hintBlock.height = this._hintUI.height
+            this._hintUI.addChild(hintBlock)
+            hintBlock.y = 0
+            hintBlock.x = this._hintData.linePos[info.column]
+        }
+    }
+
+    //创建最底层的一套方块
+    private makeBottomBlock(isStart = false) {
+        if (this.nextBlockInfo.length == 0) {
+            this.readyMakeBottomBlock()
+        }
+        this._mask.active = true
+        let result = this.upAllLine()
+        Promise.all(result).then(() => {
+            //创建方块在下一层
+            for (let i = 0; i < this.nextBlockInfo.length; i++) {
+                let lineData = this._lineDatas[10]
+                let nextBlockInfo = this.nextBlockInfo[i]
+                let color = Tools.getRandom(1, 6)
+                let block = this.getBlock(nextBlockInfo.num, color)
+                block.parent = lineData.line
+                block.name = "c_" + nextBlockInfo.column
+                block.x = lineData.linePos[nextBlockInfo.column]
+                let blockInfo: blockInfo = {
+                    node: block,
+                    column: nextBlockInfo.column,
+                    num: nextBlockInfo.num,
+                    cover: this.getCoverColumn(nextBlockInfo.column, nextBlockInfo.num),
+                    color: color
+                }
+                lineData.blockNodes.push(blockInfo)
+            }
+            this._mask.active = false
+            this.readyMakeBottomBlock()
+            if (isStart) {
+                this.makeBottomBlock()
+            } else {
+                if (CacheMgr.isNeedHint && this.hintFlag) {
+                    this.hintFlag = false
+                    this.hint_play()
+                }
+                this.downAllLine(10)
+            }
+        })
+    }
+
+    //将一行方块向上移动
+    private upLine(line: number): any[] {
+        let result = []
+        let data = this._lineDatas[line]
+        let nextData = this._lineDatas[line - 1]
+        if (data.blockNodes && data.blockNodes.length > 0) {
+            let nodesData = data.blockNodes
+            let nextNodesData = nextData.blockNodes
+            for (let i = 0; i < nodesData.length; i++) {
+                let n = nodesData[i]
+                nextNodesData.push(n)
+                n.node.parent = nextData.line
+                n.node.y = -gameConfig.gridSize //如果y = 0 的话,就没有动画做了
+                let p = new Promise((resolve, reject) => {
+                    cc.tween(n.node)
+                        .to(gameConfig.upTime, {y: 0}, {easing: 'cubicInOut'})
+                        .call(() => {
+                            resolve(true)
+                        })
+                        .start()
+                })
+                result.push(p)
+            }
+            data.blockNodes = []
+        }
+        return result
+    }
+
+    //将所有方块向上移动
+    private upAllLine(): any[] {
+        //从倒数第二行开始   依次往上移动
+        let result = []
+        for (let i = 2; i <= 10; i++) {
+            let r = this.upLine(i)
+            for (let i = 0; i < r.length; i++) {
+                result.push(r[i])
+            }
+        }
+        return result
+    }
+
+    private getCoverColumn(first: number, num: number): number[] {
+        let arr: number[] = []
+        for (let i = first; i < first + num; i++) {
+            arr.push(i)
+        }
+        return arr
+    }
+
+    private handle_block_start(e: cc.Event.EventTouch) {
+        let node: cc.Node = e.target
+        this._whiteHint.width = node.width
+        let world = node.parent.convertToWorldSpaceAR(node.position)
+        let position = this._whiteHint.parent.convertToNodeSpaceAR(world)
+        this._whiteHint.x = position.x
+        this._whiteHint.active = true
+        this.moveX = node.x
+    }
+
+    private handle_block_move(e) {
+        let node: cc.Node = e.target
+        let a = e.getDelta()
+        let world = node.parent.convertToWorldSpaceAR(node.position)
+        let position = this._whiteHint.parent.convertToNodeSpaceAR(world)
+        this._whiteHint.x = position.x
+
+        let line = Number(node.parent.name)
+        let column = Number(node.name.split("_")[1])
+        let data = this.getCanMoveMax(line, column)
+        // let position2 = node.parent.convertToNodeSpaceAR(e.getLocation())
+        let x = node.x += a.x;
+        if (data.min_x > x) {
+            x = data.min_x
+        } else if (data.max_x < x) {
+            x = data.max_x
+        }
+        node.x = x
+    }
+
+    private getCanMoveMax(line: number, column: number) {
+        let lineData = this._lineDatas[line]
+        let right_column: number = -1
+        let num: number = 0
+        let left_column: number = column
+        for (let i = 0; i < lineData.blockNodes.length; i++) {
+            let data = lineData.blockNodes[i]
+            if (data.column == column) {
+                num = data.num
+                right_column = data.cover[data.cover.length - 1]
+            }
+        }
+        let max = 0
+        let min = 0
+        //寻找左右两边最大能够移动的距离
+        while (true) {
+            right_column++
+            if (right_column > 8) {
+                max = right_column - 1
+                break
+            }
+            let flag = true
+            for (let i = 0; i < lineData.blockNodes.length; i++) {
+                let data = lineData.blockNodes[i]
+                for (let j = 0; j < data.cover.length; j++) {
+                    if (data.cover[j] == right_column) {
+                        flag = false
+                        break
+                    }
+                }
+            }
+            if (!flag) {
+                max = right_column - 1
+                break
+            } else {
+                max = right_column
+            }
+        }
+        while (true) {
+            left_column--
+            if (left_column < 1) {
+                min = left_column + 1
+                break
+            }
+            let flag = true
+            for (let i = 0; i < lineData.blockNodes.length; i++) {
+                let data = lineData.blockNodes[i]
+                for (let j = 0; j < data.cover.length; j++) {
+                    if (data.cover[j] == left_column) {
+                        flag = false
+                        break
+                    }
+                }
+            }
+            if (!flag) {
+                min = left_column + 1
+                break
+            } else {
+                min = left_column
+            }
+        }
+        let min_x = lineData.linePos[min]
+        let max_x = lineData.linePos[max - num + 1]
+
+        return {
+            min_x: min_x,
+            max_x: max_x
+        }
+    }
+
+    private handle_block_end(e) {
+        let node: cc.Node = e.target
+        let line = Number(node.parent.name)
+        let column = Number(node.name.split("_")[1])
+        this._whiteHint.active = false
+        let lineData = this._lineDatas[line]
+        this.continueXiao = 0
+        for (let i = 1; i <= 8; i++) {
+            let grid = lineData.line.getChildByName(i.toString())
+            let position = cc.v2(grid.x + grid.width / 2, grid.y + grid.height / 2)
+            if (node.getBoundingBox().contains(position)) {
+                node.x = lineData.linePos[i]
+                node.name = "c_" + i
+                for (let j = 0; j < lineData.blockNodes.length; j++) {
+                    let bInfo = lineData.blockNodes[j]
+                    if (bInfo.column == column) {
+                        bInfo.column = i
+                        bInfo.cover = this.getCoverColumn(i, bInfo.num)
+                        break
+                    }
+                }
+                break
+            }
+        }
+        if (node.x == this.moveX) {
+            this.moveX = -1
+            return
+        }
+        AudioMgr.play("move_end").then()
+        Tools.vibrateShort()
+        this.touchEndFlag = true
+        this.downAllLine(line)
+    }
+
+    //将一行方块向下移动
+    private downLine(line: number): any[] {
+        let result = []
+        let data = this._lineDatas[line]
+        let needChange: any [] = []
+        for (let i = 0; i < data.blockNodes.length; i++) {
+            //循环需要下拉行的 所有方块
+            let blockInfo = data.blockNodes[i]
+            //判断每一个方块最多可以下降到哪一行
+            let toLine = -1
+            for (let j = line + 1; j <= 10; j++) {
+                let flag = true
+                let nextData = this._lineDatas[j]
+                for (let k = 0; k < nextData.blockNodes.length; k++) {
+                    let cover = nextData.blockNodes[k].cover
+                    if (Tools.judgeArraySame(blockInfo.cover, cover)) {
+                        flag = false
+                    }
+                }
+                if (flag) {
+                    toLine = j
+                } else {
+                    break
+                }
+            }
+
+            if (toLine != -1) {
+                needChange.push({
+                    index: i,
+                    to: toLine,
+                })
+                let p = new Promise((resolve, reject) => {
+                    let n = blockInfo.node
+                    cc.tween(n)
+                        .to(gameConfig.downTime * 0.6, {y: -gameConfig.gridSize * (toLine - line)}, {easing: 'cubicInOut'})
+                        .by(gameConfig.downTime * 0.2, {y: 10},)
+                        .by(gameConfig.downTime * 0.2, {y: -10},)
+                        .union()
+                        .call(() => {
+                            n.parent = this._lineDatas[toLine].line
+                            n.y = 0
+                            resolve(true)
+                        })
+                        .start()
+                })
+                result.push(p)
+            }
+        }
+        for (let i = needChange.length - 1; i >= 0; i--) {
+            let cdata = needChange[i]
+            this._lineDatas[cdata.to].blockNodes.push(data.blockNodes[cdata.index])
+            data.blockNodes.splice(cdata.index, 1)
+        }
+        return result
+    }
+
+    //将所有方块向下移动
+    private downAllLine(line: number) {
+        //从倒数第二行开始   依次往上移动
+        this._mask.active = true
+        let result = []
+        for (let i = line; i >= 1; i--) {
+            if (i == 10) {
+                continue
+            }
+            let r = this.downLine(i)
+            for (let i = 0; i < r.length; i++) {
+                result.push(r[i])
+            }
+        }
+
+        if (result.length > 0) {
+            Promise.all(result).then(() => {
+                AudioMgr.play("down").then()
+                this.scheduleOnce(() => {
+                    this.judgeAllCanClear()
+                })
+            })
+        } else {
+            this.judgeAllCanClear()
+        }
+
+        // return result
+    }
+
+    private judgeLineCanClear(line): any {
+        let result = null
+        let blockData = this._lineDatas[line].blockNodes
+        //获取这个一行所有覆盖
+        let allCover = []
+        for (let i = 0; i < blockData.length; i++) {
+            blockData[i].cover.forEach((value) => {
+                allCover.push(value)
+            })
+        }
+        if (allCover.length >= 8) {
+            result = new Promise((resolve, reject) => {
+                cc.tween(this._lineDatas[line].line)
+                    .by(gameConfig.lineShake / 2, {x: -15},)
+                    .by(gameConfig.lineShake / 2, {x: 15},)
+                    // .by(gameConfig.lineShake / 30, {y: 2.5}, {easing: 'cubicInOut'})
+                    // .by(gameConfig.lineShake / 30, {x: 5}, {easing: 'cubicInOut'})
+                    // .by(gameConfig.lineShake / 30, {y: -5}, {easing: 'cubicInOut'})
+                    // .by(gameConfig.lineShake / 30, {y: 2.5, x: -2.5}, {easing: 'cubicInOut'})
+                    .union()
+                    // .repeat(6)
+                    .call(() => {
+                        let line_data = this._lineDatas[line]
+                        for (let i = 0; i < blockData.length; i++) {
+                            this.returnBlock(blockData[i].node)
+                        }
+                        resolve(true)
+                        line_data.blockNodes = []
+                    })
+                    .start()
+            })
+        }
+        return result
+    }
+
+    //判断所有行是否存在可以消除的行
+    private judgeAllCanClear(): any[] {
+        let result: any[] = []
+        for (let i = 1; i <= 10; i++) {
+            let r = this.judgeLineCanClear(i)
+            if (r) {
+                result.push(r)
+            }
+        }
+        if (result.length > 0) {
+            AudioMgr.play("xiaochu")
+            Tools.vibrateShort("heavy")
+            this.continueXiao += result.length
+            this.allContinueXiao += result.length
+            this.text_defen(result.length)
+            this.text_addHard()
+            Promise.all(result).then(() => {
+                this.scheduleOnce(() => {
+                    this.downAllLine(10)
+                }, 0)
+                if (CacheMgr.isNeedHint) {
+                    this.hint_hint()
+                }
+            })
+        } else {
+            //没有需要消除的,需要判断一下是不是输了 , 即第1层是不是有东西
+            if (this._lineDatas[1].blockNodes.length > 0) {
+                //todo 输了
+                this.fail_win()
+                return
+            } else if (this._lineDatas[9].blockNodes.length == 0) {
+                this.touchEndFlag = false
+                this.makeBottomBlock()
+            } else if (this.touchEndFlag) {
+                this.touchEndFlag = false
+                this.makeBottomBlock()
+            } else {
+                this._mask.active = false
+            }
+        }
+        return result
+    }
+
+    //适配边框
+    private adaptive() {
+        let top = this._content_cover.getChildByName("top")
+        let left = this._content_cover.getChildByName("left_wall")
+        let right = this._content_cover.getChildByName("right_wall")
+        let bottom = this._content_cover.getChildByName("bottom")
+
+
+        let temp = this._lineDatas[1].line.getPosition()
+        temp.y += gameConfig.gridSize
+        let left_top = this._content_cover.convertToNodeSpaceAR(this._content.convertToWorldSpaceAR(temp))
+
+        temp = Tools.getNodeFourPoint(this._lineDatas[10].line).right_down
+        let right_bottom = this._content_cover.convertToNodeSpaceAR(this._content.convertToWorldSpaceAR(temp))
+
+        top.y = left_top.y
+        top.width = this._content.width + 20
+        top.getChildByName("scoreData").getComponent(cc.Widget).updateAlignment()
+        top.getChildByName("hardLevel").getComponent(cc.Widget).updateAlignment()
+        bottom.y = right_bottom.y
+        bottom.width = this._content.width + 20
+        left.height = this._content.height + 20
+        left.x = left_top.x
+        left.y = left_top.y - this._content.height / 2
+
+        right.height = this._content.height + 20
+        right.x = right_bottom.x
+        right.y = left_top.y - this._content.height / 2
+    }
+
+    update() {
+        this._scoreLabel.string = "当前得分:" + this.score
+        this._hardLevelLabel.string = "当前难度:" + this.hardLevel.toString()
+
+        if (CacheMgr.setting.hammerNum > 0) {
+            this._hammer_icon.active = false
+            this._hammer_sprite.active = true
+            // console.log("够 的1 ")
+            this._hammer_sprite.getComponent(cc.Label).string = CacheMgr.setting.hammerNum.toString()
+        } else {
+            // console.log("不够1 ")
+            this._hammer_sprite.active = false
+            this._hammer_icon.active = true
+        }
+
+        if (CacheMgr.setting.spriteNum > 0) {
+            // console.log("狗的2 ")
+            this._sprite_icon.active = false
+            this._price_sprite.active = true
+            this._price_sprite.getComponent(cc.Label).string = CacheMgr.setting.spriteNum.toString()
+        } else {
+            // console.log("不够2 ")
+            this._price_sprite.active = false
+            this._sprite_icon.active = true
+        }
+
+    }
+
+    //更新精灵节点
+    updateSprite() {
+        this.sprite_color = Tools.getRandom(1, 6)
+        this._sprite.getChildByName("sprite").getComponent(cc.Sprite).spriteFrame = this.sprite_spriteFrame[this.sprite_color]
+    }
+
+    private fail_win() {
+        AudioMgr.play("fail")
+        Tools.vibrateLong()
+        let result: any [] = []
+        let time: number = 0
+        for (let i = 1; i <= 10; i++) {
+            let lineData = this._lineDatas[i]
+            lineData.blockNodes.forEach((value) => {
+                let node = value.node
+                let world = this._mouth.parent.convertToWorldSpaceAR(this._mouth.position)
+                let position = node.parent.convertToNodeSpaceAR(world)
+                position.x -= gameConfig.gridSize / 2
+                position.y -= gameConfig.gridSize / 2
+                // node.setAnchorPoint(0.5,0.5)
+                let p = new Promise((resolve, reject) => {
+                    cc.tween(node)
+                        .delay(time)
+                        .bezierTo(gameConfig.blockFlyTime, cc.v2(Tools.getRandom(0, 500), Tools.getRandom(0, 500)), cc.v2(Tools.getRandom(0, 500), Tools.getRandom(0, 500)), cc.v2(position))
+                        .call(() => {
+                            node.active = false
+                            node.destroy()
+                            resolve(true)
+                        })
+                        .start()
+                })
+                result.push(p);
+                time += gameConfig.blockFlyTime;
+            })
+        }
+
+        let isNewMax = false;
+        CacheMgr.gold = CacheMgr.gold + this.score;
+        if (this.score > CacheMgr.checkpoint) {
+            CacheMgr.checkpoint = this.score;
+            isNewMax = true;
+        }
+        Promise.all(result).then(() => {
+            PanelMgr.INS.openPanel({
+                panel : EndView,
+                layer : Layer.gameLayer,
+                param : {
+                    score : this.score,
+                    isNewMax : isNewMax
+                },
+                call : ()=>{
+                    PanelMgr.INS.closePanel(GameView) ;
+                }
+            })
+        });
+    }
+
+    private text_defen(n: number) {
+        let num = this.hardLevel * n * this.continueXiao
+        this.score += num
+        let node: cc.Node = null
+        node = cc.instantiate(this.get_prefab)
+        node.children[0].getComponent(cc.Label).string = num.toString()
+        this._textHint.addChild(node)
+        if (this.continueXiao > 1) {
+            node = cc.instantiate(this.nice_prefab)
+            node.children[0].getComponent(cc.Label).string = this.continueXiao.toString()
+            this._textHint.addChild(node)
+        }
+    }
+
+    private text_start() {
+        AudioMgr.play("start")
+        let text_prefab = cc.instantiate(this.start_prefab)
+        // text_prefab.getComponent(cc.Label).string = "游戏开始"
+        text_prefab.getComponent(Text).delay = 5
+        // this._textHint.addChild(text_prefab)
+        // text_prefab = cc.instantiate(this.text_prefab)
+        // text_prefab.getComponent(Text).delay = 5
+        // text_prefab.getComponent(cc.Label).string = "拖动方块,消除整行."
+        this._textHint.addChild(text_prefab)
+    }
+
+    private text_addHard() {
+        if (this.hardLevel >= gameConfig.grade_of_difficulty_config.length - 1) {
+            return
+        }
+        if (this.allContinueXiao >= 10) {
+            this.hardLevel++
+            this.allContinueXiao = 2
+            let text_prefab = cc.instantiate(this.hardUp_prefab)
+            // text_prefab.getComponent(cc.Label).string = "难度提升,得分X" + this.hardLevel
+            text_prefab.children[0].getComponent(cc.Label).string = this.hardLevel.toString()
+            text_prefab.getComponent(Text).delay = 5
+            this._textHint.addChild(text_prefab)
+        }
+    }
+
+    private handle_hammer() {
+        if (this._hint_hammer.active) {
+            return;
+        }
+        if (CacheMgr.setting.hammerNum <= 0) {
+            Tools.handleVideo().then((res) => {
+                if (!res) {
+                    return;
+                }
+                //判断是否存在3个的方块
+                let dataBeChui: any [] = []
+                for (let i = 1; i <= 10; i++) {
+                    this._lineDatas[i].blockNodes.forEach((value) => {
+                        if (value.num >= 3) {
+                            dataBeChui.push({
+                                line: i,
+                                column: value.column
+                            })
+                        }
+                    })
+                }
+                if (dataBeChui.length == 0) {
+                    this._hint_hammer.active = true
+                    // Tools.changeGold(gameConfig.price)
+                    this.scheduleOnce(() => {
+                        this._hint_hammer.active = false
+                    }, gameConfig.hide_hint_sprite)
+                    CacheMgr.setting.hammerNum++
+                    CacheMgr.setting = CacheMgr.setting
+                    return
+                }
+
+                this._mask.active = true
+                let pss = []
+                let needDelete: Map<number, number[]> = new Map<number, number[]>()
+                dataBeChui.forEach((value) => {
+                    let pp = new Promise((resolve, reject) => {
+                        let lineData = this._lineDatas[value.line]
+                        let idx = 0
+                        lineData.blockNodes.forEach((value2, index) => {
+                            if (value2.column == value.column) {
+                                idx = index
+                            }
+                        })
+                        let oldBlock = lineData.blockNodes[idx]
+                        let ps = []
+                        for (let i = 0; i < oldBlock.cover.length; i++) {
+                            let h = cc.instantiate(this.hammer_prefab)
+                            h.width = gameConfig.gridSize
+                            h.height = gameConfig.gridSize
+                            let world = oldBlock.node.parent.convertToWorldSpaceAR(oldBlock.node.position)
+                            this._content.addChild(h)
+                            h.position = h.parent.convertToNodeSpaceAR(world)
+                            h.x += oldBlock.node.width / 2
+                            h.y += oldBlock.node.height / 2
+                            let p = new Promise((resolve, reject) => {
+                                cc.tween(h)
+                                    .delay(0.5)
+                                    .to(gameConfig.hammerRotation, {angle: 30}, {easing: 'cubicInOut'})
+                                    .call(() => {
+                                        cc.tween(oldBlock.node)
+                                            .by(gameConfig.lineShake / 2, {x: -15},)
+                                            .by(gameConfig.lineShake / 2, {x: 15},)
+                                            .union()
+                                            .call(() => {
+                                                h.active = false
+                                                h.destroy()
+                                                let node = this.getBlock(1, oldBlock.color)
+                                                node.y = 0
+                                                node.x = lineData.linePos[oldBlock.cover[i]]
+                                                node.name = "c_" + oldBlock.cover[i]
+                                                lineData.line.addChild(node)
+                                                lineData.blockNodes.push({
+                                                    node: node,
+                                                    column: oldBlock.cover[i],
+                                                    num: 1,
+                                                    cover: [oldBlock.cover[i]],
+                                                    color: oldBlock.color,
+                                                })
+                                                resolve(true)
+                                            })
+                                            .start()
+                                    })
+                                    .start()
+                            })
+                            ps.push(p)
+                        }
+                        Promise.all(ps).then(() => {
+                            this.returnBlock(oldBlock.node)
+                            // needDelete.push({
+                            //     line: value.line,
+                            //     idx: idx
+                            // })
+                            if (!needDelete.has(value.line)) {
+                                needDelete.set(value.line, [])
+                            }
+                            needDelete.get(value.line).push(idx)
+                            // lineData.blockNodes.splice(idx, 1)
+                            resolve(true)
+                        })
+                    })
+                    pss.push(pp)
+                })
+
+
+                this.scheduleOnce(() => {
+                    AudioMgr.play("knock")
+                }, 0.5)
+                Promise.all(pss).then(() => {
+                    this._mask.active = false
+                    needDelete.forEach((value, key) => {
+                        for (let i = this._lineDatas[key].blockNodes.length - 1; i >= 0; i--) {
+                            if (Tools.JudgeValueInArr(i, value)) {
+                                this._lineDatas[key].blockNodes.splice(i, 1)
+                            }
+                        }
+                    })
+
+                    this.scheduleOnce(() => {
+                        this.downAllLine(10)
+                    }, 0)
+                })
+            })
+
+        } else {
+            //判断是否存在3个的方块
+            let dataBeChui: any [] = []
+            for (let i = 1; i <= 10; i++) {
+                this._lineDatas[i].blockNodes.forEach((value) => {
+                    if (value.num >= 3) {
+                        dataBeChui.push({
+                            line: i,
+                            column: value.column
+                        })
+                    }
+                })
+            }
+            if (dataBeChui.length == 0) {
+                this._hint_hammer.active = true
+                // Tools.changeGold(gameConfig.price)
+                this.scheduleOnce(() => {
+                    this._hint_hammer.active = false
+                }, gameConfig.hide_hint_sprite)
+                return
+            }
+
+            CacheMgr.setting.hammerNum--
+            CacheMgr.setting = CacheMgr.setting
+            this._mask.active = true
+            let pss = []
+            let needDelete: Map<number, number[]> = new Map<number, number[]>()
+            dataBeChui.forEach((value) => {
+                let pp = new Promise((resolve, reject) => {
+                    let lineData = this._lineDatas[value.line]
+                    let idx = 0
+                    lineData.blockNodes.forEach((value2, index) => {
+                        if (value2.column == value.column) {
+                            idx = index
+                        }
+                    })
+                    let oldBlock = lineData.blockNodes[idx]
+                    let ps = []
+                    for (let i = 0; i < oldBlock.cover.length; i++) {
+                        let h = cc.instantiate(this.hammer_prefab)
+                        h.width = gameConfig.gridSize
+                        h.height = gameConfig.gridSize
+                        let world = oldBlock.node.parent.convertToWorldSpaceAR(oldBlock.node.position)
+                        this._content.addChild(h)
+                        h.position = h.parent.convertToNodeSpaceAR(world)
+                        h.x += oldBlock.node.width / 2
+                        h.y += oldBlock.node.height / 2
+                        let p = new Promise((resolve, reject) => {
+                            cc.tween(h)
+                                .delay(0.5)
+                                .to(gameConfig.hammerRotation, {angle: 30}, {easing: 'cubicInOut'})
+                                .call(() => {
+                                    cc.tween(oldBlock.node)
+                                        .by(gameConfig.lineShake / 2, {x: -15},)
+                                        .by(gameConfig.lineShake / 2, {x: 15},)
+                                        .union()
+                                        .call(() => {
+                                            h.active = false
+                                            h.destroy()
+                                            let node = this.getBlock(1, oldBlock.color)
+                                            node.y = 0
+                                            node.x = lineData.linePos[oldBlock.cover[i]]
+                                            node.name = "c_" + oldBlock.cover[i]
+                                            lineData.line.addChild(node)
+                                            lineData.blockNodes.push({
+                                                node: node,
+                                                column: oldBlock.cover[i],
+                                                num: 1,
+                                                cover: [oldBlock.cover[i]],
+                                                color: oldBlock.color,
+                                            })
+                                            resolve(true)
+                                        })
+                                        .start()
+                                })
+                                .start()
+                        })
+                        ps.push(p)
+                    }
+                    Promise.all(ps).then(() => {
+                        this.returnBlock(oldBlock.node)
+                        // needDelete.push({
+                        //     line: value.line,
+                        //     idx: idx
+                        // })
+                        if (!needDelete.has(value.line)) {
+                            needDelete.set(value.line, [])
+                        }
+                        needDelete.get(value.line).push(idx)
+                        // lineData.blockNodes.splice(idx, 1)
+                        resolve(true)
+                    })
+                })
+                pss.push(pp)
+            })
+
+
+            this.scheduleOnce(() => {
+                AudioMgr.play("knock")
+            }, 0.5)
+            Promise.all(pss).then(() => {
+                this._mask.active = false
+                needDelete.forEach((value, key) => {
+                    for (let i = this._lineDatas[key].blockNodes.length - 1; i >= 0; i--) {
+                        if (Tools.JudgeValueInArr(i, value)) {
+                            this._lineDatas[key].blockNodes.splice(i, 1)
+                        }
+                    }
+                })
+
+                this.scheduleOnce(() => {
+                    this.downAllLine(10)
+                }, 0)
+            })
+
+        }
+    }
+
+    private handle_sprite() {
+        if (this._hint_sprite.active) {
+            return;
+        }
+
+        if (CacheMgr.setting.spriteNum <= 0) {
+            Tools.handleVideo().then((res) => {
+                if (!res) {
+                    return;
+                }
+                let needDelData: Map<number, number[]> = new Map<number, number[]>()
+                let ps = []
+                //遍历颜色
+                for (let i = 1; i <= 10; i++) {
+                    let blockInfo = this._lineDatas[i].blockNodes
+                    blockInfo.forEach((value, index) => {
+                        if (value.color == this.sprite_color) {
+                            if (!needDelData.has(i)) {
+                                needDelData.set(i, [])
+                            }
+                            needDelData.get(i).push(index)
+                            let sprite_node = cc.instantiate(this.sprite_prefab)
+                            sprite_node.scale = gameConfig.gridSize / sprite_node.width
+                            this.node.addChild(sprite_node)
+                            sprite_node.position = sprite_node.parent.convertToNodeSpaceAR(this._sprite.parent.convertToWorldSpaceAR(this._sprite.position))
+                            sprite_node.getComponent(cc.Sprite).spriteFrame = this.sprite_spriteFrame[this.sprite_color]
+                            let p = new Promise((resolve, reject) => {
+                                let world = value.node.parent.convertToWorldSpaceAR(value.node.position)
+                                let position = sprite_node.parent.convertToNodeSpaceAR(world)
+                                position.x += value.node.width / 2
+                                position.y += value.node.height / 2
+                                cc.tween(sprite_node)
+                                    .bezierTo(gameConfig.sprite_move, cc.v2(Tools.getRandom(-500, 500), Tools.getRandom(-500, 500)), cc.v2(Tools.getRandom(-500, 500), Tools.getRandom(-500, 500)), cc.v2(position))
+                                    .call(() => {
+                                        cc.tween(sprite_node)
+                                            .by(gameConfig.sprite_jump / 2, {y: 20}, {easing: 'cubicInOut'})
+                                            .by(gameConfig.sprite_jump / 2, {y: -20}, {easing: 'cubicInOut'})
+                                            .union()
+                                            .call(() => {
+                                                cc.tween(value.node)
+                                                    .by(gameConfig.lineShake / 2, {x: -15},)
+                                                    .by(gameConfig.lineShake / 2, {x: 15},)
+                                                    .union()
+                                                    .call(() => {
+                                                        sprite_node.active = false
+                                                        value.node.active = false
+                                                        value.node.destroy()
+                                                        resolve(true)
+                                                    })
+                                                    .start()
+                                            })
+                                            .start()
+                                    })
+                                    .start()
+                            })
+                            ps.push(p)
+                        }
+                    })
+                }
+                if (needDelData.size == 0) {
+                    this._hint_sprite.active = true
+                    // Tools.changeGold(gameConfig.price)
+                    this.scheduleOnce(() => {
+                        this._hint_sprite.active = false
+                    }, gameConfig.hide_hint_sprite)
+                    CacheMgr.setting.spriteNum++
+                    CacheMgr.setting = CacheMgr.setting
+                    console.log("加上一次提示机会", CacheMgr.setting)
+                    return
+                }
+                // AudioMgr.play("sprite_move")
+                this._mask.active = true
+                Promise.all(ps).then(() => {
+                    AudioMgr.play("sprite_xiaochu")
+                    needDelData.forEach((value, key) => {
+                        for (let i = this._lineDatas[key].blockNodes.length - 1; i >= 0; i--) {
+                            if (Tools.JudgeValueInArr(i, value)) {
+                                this._lineDatas[key].blockNodes.splice(i, 1)
+                            }
+                        }
+                    })
+                    this.updateSprite()
+                    this.scheduleOnce(() => {
+                        this.downAllLine(10)
+                    }, 0)
+                    this._mask.active = false
+                })
+            })
+        } else {
+            let needDelData: Map<number, number[]> = new Map<number, number[]>()
+            let ps = []
+            //遍历颜色
+            for (let i = 1; i <= 10; i++) {
+                let blockInfo = this._lineDatas[i].blockNodes
+                blockInfo.forEach((value, index) => {
+                    if (value.color == this.sprite_color) {
+                        if (!needDelData.has(i)) {
+                            needDelData.set(i, [])
+                        }
+                        needDelData.get(i).push(index)
+                        let sprite_node = cc.instantiate(this.sprite_prefab)
+                        sprite_node.scale = gameConfig.gridSize / sprite_node.width
+                        this.node.addChild(sprite_node)
+                        sprite_node.position = sprite_node.parent.convertToNodeSpaceAR(this._sprite.parent.convertToWorldSpaceAR(this._sprite.position))
+                        sprite_node.getComponent(cc.Sprite).spriteFrame = this.sprite_spriteFrame[this.sprite_color]
+                        let p = new Promise((resolve, reject) => {
+                            let world = value.node.parent.convertToWorldSpaceAR(value.node.position)
+                            let position = sprite_node.parent.convertToNodeSpaceAR(world)
+                            position.x += value.node.width / 2
+                            position.y += value.node.height / 2
+                            cc.tween(sprite_node)
+                                .bezierTo(gameConfig.sprite_move, cc.v2(Tools.getRandom(-500, 500), Tools.getRandom(-500, 500)), cc.v2(Tools.getRandom(-500, 500), Tools.getRandom(-500, 500)), cc.v2(position))
+                                .call(() => {
+                                    cc.tween(sprite_node)
+                                        .by(gameConfig.sprite_jump / 2, {y: 20}, {easing: 'cubicInOut'})
+                                        .by(gameConfig.sprite_jump / 2, {y: -20}, {easing: 'cubicInOut'})
+                                        .union()
+                                        .call(() => {
+                                            cc.tween(value.node)
+                                                .by(gameConfig.lineShake / 2, {x: -15},)
+                                                .by(gameConfig.lineShake / 2, {x: 15},)
+                                                .union()
+                                                .call(() => {
+                                                    sprite_node.active = false
+                                                    value.node.active = false
+                                                    value.node.destroy()
+                                                    resolve(true)
+                                                })
+                                                .start()
+                                        })
+                                        .start()
+                                })
+                                .start()
+                        })
+                        ps.push(p)
+                    }
+                })
+            }
+            if (needDelData.size == 0) {
+                this._hint_sprite.active = true
+                // Tools.changeGold(gameConfig.price)
+                this.scheduleOnce(() => {
+                    this._hint_sprite.active = false
+                }, gameConfig.hide_hint_sprite)
+                return
+            }
+            CacheMgr.setting.spriteNum--
+            CacheMgr.setting = CacheMgr.setting
+            // AudioMgr.play("sprite_move")
+            this._mask.active = true
+            Promise.all(ps).then(() => {
+                AudioMgr.play("sprite_xiaochu")
+                needDelData.forEach((value, key) => {
+                    for (let i = this._lineDatas[key].blockNodes.length - 1; i >= 0; i--) {
+                        if (Tools.JudgeValueInArr(i, value)) {
+                            this._lineDatas[key].blockNodes.splice(i, 1)
+                        }
+                    }
+                })
+                this.updateSprite()
+                this.scheduleOnce(() => {
+                    this.downAllLine(10)
+                }, 0)
+                this._mask.active = false
+            })
+        }
+    }
+
+    private handle_menu() {
+        // this._menuPanel.active = !this._menuPanel.active
+        if (this._menuPanel.y > this._menu.y) {
+            if (this._menuPanel.y != this._menu.y + this._menu.height) {
+                return
+            }
+            tween(this._menuPanel)
+                .to(gameConfig.menu_box_move, {y: this._menu.y}, {easing: 'cubicInOut'})
+                .call(() => {
+
+                    this.scheduleOnce(() => {
+                        this._menuPanel.active = false
+                    })
+                })
+                .start()
+        } else {
+            this._menuPanel.active = true
+            tween(this._menuPanel)
+                .to(gameConfig.menu_box_move, {y: this._menu.y + this._menu.height})
+                .start()
+        }
+    }
+
+    //重新开始
+    private handle_restart() {
+        for (let i = 1; i <= 10; i++) {
+            let lineData = this._lineDatas[i]
+            lineData.blockNodes.forEach((value) => {
+                this.returnBlock(value.node)
+            })
+            lineData.blockNodes = []
+        }
+        this.continueXiao = 0
+        this.allContinueXiao = 0
+        this.hardLevel = 1
+        this.score = 0
+        this.makeBottomBlock(true)
+    }
+
+    //返回首页
+    private handle_return() {
+        PanelMgr.INS.openPanel({
+            panel : HomeView,
+            layer : Layer.gameLayer,
+            call : ()=>{
+                PanelMgr.INS.closePanel(GameView) ;
+            }
+        })
+    }
+
+
+    update_hintMask() {
+        if (this._hint_mask) {
+            this._hint_mask.children[0].x = -this._hint_mask.position.x
+            this._hint_mask.children[0].y = -this._hint_mask.position.y
+        }
+    }
+
+    hint_play() {
+        this._hint_mask.active = true
+        this._hint_mask.width = this._lineDatas[10].line.width
+        this._hint_mask.height = this._lineDatas[10].line.height * 2
+        this._hint_mask.position = this._lineDatas[10].line.position
+        for (let i = 9; i <= 10; i++) {
+            if (i == 10) {
+                this._lineDatas[i].blockNodes.forEach((value) => {
+                    let node = value.node
+                    node.off(cc.Node.EventType.TOUCH_START, this.handle_block_start, this)
+                    node.off(cc.Node.EventType.TOUCH_MOVE, this.handle_block_move, this)
+                    node.off(cc.Node.EventType.TOUCH_END, this.handle_block_end, this)
+                    node.off(cc.Node.EventType.TOUCH_CANCEL, this.handle_block_end, this)
+                })
+            } else {
+                this._lineDatas[i].blockNodes.forEach((value) => {
+                    if (value.column != 6) {
+                        let node = value.node
+                        node.off(cc.Node.EventType.TOUCH_START, this.handle_block_start, this)
+                        node.off(cc.Node.EventType.TOUCH_MOVE, this.handle_block_move, this)
+                        node.off(cc.Node.EventType.TOUCH_END, this.handle_block_end, this)
+                        node.off(cc.Node.EventType.TOUCH_CANCEL, this.handle_block_end, this)
+                    }
+                })
+            }
+        }
+        // this._hint_label.getComponent(cc.Label).string = "按住方块,向左拖动1格"
+        this._hint_label.getComponent(cc.Sprite).spriteFrame = this.hint_1_spriteFrame
+        this._hint_label.y = this._hint_mask.y + this._hint_mask.height
+        this._hint_label.active = true
+
+        this._hint_hand.active = true
+        this._hint_hand.width = gameConfig.gridSize
+        this._hint_hand.height = gameConfig.gridSize
+        let p = cc.v3(this._lineDatas[9].linePos[6])
+        let startWorld = this._lineDatas[9].line.convertToWorldSpaceAR(p)
+        let startPosition = this.node.convertToNodeSpaceAR(startWorld)
+
+        startPosition.x += gameConfig.gridSize / 2
+        startPosition.y -= gameConfig.gridSize / 2
+
+        let p2 = cc.v3(this._lineDatas[9].linePos[5])
+        let endWorld = this._lineDatas[9].line.convertToWorldSpaceAR(p2)
+        let endPosition = this.node.convertToNodeSpaceAR(endWorld)
+        endPosition.y -= gameConfig.gridSize / 2
+        this._hint_hand.position = startPosition
+        tween(this._hint_hand)
+            .to(gameConfig.hint_hand_move, {position: endPosition})
+            .to(0, {position: startPosition})
+            .union()
+            .repeatForever()
+            .start()
+
+        this.update_hintMask()
+    }
+
+    hint_hint() {
+        this._hint_mask.width = this._hintUI.width
+        this._hint_mask.height = this._hintUI.height
+        this._hint_mask.position = this._hintUI.position
+        this._hint_hand.active = false
+
+        // this._hint_label.getComponent(cc.Label).string = "这里是下一行即将出现的方块(点击空白继续)"
+        this._hint_label.getComponent(cc.Sprite).spriteFrame = this.hint_2_spriteFrame
+        this._hint_label.y = this._hint_mask.y + this._hint_mask.height
+        this._hint_label.active = true
+        this.update_hintMask()
+        this.hint_register()
+
+        CacheMgr.isNeedHint = false
+        this._hint_mask.active = false
+        this.scheduleOnce(() => {
+            tween(this._hint_label)
+                .to(1, {opacity: 0})
+                .call(() => {
+                    this._hint_label.active = false
+                })
+                .start()
+        }, 4)
+    }
+
+    hint_register() {
+        this._lineDatas[9].blockNodes.forEach((value) => {
+            let block = value.node
+            block.on(cc.Node.EventType.TOUCH_START, this.handle_block_start, this)
+            block.on(cc.Node.EventType.TOUCH_MOVE, this.handle_block_move, this)
+            block.on(cc.Node.EventType.TOUCH_END, this.handle_block_end, this)
+            block.on(cc.Node.EventType.TOUCH_CANCEL, this.handle_block_end, this)
+        })
+    }
+
+    //重写 gameBoxScroll 滚动方向
+    protected gameBoxScrollViewDirection(): string {
+        return "v"
+    }
+
+}
+
+interface lineData {
+    line: cc.Node
+    linePos: number[]
+    blockNodes: blockInfo[]
+}
+
+export interface nextBlockInfo {
+    num: number
+    column: number
+}
+
+interface blockInfo {
+    node: cc.Node,
+    column: number,
+    num: number,
+    cover: number[],
+    color: number
+}

+ 9 - 0
assets/Script/Moudle/View/GameView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "bfce9dce-6c7f-4305-b457-7808df5cae41",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 98 - 0
assets/Script/Moudle/View/HomeView.ts

@@ -0,0 +1,98 @@
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import GameInfoView from "./GameInfoView";
+import GameView from "./GameView";
+import Shop from "./logic/game/shop";
+import Sign from "./logic/game/sign";
+
+import PanelMgr, {Layer} from "../../Common/manage/PanelMgr";
+import ShowConfig from "../../Common/ShowConfig";
+import QgBanner from "../../Common/manage/Api/QgBanner";
+import Global from "../../Common/Global";
+import Emit from "../../Common/manage/Emit/Emit";
+import EmitData from "../../Common/manage/Emit/EmitData";
+import QgApi from "../../Common/manage/Api/QgApi";
+
+const {ccclass} = cc._decorator;
+@ccclass
+export default class HomeView extends LayerPanel {
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "homeView",
+            name: "homeView"
+        }
+    }
+    private _exportData: any = null;
+
+    //node
+    private _button: cc.Node = null;
+    private _setting: cc.Node = null;
+    private _shopBtn: cc.Node = null ;
+    private _shortBtn : cc.Node = null ;
+    public initUI() {
+        //todo 逻辑
+        PanelMgr.INS.openPanel({
+            panel: GameInfoView,
+            layer: Layer.gameInfoLayer,
+        })
+
+        this._button = this.getNode("next");
+        this.onTouch(this._button, () => {
+            PanelMgr.INS.openPanel({
+                panel : GameView,
+                layer : Layer.gameLayer,
+                call : ()=>{
+                    PanelMgr.INS.closePanel(HomeView) ;
+                    PanelMgr.INS.closePanel(Shop) ;
+                    PanelMgr.INS.closePanel(Sign) ;
+                }
+            })
+        });
+
+        this._setting = this.getNode("setting")
+
+        this._shopBtn = this.getNode("bottomUI/shopIcon")
+        this.onTouch(this._shopBtn, () => {
+            PanelMgr.INS.openPanel({
+                panel : Shop,
+                layer : Layer.gameLayer
+            })
+        })
+
+        //下面是原始的代码
+
+        // this._shortBtn = this.getNode('shortBtn') ;
+
+        // QgApi.judgeShortIcon().then((res : boolean)=>{
+        //     this._shortBtn.active = res;
+        // })
+
+        // this.onTouch(this._shortBtn, () => {
+        //     QgApi.addShortcutIcon().then((res)=>{
+        //         if (res) {
+        //             this._shortBtn.active = false ;
+        //         }
+        //     })
+        // })
+    }
+
+    public show(param: any) {
+        ShowConfig.show('homeConfig').then((res) => {
+            if (Global.config.homeConfig.bannerShow == 1) {
+                QgBanner.showBanner();
+            } else {
+                QgBanner.hideBanner();
+            }
+        });
+    }
+
+    public hide() {
+
+        if (Global.config.homeConfig.nativeConfig.type == 2) {
+            Emit.instance().emit(EmitData.CLOSE_NATIVE) ;
+        }
+    }
+
+
+
+    //todo logic 方法
+}

+ 9 - 0
assets/Script/Moudle/View/HomeView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "cb3bf15e-d161-4f20-9a4a-5edd68e05e45",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 189 - 0
assets/Script/Moudle/View/NativeView.ts

@@ -0,0 +1,189 @@
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import Texture2D = cc.Texture2D;
+import QgNative from "../../Common/manage/Api/QgNative";
+import Emit from "../../Common/manage/Emit/Emit";
+import EmitData from "../../Common/manage/Emit/EmitData";
+import QgBanner from "../../Common/manage/Api/QgBanner";
+import PanelMgr from "../../Common/manage/PanelMgr";
+
+const {ccclass, property} = cc._decorator;
+
+const {TOUCH_START} = cc.Node.EventType ;
+
+@ccclass
+export default class NativeView extends LayerPanel {
+
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "nativeView",
+            name: "nativeView"
+        }
+    }
+
+    @property(cc.Node)
+    native_inters: cc.Node = null;
+
+    @property(cc.Node)
+    native_implant: cc.Node = null;
+
+    private nativeMessage : any = null ;
+
+    private currSprite : cc.Texture2D = null ;
+
+    private adId : string = null ;
+
+    private labelType : number = null ;
+
+    private labelArr : string[] = ['点击查看','点击跳过'] ;
+
+    private type : number = null ;
+
+    initUI() {
+        this.initTouch() ;
+    }
+
+    show(param: any): void {
+        this.node.getChildByName('inputEvent').active = false ;
+        this.node.getChildByName('inputEvent_implant').active = false ;
+
+        this.native_inters.active = false ;
+        this.native_implant.active = false ;
+
+        this.labelType = param.labelType ;
+        this.type = param.type ;
+
+        this.scheduleOnce(()=>{
+            if (QgNative.nativeMessage != null) {
+                this.nativeMessage = QgNative.nativeMessage ;
+                this.open_type(param.type) ;
+            }else {
+                QgNative.loadNative().then((res)=>{
+                    if (res && res != false) {
+                        this.nativeMessage = res ;
+                        this.open_type(param.type) ;
+                    }else {
+
+                    }
+                })
+            }
+        },param.time) ;
+
+        if (this.type == 2) {
+            Emit.instance().on(EmitData.CLOSE_NATIVE,this.closeNative,this) ;
+        }
+
+    }
+
+    openNative (node : cc.Node) {
+        node.getChildByName('title').getComponent(cc.Label).string = this.nativeMessage.desc ;
+
+        let imgUrl = null ;
+        if (this.nativeMessage.imgUrlList && this.nativeMessage.imgUrlList.length > 0) {
+            imgUrl = this.nativeMessage.imgUrlList[0] ;
+        }
+
+        if (imgUrl != null) {
+            cc.assetManager.loadRemote(imgUrl,{ext: '.png'},(err, asset : Texture2D)=>{
+                if (err) {
+                    console.error('原生广告图片加载错误>>>>>>',err) ;
+                    return
+                }
+
+                this.currSprite = asset ;
+                node.getChildByName('image').getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(this.currSprite) ;
+
+            })
+        }
+
+        this.adId = this.nativeMessage.adId ;
+        QgNative.repAdShow(this.nativeMessage.adId) ;
+
+    }
+
+    open_type (type) {
+        if (!this.nativeMessage)  {
+            return
+        }
+
+        if (type == 1) {
+            this.node.getChildByName('inputEvent').active = true ;
+
+            this.native_inters.getChildByName('nativeBtn').getChildByName('label').getComponent(cc.Label).string = this.labelArr[this.labelType - 1] ;
+
+            this.native_inters.getChildByName('close').active = false ;
+            this.native_inters.active = true ;
+            this.scheduleOnce(()=>{
+                this.native_inters.getChildByName('close').active = true ;
+            },2)
+
+            this.openNative(this.native_inters) ;
+        }
+
+        if (type == 2) {
+            QgBanner.hideBanner() ;
+            this.node.getChildByName('inputEvent_implant').active = true ;
+
+            this.native_implant.getChildByName('nativeBtn').getChildByName('label').getComponent(cc.Label).string = this.labelArr[this.labelType - 1] ;
+
+            this.native_implant.getChildByName('close').active = false ;
+            this.native_implant.active = true ;
+            this.scheduleOnce(()=>{
+                this.native_implant.getChildByName('close').active = true ;
+            },2)
+
+            this.openNative(this.native_implant) ;
+        }
+
+    }
+
+    initTouch () {
+        this.native_inters.getChildByName('image').on(TOUCH_START,()=>{
+            QgNative.repAdClick(this.adId) ;
+        })
+
+        this.native_implant.getChildByName('image').on(TOUCH_START,()=>{
+            QgNative.repAdClick(this.adId) ;
+        })
+
+        this.native_inters.getChildByName('nativeBtn').on(TOUCH_START,()=>{
+            this.handlerNativeBtn() ;
+        })
+
+        this.native_implant.getChildByName('nativeBtn').on(TOUCH_START,()=>{
+            this.handlerNativeBtn() ;
+        })
+
+        this.native_inters.getChildByName('close').on(TOUCH_START,()=>{
+            this.closeNative() ;
+        })
+
+        this.native_implant.getChildByName('close').on(TOUCH_START,()=>{
+            this.closeNative() ;
+        })
+
+    }
+
+    handlerNativeBtn () {
+       if (this.labelType == 1)  {
+           QgNative.repAdClick(this.adId) ;
+       }else {
+           this.closeNative() ;
+       }
+    }
+
+    hide() {
+        QgNative.anewLoad() ;
+        Emit.instance().emit(EmitData.IN_NATIVE_NEXT) ;
+        if (this.type == 2) {
+            QgBanner.showBanner() ;
+            Emit.instance().off(EmitData.CLOSE_NATIVE,this.closeNative,this) ;
+        }
+    }
+
+    closeNative() {
+        PanelMgr.INS.closePanel(NativeView,false) ;
+    }
+
+
+    // update (dt) {}
+}

+ 9 - 0
assets/Script/Moudle/View/NativeView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "1918abc1-b5c7-40bf-b1d3-c07761510f75",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 116 - 0
assets/Script/Moudle/View/ShortageView.ts

@@ -0,0 +1,116 @@
+import LayerPanel, {UrlInfo} from "../../Common/manage/Layer/LayerPanel";
+import Global from "../../Common/Global";
+import LoadMgr from "../../Common/manage/LoadMgr";
+import GameLog from "../../Common/manage/GameLogMgr";
+import CacheMgr from "../../Common/manage/CacheMgr";
+import Tools from "../../Common/Tools";
+import url = cc.url;
+import PanelMgr from "../../Common/manage/PanelMgr";
+
+const {ccclass, property} = cc._decorator;
+@ccclass
+export default class ShortageView extends LayerPanel {
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "shortageView",
+            name: "shortageView"
+        }
+    }
+
+    //node
+    private _image: cc.Node = null;
+    private _button: cc.Node = null;
+    private _skipButton: cc.Node = null;
+    private _addNum: cc.Node = null
+
+    private callBack: Function = null;  // 玩家领取成功对应的道具 回调
+    private price: number = 0; //当前逻辑所需要的消耗数量
+
+    public initUI() {
+        this._image = this.getNode("image");
+        this._button = this.getNode("button");
+        this._skipButton = this.getNode("skip");
+        this._addNum = this.getNode("add_num")
+    }
+
+    /**
+     * @param param  {
+     *     type  :   string   不足类型  例如   gold : 金币  st
+     *     callBack : Function  //回调
+     *     price :   number   本次展示观看视频成功之后,回调执行条件价格
+     * }
+     */
+    public show(param: any) {
+        try {
+            let type: string = ""
+            if (param) {
+                this.callBack = param.callBack;
+                this.price = param.price;
+                type = param.type;
+            }
+
+            this._image.active = false;
+            this._skipButton.active = false;
+            this._button.active = false;
+
+            this.replaceSprite(this._image, type);
+            this.replaceSprite(this._skipButton, type);
+            this.replaceSprite(this._button, type);
+
+            let addNum = Global.config.addInfo[type]
+            this._addNum.getComponent(cc.Label).string = "+" + addNum
+
+            this.onTouch(this._button, () => {
+                Tools.handleVideo().then((res) => {
+                    if (res) {
+                        if (type == "gold") {
+                            CacheMgr.gold = CacheMgr.gold + addNum
+                            PanelMgr.INS.closePanel(ShortageView)
+                            if (this.callBack && CacheMgr.gold >= this.price) {
+                                CacheMgr.gold = CacheMgr.gold - this.price
+                                this.callBack()
+                            }
+                        } else if (type == "diamond") {
+                            CacheMgr.diamond = CacheMgr.diamond + addNum
+                            PanelMgr.INS.closePanel(ShortageView)
+                            if (this.callBack && CacheMgr.diamond >= this.price) {
+                                CacheMgr.diamond = CacheMgr.diamond - this.price
+                                this.callBack()
+                            }
+                        } else if (type == "stamina") {
+                            CacheMgr.stamina = CacheMgr.stamina + addNum
+                            PanelMgr.INS.closePanel(ShortageView)
+                            if (this.callBack && CacheMgr.stamina >= this.price) {
+                                CacheMgr.stamina = CacheMgr.stamina - this.price
+                                this.callBack()
+                            }
+                        }
+                    }
+                });
+            });
+
+            this.onTouch(this._skipButton, () => {
+                PanelMgr.INS.closePanel(ShortageView)
+            });
+
+            this.node.active = true;
+        } catch (e) {
+            GameLog.error('home show error ');
+        }
+    }
+
+    //替换图片
+    public replaceSprite(node: cc.Node, type: string) {
+        if (!node || !type) {
+            return;
+        }
+        let sprite = node.getComponent(cc.Sprite)
+        if (!sprite) {
+            return;
+        }
+        LoadMgr.loadSprite(sprite, "view/shortage/" + type + "/" + node.name).then();
+    }
+
+    public hide() {
+    }
+}

+ 9 - 0
assets/Script/Moudle/View/ShortageView.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "9bbd6735-26fe-4893-9833-4111372366ec",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Moudle/View/logic.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "3b615ec2-2ec7-40f1-b3ec-fd8b293152b2",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Moudle/View/logic/common.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "f7560906-808c-4084-b726-d3c384d00d13",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 173 - 0
assets/Script/Moudle/View/logic/common/config.ts

@@ -0,0 +1,173 @@
+import {nextBlockInfo} from "../../GameView";
+import Tools from "../../../../Common/Tools";
+import CacheMgr from "../../../../Common/manage/CacheMgr";
+
+export default class gameConfig {
+    //GameConfig
+    public static gridSize: number = 90  // 格子长宽
+    //生成方块空白格子区间
+    public static bottomBlankMin: number = 1
+    public static bottomBlankMax: number = 3
+
+    public static price: number = 30 //道具金币
+    //商城价格
+    public static price_hammer: number = 200
+    public static price_sprite: number = 200
+    public static price_stamina: number = 300
+    //时间
+    public static upTime: number = 0.3
+    public static downTime: number = 0.2
+    public static lineShake: number = 0.3
+    public static blockFlyTime: number = 0.1
+    public static hammerRotation: number = 0.1
+    public static hide_hint_sprite: number = 1 //隐藏提示图片时间
+    public static sprite_move: number = 0.5
+    public static sprite_jump: number = 0.5
+    public static xinjilu: number = 2
+    public static hint_hand_move: number = 1 //提示手指移动时间
+    public static menu_box_move: number = 0.2
+    //签到
+    public static signData: signData[] = [
+        {
+            type: 1,
+            num: 300,
+            title: "金币300",
+            func: (num: number) => {
+                Tools.changeGold(num)
+            }
+        },
+        {
+            type: 2,
+            num: 2,
+            title: "锤子2个",
+            func: (num: number) => {
+                CacheMgr.setting.hammerNum = CacheMgr.setting.hammerNum + num
+                CacheMgr.setting = CacheMgr.setting
+            }
+        },
+        {
+            type: 3,
+            num: 3,
+            title: "恶魔3个",
+            func: (num: number) => {
+                CacheMgr.setting.spriteNum = CacheMgr.setting.spriteNum + num
+                CacheMgr.setting = CacheMgr.setting
+            }
+        },
+        {
+            type: 1,
+            num: 1000,
+            title: "金币1000",
+            func: (num: number) => {
+                Tools.changeGold(num)
+            }
+        },
+        {
+            type: 2,
+            num: 4,
+            title: "锤子4个",
+            func: (num: number) => {
+                CacheMgr.setting.hammerNum = CacheMgr.setting.hammerNum + num
+                CacheMgr.setting = CacheMgr.setting
+            }
+        },
+        {
+            type: 3,
+            num: 5,
+            title: "恶魔5个",
+            func: (num: number) => {
+                CacheMgr.setting.spriteNum = CacheMgr.setting.spriteNum + num
+                CacheMgr.setting = CacheMgr.setting
+            }
+        },
+    ]
+
+    public static singData7: signDataSeven = {
+        type: [1, 2, 3],
+        title: ["金币1000", "锤子2个", "恶魔2个"],
+        func: (num: number) => {
+            Tools.changeGold(1000 * num)
+            CacheMgr.setting.hammerNum += 2 * num
+            CacheMgr.setting.spriteNum += 2 * num
+            CacheMgr.setting = CacheMgr.setting
+        }
+    }
+
+    //提示数据
+    public static hint_data: nextBlockInfo [] [] = [
+        [
+
+            {
+                column: 1,
+                num: 3
+            },
+            {
+                column: 4,
+                num: 1
+            },
+            {
+                column: 6,
+                num: 1
+            },
+            {
+                column: 7,
+                num: 2
+            },
+        ],
+
+        [
+
+            {
+                column: 1,
+                num: 3
+            },
+            {
+                column: 4,
+                num: 1
+            },
+            {
+                column: 6,
+                num: 1
+            },
+            {
+                column: 7,
+                num: 2
+            },
+        ]
+    ]
+    public static grade_of_difficulty_config: grade_of_difficulty_config [] = [
+        null,
+        {probability_1: 20, probability_2: 30, probability_3: 10, probability_4: 0},
+        // {probability_1: 100, probability_2: 0, probability_3: 0, probability_4: 0},
+        {probability_1: 50, probability_2: 40, probability_3: 20, probability_4: 10},
+        {probability_1: 40, probability_2: 50, probability_3: 30, probability_4: 20},
+        {probability_1: 40, probability_2: 60, probability_3: 40, probability_4: 30},
+        {probability_1: 30, probability_2: 70, probability_3: 50, probability_4: 40},
+        {probability_1: 20, probability_2: 30, probability_3: 60, probability_4: 60},
+        // {probability_1: 100, probability_2: 0, probability_3: 0, probability_4: 0},
+        {probability_1: 50, probability_2: 40, probability_3: 70, probability_4: 70},
+        {probability_1: 40, probability_2: 50, probability_3: 80, probability_4: 80},
+        {probability_1: 40, probability_2: 60, probability_3: 90, probability_4: 90},
+        {probability_1: 30, probability_2: 70, probability_3: 100, probability_4: 100},
+    ]
+}
+
+interface grade_of_difficulty_config {
+    probability_1: number;  //一个方块概率
+    probability_2: number;  //两个方块概率
+    probability_3: number;  //三个方块概率
+    probability_4: number;  //四个方块概率
+}
+
+export interface signData {
+    type: number //类型
+    num: number  // 2
+    title: string  //介绍
+    func: Function  //handle
+}
+
+export interface signDataSeven {
+    type: number[] //类型
+    title: string[]  //介绍
+    func: Function  //handle
+}

+ 9 - 0
assets/Script/Moudle/View/logic/common/config.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "209a56b4-59a8-4881-91d3-cde872f3887f",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 17 - 0
assets/Script/Moudle/View/logic/common/text.ts

@@ -0,0 +1,17 @@
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class Text extends cc.Component {
+
+    delay: number = 0
+
+    start() {
+        cc.tween(this.node)
+            .delay(this.delay)
+            .to(2, {opacity: 0})
+            .call(() => {
+                this.node.destroy()
+            })
+            .start()
+    }
+}

+ 9 - 0
assets/Script/Moudle/View/logic/common/text.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "71b0e70d-e3bc-46df-8723-2700840dba52",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Moudle/View/logic/game.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "64aaa535-fbc8-4087-aa7b-97e15eb104cb",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 63 - 0
assets/Script/Moudle/View/logic/game/shop.ts

@@ -0,0 +1,63 @@
+import LayerPanel, {UrlInfo} from "../../../../Common/manage/Layer/LayerPanel";
+import Tools from "../../../../Common/Tools";
+import gameConfig from "../common/config";
+import CacheMgr from "../../../../Common/manage/CacheMgr";
+import PanelMgr from "../../../../Common/manage/PanelMgr";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class Shop extends LayerPanel {
+    private hammer_btn: cc.Node = null
+    private sprite_btn: cc.Node = null
+    private stamina_btn: cc.Node = null
+    private close_btn: cc.Node = null
+
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "game",
+            name: "shop"
+        }
+    }
+
+    initUI() {
+        this.hammer_btn = this.getNode("content/hammer/btn")
+        this.onTouch(this.hammer_btn, () => {
+            Tools.changeGold(-gameConfig.price_hammer, () => {
+                CacheMgr.setting.hammerNum++
+                CacheMgr.setting = CacheMgr.setting
+            })
+        })
+        this.change_price(this.hammer_btn, gameConfig.price_hammer)
+        this.sprite_btn = this.getNode("content/sprite/btn")
+        this.onTouch(this.sprite_btn, () => {
+            Tools.changeGold(-gameConfig.price_sprite, () => {
+                CacheMgr.setting.spriteNum++
+                CacheMgr.setting = CacheMgr.setting
+            })
+        })
+        this.change_price(this.sprite_btn, gameConfig.price_sprite)
+        this.stamina_btn = this.getNode("content/stamina/btn")
+        this.onTouch(this.stamina_btn, () => {
+            Tools.changeGold(-gameConfig.price_stamina, () => {
+                CacheMgr.stamina = CacheMgr.stamina + 1
+            })
+        })
+        this.change_price(this.stamina_btn, gameConfig.price_stamina)
+        this.close_btn = this.getNode("btn")
+        this.onTouch(this.close_btn, () => {
+            PanelMgr.INS.closePanel(Shop) ;
+        })
+    }
+
+    change_price(node: cc.Node, num: number) {
+        let label = node.getChildByName("num").getComponent(cc.Label)
+        label.string = num.toString()
+    }
+
+    show(param: any): void {
+    }
+
+    hide() {
+    }
+}

+ 9 - 0
assets/Script/Moudle/View/logic/game/shop.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "2d262c05-3c84-4dde-8d35-b0f378b618a2",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 141 - 0
assets/Script/Moudle/View/logic/game/sign.ts

@@ -0,0 +1,141 @@
+import LayerPanel, {UrlInfo} from "../../../../Common/manage/Layer/LayerPanel";
+import Tools from "../../../../Common/Tools";
+import gameConfig, {signData, signDataSeven} from "../common/config";
+import CacheMgr from "../../../../Common/manage/CacheMgr";
+import Constant from "../../../../Common/Constant";
+import PanelMgr from "../../../../Common/manage/PanelMgr";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class Sign extends LayerPanel {
+
+    @property([cc.SpriteFrame])
+    type_spriteFrame: cc.SpriteFrame[] = []
+
+
+    public static getUrl(): UrlInfo {
+        return {
+            bundle: "game",
+            name: "sign"
+        }
+    }
+    private items: cc.Node [] = []
+    private get: cc.Node = null
+    private double_get: cc.Node = null
+    private close: cc.Node = null
+
+    initUI() {
+        this.get = this.getNode("get")
+        this.onTouch(this.get, this.handle_get)
+        this.double_get = this.getNode("double")
+        this.onTouch(this.double_get, this.handle_double_get)
+        this.close = this.getNode("btn")
+        this.onTouch(this.close, () => {
+            PanelMgr.INS.closePanel(Sign) ;
+        })
+        let content = this.node.children[0]
+        for (let i = 0; i < content.childrenCount; i++) {
+            this.items.push(content.children[i])
+            if (i == 6) {
+                // this.changeItem7(content.children[i], gameConfig.singData7)
+            } else {
+                this.changeItem(content.children[i], gameConfig.signData[i])
+            }
+            if (i == 6) {
+                this.changeSignStatus7(content.children[i])
+            } else {
+                this.changeSignStatus(i, content.children[i])
+            }
+        }
+        if (CacheMgr.setting.signNum >= 6 || CacheMgr.setting.lastSignNum == Tools.date_getTimeNum(new Date)) {
+            this.hideBtn()
+        }
+    }
+
+    private changeItem(node: cc.Node, data: signData) {
+        // let one = node.children[0]
+        node.children[1].getComponent(cc.Sprite).spriteFrame = this.type_spriteFrame[data.type]
+        node.children[2].getComponent(cc.Label).string = data.title
+    }
+
+    private changeSignStatus(i: number, node: cc.Node) {
+        if (i == -1) {
+            node.getChildByName("mask").active = true
+            node.getChildByName("签到").active = true
+            return
+        }
+        if (CacheMgr.setting.signNum >= i) {
+            node.getChildByName("mask").active = true
+            node.getChildByName("签到").active = true
+        } else {
+            node.getChildByName("mask").active = false
+            node.getChildByName("签到").active = false
+        }
+    }
+
+
+    private changeSignStatus7(node: cc.Node, isFalse: boolean = false) {
+        if (isFalse) {
+            node.getChildByName("签到").active = true
+            node.getChildByName("mask").active = true
+        }
+        if (CacheMgr.setting.signNum >= 6) {
+            node.getChildByName("签到").active = true
+            node.getChildByName("mask").active = true
+        } else {
+            node.getChildByName("签到").active = false
+            node.getChildByName("mask").active = false
+        }
+    }
+
+    private handle_get() {
+        if (CacheMgr.setting.signNum == 5) {
+            gameConfig.singData7.func(1)
+            CacheMgr.setting.signNum++
+            this.changeSignStatus7(this.items[6], true)
+        } else {
+            let data = gameConfig.signData[CacheMgr.setting.signNum + 1]
+            CacheMgr.setting.signNum++
+            this.changeSignStatus(-1, this.items[CacheMgr.setting.signNum])
+            data.func(data.num)
+        }
+        CacheMgr.setting.lastSignNum = Tools.date_getTimeNum(new Date())
+        CacheMgr.setting = CacheMgr.setting
+        this.hideBtn()
+    }
+
+    private handle_double_get() {
+
+        Tools.handleVideo().then((res) => {
+            if (res) {
+                if (CacheMgr.setting.signNum == 5) {
+                    gameConfig.singData7.func(2)
+                    CacheMgr.setting.signNum++
+                    this.changeSignStatus7(this.items[6], true)
+                } else {
+                    let data = gameConfig.signData[CacheMgr.setting.signNum + 1]
+                    CacheMgr.setting.signNum++
+                    this.changeSignStatus(-1, this.items[CacheMgr.setting.signNum])
+                    data.func(data.num * 2)
+                }
+
+                CacheMgr.setting.lastSignNum = Tools.date_getTimeNum(new Date())
+                CacheMgr.setting = CacheMgr.setting
+                this.hideBtn()
+            }
+        })
+    }
+
+    private hideBtn() {
+        this.get.active = false
+        this.double_get.active = false
+    }
+
+    show(param: any): void {
+    }
+
+    hide() {
+    }
+
+}

+ 9 - 0
assets/Script/Moudle/View/logic/game/sign.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "8ea413b5-ef9d-42e1-8cbb-724d94ee2392",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/SDK.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "b3e705e1-3b09-4769-8fc3-1af88846941f",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 161 - 0
assets/Script/SDK/JiuWuSDK.ts

@@ -0,0 +1,161 @@
+import Tools from "../Common/Tools";
+import Global from "../Common/Global";
+import QgApi from "../Common/manage/Api/QgApi";
+import Loading from "../Scene/Loading";
+import LogMgr from "../Common/LogMgr";
+import CacheMgr from "../Common/manage/CacheMgr";
+
+export default class JiuWuSDK {
+
+    public static qgToken: any = null;
+
+    public static initSDK: boolean = false;
+
+    public static url = {
+        test: "ZHhttps://api.jiuwugame.cn",
+        host: "ZHhttps://api.jiuwugame.cn",
+    }
+
+    public static gameInfo: GameInfo = {
+        gameId: 125,
+        gameVersion: "ZH20211026",
+        client: 'ZH95e7b3d7beceea9a7b85a3235892e728',
+        token: 'ZH$2a$10$gjXXqXHT85QpdRZSsS8QZuu6AnI5hJL/ZzyJ8yzMCit2ii7RhGd.W',
+    }
+
+    public static launchData: launchData = {
+        scene: '',
+        query: null,
+        shareTicket: '',
+        referrerInfo: {
+            appId: '',
+            extraData: null
+        }
+    }
+
+    public static inSet_API_Config() {
+        return new Promise((resolve, reject) => {
+            this.login().then(() => {
+                this.register().then((data) => {
+                    Global.allData = data;
+
+                    let gmsUser = Global.allData.data.data.gmsUser;
+                    CacheMgr.userId = gmsUser.userId;
+                    CacheMgr.openId = gmsUser.openId;
+                    CacheMgr.isAuth = gmsUser.isAuth;
+                    // @ts-ignore
+                    Global.config = JSON.parse(Global.allData.data.data.versionMode);
+
+                    QgApi.createAdv() ;
+
+                    LogMgr.log('一切就绪......')
+                    this.initSDK = true;
+                    resolve(true);
+                }, () => {
+                    LogMgr.error('就绪失败......')
+                })
+            })
+
+        })
+    }
+
+    /**
+     * 后台 注册或者登录
+     */
+    public static register() {
+        try {
+            return new Promise((resolve, reject) => {
+                console.log('准备发送请求......')
+                let param: regisMessage = Object(null);
+                console.log('发送请求中......A')
+                param.url = Tools.getHost() + '/api/login/loginsum';
+                console.log('发送请求中......B')
+                param.data = {
+                    code: this.qgToken,
+                    gameId: this.gameInfo.gameId,
+                    sceneVal: undefined,
+                    exportId: undefined,
+                    version: this.gameInfo.gameVersion,
+                }
+                console.log('发送请求中......C')
+                param.method = 'POST';
+                param.header = this.headers();
+                param.header['content-type'] = 'application/json';
+                param.success = (res) => {
+                    if (res.data.code === 200) {
+                        console.log('后台登录注册成功:', res)
+                        resolve(res);
+                    } else {
+                        console.error('登录错误:', res);
+                        reject(res);
+                    }
+                };
+                param.fail = (err) => {
+                    console.error('发送请求失败:', err);
+                }
+                console.log('发送请求中......D')
+                QgApi.sponsorHttps(param);
+            });
+        } catch (e) {
+            console.error('后台登录错误:', e);
+        }
+    }
+
+    /**
+     * 登录vivo
+     */
+    public static login() {
+        return new Promise((resolve, reject) => {
+            try {
+                QgApi.login().then((token) => {
+                    if (token != false) {
+                        this.qgToken = token;
+                        resolve(true);
+                    }
+                }, () => {
+                    console.error('登录失败')
+                })
+            } catch (e) {
+                console.log(' login error', e);
+            }
+        })
+    }
+
+    public static headers() {
+        return {
+            'x-client': this.gameInfo.client,
+            'x-token': this.gameInfo.token
+        }
+    }
+
+}
+
+
+interface GameInfo {
+    gameId: number,
+    gameVersion: string,
+    client: string,
+    token: string
+}
+
+interface launchData {
+    scene: string,
+    query: any,
+    shareTicket: string,
+    referrerInfo: referrerInfo
+}
+
+export interface referrerInfo {
+    appId: string,
+    extraData: any
+}
+
+export interface regisMessage {
+    url: string,
+    data: object,
+    method: string,
+    success: any,
+    fail: any,
+    header: any
+}
+

+ 9 - 0
assets/Script/SDK/JiuWuSDK.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "836fe1e6-e60d-4c24-8a89-4e3bb42a5634",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/Script/Scene.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "cdb32b53-d407-4743-987d-9ce39c5e9b89",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 47 - 0
assets/Script/Scene/Game.ts

@@ -0,0 +1,47 @@
+import PanelMgr, {Layer, View} from "../Common/manage/PanelMgr";
+import Emit from "../Common/manage/Emit/Emit";
+import {EventCode} from "../Common/manage/Emit/EmitData";
+import HomeView from "../Moudle/View/HomeView";
+import Global from "../Common/Global";
+import AudioMgr from "../Common/manage/AudioMgr";
+import QgApi from "../Common/manage/Api/QgApi";
+import ShowConfig from "../Common/ShowConfig";
+
+// cc.macro.CLEANUP_IMAGE_CACHE = false;
+// cc.dynamicAtlasManager.enabled = true;
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class Game extends cc.Component {
+    banner: cc.Node = null
+
+    //Game实例
+    public static Ins: Game = null;
+
+    onLoad() {
+        AudioMgr.backMusic()
+        Game.Ins = this ;
+
+        if (!PanelMgr.INS) {
+            Emit.instance().on(EventCode.PanelMgrInitOK, this.do_after_panelMgr_initOK, this)
+        } else {
+            this.do_after_panelMgr_initOK()
+        }
+    }
+
+    //PanelMgr 初始化完成之后执行的方法
+    do_after_panelMgr_initOK() {
+        this.banner = this.node.getChildByName('bannerLayer').children[0];
+
+        if (Global.isVivo) {
+            QgApi.createBanner() ;
+            ShowConfig.initEmit() ;
+        }
+
+        PanelMgr.INS.openPanel({
+            layer: Layer.gameLayer,
+            panel: HomeView,
+        })
+    }
+
+}

+ 9 - 0
assets/Script/Scene/Game.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "8438fc75-a1ec-4e7f-826b-77db84b7953d",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 94 - 0
assets/Script/Scene/Loading.ts

@@ -0,0 +1,94 @@
+import Tools from "../Common/Tools";
+import JiuWuSDK from "../SDK/JiuWuSDK";
+import CacheMgr from "../Common/manage/CacheMgr";
+import Global from "../Common/Global";
+import Emit from "../Common/manage/Emit/Emit";
+import LogMgr from "../Common/LogMgr";
+import QgBanner from "../Common/manage/Api/QgBanner";
+import EmitData from "../Common/manage/Emit/EmitData";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class Loading extends cc.Component {
+
+    @property(cc.Node)
+    round: cc.Node = null;
+
+    @property(cc.Node)
+    mask: cc.Node = null;
+
+    private tween = null;
+
+    protected onLoad() {
+        // @ts-ignore
+        if (window.qg) {
+            Global.isVivo = true;
+        }
+        this.mask.width = 0
+        //假的进度条
+        this.tween = cc.tween(this.mask)
+            .to(3, {width: 300}, {easing: "quadOut"})
+            .start();
+        let i = 0;
+
+
+        cc.director.preloadScene("Game")
+
+        let num = Tools.model_initModel(() => {
+            i++
+            if (i === num) {
+                this.tween.stop();
+                cc.tween(this.mask)
+                    .to(2, {width: 500}, {easing: 'quadOut'})
+                    .call(() => {
+                        if (Global.isVivo) {
+                            if (JiuWuSDK.initSDK) {
+                                this.loadScene();
+                            } else {
+                                Emit.instance().on(EmitData.LOAD_GAME_SCENE, this.loadScene, this);
+                            }
+                        } else {
+                            cc.director.loadScene('Game');
+                        }
+                    })
+                    .start();
+            }
+        });
+
+        this.someMotor();
+    }
+
+    loadScene() {
+        cc.director.loadScene('Game');
+    }
+
+
+    someMotor() {
+        if (!Global.isVivo) {
+            return
+        }
+
+        // @ts-ignore
+        window.qg.onShow(() => {
+            LogMgr.log('Banner刷新>>>>>>onShow', QgBanner.isShow);
+            if (QgBanner.isShow) {
+                QgBanner.cutBanner().then();
+            }
+
+            cc.audioEngine.resumeMusic()
+        })
+
+        // @ts-ignore
+        window.qg.onHide(() => {
+
+            CacheMgr.updateData();
+            cc.audioEngine.pauseMusic()
+        })
+
+        JiuWuSDK.inSet_API_Config().then(() => {
+            Emit.instance().emit(EmitData.LOAD_GAME_SCENE);
+        })
+
+    }
+}

+ 9 - 0
assets/Script/Scene/Loading.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "1.0.8",
+  "uuid": "ec6e2ae0-32f1-41e2-83f3-25e43c60066d",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 12 - 0
assets/View.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "962e5d34-2f90-4995-b969-7153008c2fd8",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 20 - 0
assets/View/end.meta

@@ -0,0 +1,20 @@
+{
+  "ver": "1.1.2",
+  "uuid": "ebb0ace6-8865-4814-a5a9-343e84467175",
+  "isBundle": true,
+  "bundleName": "",
+  "priority": "5",
+  "compressionType": {
+    "qgame": "subpackage"
+  },
+  "optimizeHotUpdate": {
+    "qgame": false
+  },
+  "inlineSpriteFrames": {
+    "qgame": false
+  },
+  "isRemoteBundle": {
+    "qgame": false
+  },
+  "subMetas": {}
+}

+ 143 - 0
assets/View/end/coin.prefab

@@ -0,0 +1,143 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "",
+    "_objFlags": 0,
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "asyncLoadAssets": false,
+    "readonly": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "coin",
+    "_objFlags": 0,
+    "_parent": null,
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 3
+      }
+    ],
+    "_prefab": {
+      "__id__": 4
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 60,
+      "height": 60
+    },
+    "_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__": 1
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "22afd7da-18b2-4a2e-8bd1-d492d69717b4"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": {
+      "__uuid__": "412bb7c2-a563-4b3b-a48e-4eb392bc0530"
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Animation",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "_defaultClip": {
+      "__uuid__": "d0ebfb3b-1ffe-4840-812c-fa7dd48e870e"
+    },
+    "_clips": [
+      {
+        "__uuid__": "d0ebfb3b-1ffe-4840-812c-fa7dd48e870e"
+      }
+    ],
+    "playOnLoad": true,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "edc9971e-51ac-4946-a3c4-b0bbef800e25"
+    },
+    "fileId": "",
+    "sync": false
+  }
+]

+ 8 - 0
assets/View/end/coin.prefab.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "1.2.9",
+  "uuid": "edc9971e-51ac-4946-a3c4-b0bbef800e25",
+  "optimizationPolicy": "AUTO",
+  "asyncLoadAssets": false,
+  "readonly": false,
+  "subMetas": {}
+}

+ 119 - 0
assets/View/end/huodejinbi.prefab

@@ -0,0 +1,119 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "",
+    "_objFlags": 0,
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "asyncLoadAssets": false,
+    "readonly": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "huodejinbi",
+    "_objFlags": 0,
+    "_parent": null,
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 2
+      }
+    ],
+    "_prefab": {
+      "__id__": 3
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 45,
+      "height": 47
+    },
+    "_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__": 1
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "581cd9ac-5903-4ef0-a92a-3b368a89de2a"
+    },
+    "_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__": "eb95f939-99c5-49e5-9b4a-91a81ff8a181"
+    },
+    "fileId": "",
+    "sync": false
+  }
+]

+ 8 - 0
assets/View/end/huodejinbi.prefab.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "1.2.9",
+  "uuid": "eb95f939-99c5-49e5-9b4a-91a81ff8a181",
+  "optimizationPolicy": "AUTO",
+  "asyncLoadAssets": false,
+  "readonly": false,
+  "subMetas": {}
+}

+ 24 - 0
assets/View/endView.meta

@@ -0,0 +1,24 @@
+{
+  "ver": "1.1.2",
+  "uuid": "a5e6c448-930f-4cde-9c6b-76eca559de52",
+  "isBundle": true,
+  "bundleName": "",
+  "priority": "5",
+  "compressionType": {
+    "wechatgame": "subpackage",
+    "qgame": "subpackage"
+  },
+  "optimizeHotUpdate": {
+    "wechatgame": false,
+    "qgame": false
+  },
+  "inlineSpriteFrames": {
+    "wechatgame": false,
+    "qgame": false
+  },
+  "isRemoteBundle": {
+    "wechatgame": false,
+    "qgame": false
+  },
+  "subMetas": {}
+}

+ 12 - 0
assets/View/endView/end.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.1.2",
+  "uuid": "cc3416da-3e4d-47fe-9e43-3bfd97b68ab0",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 143 - 0
assets/View/endView/end/coin.prefab

@@ -0,0 +1,143 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "",
+    "_objFlags": 0,
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "asyncLoadAssets": false,
+    "readonly": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "coin",
+    "_objFlags": 0,
+    "_parent": null,
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 3
+      }
+    ],
+    "_prefab": {
+      "__id__": 4
+    },
+    "_opacity": 255,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 60,
+      "height": 60
+    },
+    "_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__": 1
+    },
+    "_enabled": true,
+    "_materials": [
+      {
+        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
+      }
+    ],
+    "_srcBlendFactor": 770,
+    "_dstBlendFactor": 771,
+    "_spriteFrame": {
+      "__uuid__": "22afd7da-18b2-4a2e-8bd1-d492d69717b4"
+    },
+    "_type": 0,
+    "_sizeMode": 1,
+    "_fillType": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_atlas": {
+      "__uuid__": "412bb7c2-a563-4b3b-a48e-4eb392bc0530"
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Animation",
+    "_name": "",
+    "_objFlags": 0,
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "_defaultClip": {
+      "__uuid__": "d0ebfb3b-1ffe-4840-812c-fa7dd48e870e"
+    },
+    "_clips": [
+      {
+        "__uuid__": "d0ebfb3b-1ffe-4840-812c-fa7dd48e870e"
+      }
+    ],
+    "playOnLoad": true,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__uuid__": "edc9971e-51ac-4946-a3c4-b0bbef800e25"
+    },
+    "fileId": "",
+    "sync": false
+  }
+]

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.