import AppConfig from "../../FrameWork/Config/AppConfig";
import AppSwitchConfig from "../../FrameWork/Config/AppSwitchConfig";
import { ryw_Event } from "../../FrameWork/Event/EventEnum";
import EventMgr from "../../FrameWork/Event/EventMgr";

import BundleMgr from "../../FrameWork/Mgr/BundleMgr";
import GEMgr from "../../FrameWork/Mgr/GEMgr";
import VibrateMgr from "../../FrameWork/Mgr/VibrateMgr";
import User from "../../FrameWork/User/User";
import AppPlatform from "../../FrameWork/Util/AppPlatform";
import { MainTaskIdEnum } from "../../Scripts/JuQingChat/TaskManager";
import UserManager from "../../Scripts/Manager/UserManager";
import PrefabManage from "../../Scripts/PrefabManager/PrefabManage";
import TTAPI from "../tt/TTAPI";

export default class Common5 {
    public static curShowTufaEvent: number = 0;
    public static isTouching: boolean = false;
    public static isFirstInLaji = true;//玩家是否第一次进入
    public static isNewUser: boolean = false;
    public static isNoEnergyMode = 0; //畅玩
    public static isVideoAdStopTime: boolean = false;//
    public static isMute: boolean = false;//是否静音
    public static isNoMusic: boolean = false;//是否静音
    public static isNoEffect: boolean = false;//是否静音
    public static isNoZD: boolean = false;//是否关闭震动
    public static audioId: number = 0;//音乐ID
    //游戏相关
    public static ISSHOWGM: boolean = true;//

    public static juQingStocksConfig = []//保存剧情配置文件

    public static allJuQingJson = {}//保存所有剧情对话json

    public static bagConfigs = null

    public static isNoPower: boolean = false;//体力不够

    public static isBackLevel = 0;

    public static videoGetPowerNum = 3; //普通体力视频获取点数
    public static powerRecoverTime = 300; //体力恢复时间(s)
    public static fisrtPower = 1;       //玩家第一次进入游戏的体力值
    public static maxPower = 3;       //体力值上限

    public static videoFirstGetPowerNum = 2; //无限体力第一次视频获取点数
    public static videoSecondGetPowerNum = 3; //无限体力第二次视频获取点数

    public static videoWxtlPowerNum = 3; //无限体力获取视频数
    static allStocksConfig = [];

    public static allJuQingChatConfig = {}//保存所有剧情聊天配置文件
    public static chatPersonConfig = null//保存所有聊天人物
    public static isOpenChatPeople = '';
    static lixianTime: number = 0;
    // onLoad () {}
    public static GameProbabillityConfig = null//
    public static guwanConfigs = null//
    public static ChanYeLevelUpIndex = 1//
    public static FengWeiLevelUpIndex = 1
    public static ChanYeLevel = 0//
    public static FengWeiLevel = 0
    // public static NewGuideStep = 0//
    public static earnMoneySecond = 240;
    public static DiTanIndex = 0;

    public static curGameName = '主界面';
    public static isCeBianLanEnter: boolean = false//是否从侧边栏进入游戏
    public static huangjinHaianConfigs = null//
    public static huangjinHeDengChange = { countNum: 0, dayNum: 0, changeGailv: 0 }
    public static onHideState = {
        gold: 0, //金币
        strength: 0,  //体力
        sendCardTimes: 0, //发牌次数
        unlockLevel: 0, //已经解锁关卡/槽位
        removeTimes: 0, //消除次数
        default1: 0, //默认字段1
        default2: 0, //默认字段2
        default3: 0 //默认字段3
    }
    public static levelGameConfig = null;
    public static gameConfig = null;
    public static selectGameNum: number = -1;//选择的是第几关
    public static selectGameInfo = null;//选择的关卡信息
    public static curWordGameType = 0; //记录当前在哪个分类
    public static showAllGameUnLock = false;
    public static wordGameType = 0;
    public static showShouzhi = true
    public static saveTime = 0;
    public static kaiKuangVDIndex = 0;
    public static ShenMirenChat = false
    public static isHaveUserName = true
    public static addGameArr =
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
            11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
            21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
            31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
            44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
            57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
            70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81

        ];
    public static caiPuConfigs = null//
    public static AllMineralsConfig = null//所有矿产配置文件
    public static AllMountingConfig = null//所有山峰配置文件

    public static NeedReleaseRes = null;
    public static NeedReleaseResCity = null;
    public static NeedReleaseResShiQu = null;
    public static NeedReleaseResMyroom = null;
    public static selectUrl = null;
    public static MoTuoCheConfig = null
    public static TaskBtnState = null


    public static MangKengMoney = 0
    public static JinkuaiMoney = 0
    public static HuashiMoney = 0
    public static SunshiMoney = 0
    static addNum: any = 0;
    public static shamoVDIndex = 0

    public static DescCommonIndex = 0; //任务描述的物品数量

    public static EndGameTask = MainTaskIdEnum.MainTask_555;
    static isShowAdd: boolean = true;
    /**材质存储列表 */
    private static imgMap: Map<string, cc.SpriteFrame>;
    public static audioMap: Map<string, cc.AudioClip>;
    public static spineMap: Map<string, sp.SkeletonData>;
    public static prefabMap: Map<string, cc.Prefab>;

    public static CommonGuideIndex = 0
    public static task502 = false
    public static task505 = false

    public static showDH12 = true
    public static guwanchengADNum = 0
    public static qinwanglinADNum = 0
    public static TaskGuide503 = false
    public static TaskGuide516 = false
    public static mishuGuide = false
    start() {

    }
    getHuangjinghaianGetReward() {
        if (Common5.huangjinHeDengChange.dayNum > 0) {
            //0-1
            return Common5.huangjinHeDengChange.changeGailv
        } else {
            if (Common5.huangjinHeDengChange.countNum > 0) {
                return Common5.huangjinHeDengChange.countNum
            } else {
                return 0
            }
        }
    }
    public static setNodePos(pointNode: cc.Node, x, y) {
        pointNode.setPosition(x, y);
    }
    public static LoadRemoteBundle(name, func) {
        BundleMgr.loadBundleByName_custom(name, handleFM_custom((err, bundle) => {
            if (err) {
                //console.error(err);
            } else {
                func();
            }
        }, this));
    }



    public static loadAllJson() {
        let ChatPersonCallFunc = (callFunc) => {
            cc.loader.loadRes('Json/JuQingChatConfig/ChatPerson.json', function (err, gameconfig) {
                if (err) {
                    //console.log(err);
                    return;
                }
                Common5.chatPersonConfig = gameconfig.json;
                for (var i = 0; i < Common5.chatPersonConfig.length; i++) {
                    let jsonName = Common5.chatPersonConfig[i].jsonName
                    if (!Common5.allJuQingChatConfig[jsonName]) {
                        // console.log("加载人物剧情聊天json==",jsonName)
                        cc.loader.loadRes('Json/JuQingChatConfig/' + jsonName + '.json', function (err, gameconfig) {
                            if (err) {
                                //console.log(err);
                                return;
                            }
                            Common5.allJuQingChatConfig[jsonName] = gameconfig.json;
                        });

                    }
                }
                callFunc()
            });
        }
        let allStockConfigCallFunc = (callFunc) => {
            cc.loader.loadRes('Json/stockConfig/allStockConfig.json', function (err, gameconfig) {
                if (err) {
                    return;
                }
                Common5.allStocksConfig = gameconfig.json;
                // console.log("游戏配置加载成功", Common5.allStocksConfig);
                callFunc()
            });
        }

        let caipuCallFunc = (callFunc) => {
            cc.loader.loadRes('Json/gameConfig/caipu.json', function (err, gameconfig) {
                if (err) {
                    return;
                }
                Common5.caiPuConfigs = gameconfig.json;
                //console.log("游戏配置加载成功", Common5.juQingStocksConfig);
                callFunc()
            });
        }

        //这里用递归的方式加载json,处理同时加载多个json情况
        let loadJsonArr = [
            ChatPersonCallFunc, allStockConfigCallFunc, caipuCallFunc
        ]

        let loadIndex = 0
        let loadCallFunc = (index) => {
            if (index >= loadJsonArr.length) {
                return
            }
            console.log('loading页loadAllJson_', index)
            let callFunc = () => {
                console.log('loading页单个json加载完毕,加载下一个')
                loadCallFunc(++loadIndex)
            }
            loadJsonArr[index](callFunc)
        }
        loadCallFunc(loadIndex)
    }

    /**
     * 加载本地游戏相关json配置
     */
    public static loadConfigLocal_custom(AppSwitchcallback?) {
        console.log("加载本地json===")
        Common5.loadAllJson()
        if (AppSwitchcallback) {
            AppSwitchcallback()
        }
        Common5.imgMap = new Map();
        Common5.audioMap = new Map()
        Common5.spineMap = new Map()
        Common5.prefabMap = new Map()
    }



    public static addResourseSprite_custom(picSp: cc.Sprite, url: string) {
        cc.resources.load(url, cc.Texture2D, function (err, texture: cc.Texture2D) {
            if (err) {
                //console.log("加载图片失败")
                return;
            }
            var sprite0 = new cc.SpriteFrame(texture);
            picSp.spriteFrame = sprite0;
        });
    }


    /**
     * 注册节点点击事件
     * 
     * @param btnNode 按钮节点
     * @param callback 点击事件
     * @param protectedTime 保护时间,防止连续点击
     * @param scaleTime 放大缩小时间
     * @param soundName 按钮音效
     * @param clickSprite 点击按钮图片
     */
    public static btnRegister_custom(btnNode: cc.Node, callback: Function, protectedTime: number = 0.1, scaleTime: number = 0.2, soundName: string = "ui", clickSprite: cc.SpriteFrame = null) {
        //console.log("注册按钮事件", btnNode.name);
        let btnSprite = null;//btnNode.getComponent(cc.Sprite).spriteFrame;
        if (btnNode.getComponent(cc.Sprite) != null) {
            btnSprite = btnNode.getComponent(cc.Sprite).spriteFrame;
        }
        //开始触摸
        soundName = soundName
        let tmpScale = btnNode.scale;
        btnNode.on(cc.Node.EventType.TOUCH_START, () => {
            // SoundMgr.playSound_custom(soundName);
            // Common5.getSoundFromBundle_custom("subRes_Resources", soundName, false);
            Common5.playEffect(soundName);
            VibrateMgr.vibrateShort_custom();
            if (scaleTime > 0) {
                cc.tween(btnNode).to(scaleTime, { scale: tmpScale * 0.8 }).start();
            }
            if (clickSprite != null) {
                //console.log("clickSprite", clickSprite);
                btnNode.getComponent(cc.Sprite).spriteFrame = clickSprite;
            }
        }, this);
        //结束触摸,响应时间
        btnNode.on(cc.Node.EventType.TOUCH_END, () => {
            VibrateMgr.vibrateShort_custom();
            if (scaleTime > 0) {
                cc.tween(btnNode).to(scaleTime, { scale: tmpScale }).start();
            }
            if (btnSprite != null) {
                btnSprite = btnNode.getComponent(cc.Sprite).spriteFrame;
                btnNode.getComponent(cc.Sprite).spriteFrame = btnSprite;
            }
            if (Common5.isTouching === false) {
                Common5.isTouching = true;
                callback(btnNode);
                setTimeout(() => {
                    Common5.isTouching = false;
                }, protectedTime * 1000);
            }
        }, this);
        //退出按钮
        btnNode.on(cc.Node.EventType.TOUCH_CANCEL, () => {
            if (btnSprite != null) {
                btnNode.getComponent(cc.Sprite).spriteFrame = btnSprite;
            }
            if (scaleTime > 0) {
                cc.tween(btnNode).to(scaleTime, { scale: tmpScale }).start();
            }
        }, this);
    }


    /**
     * 得到节点的世界坐标
     * @param node 节点
     */
    public static getPosInWorld_custom(node: cc.Node) {
        let pos = node.getPosition();
        var newVec3 = node.parent.convertToWorldSpaceAR(pos);
        let returnPos = cc.v2(newVec3.x - cc.winSize.width / 2, newVec3.y - cc.winSize.height / 2)
        return returnPos;
    }

    /**
     * 求两个节点的距离
     * @param node0 
     * @param node1 
     * @returns 
     */
    public static makeNodeDistance_custom(node0: cc.Node, node1: cc.Node) {
        let pos0 = Common5.getPosInWorld_custom(node0);
        let pos1 = Common5.getPosInWorld_custom(node1);
        return Common5.makeDistance(pos0, pos1);
    }

    /**
     * 求两点的距离
     * 
     * @param pos0 第一个位置
     * @param pos1 第二个位置
     */
    public static makeDistance(pos0: cc.Vec2, pos1: cc.Vec2) {
        // let dx = Math.abs(pos0.x - pos1.x);
        // let dy = Math.abs(pos0.y - pos1.y);
        var dis = Math.abs(pos0.sub(pos1).mag())//Math.sqrt(Math.pow(dx,2)+Math.pow(dy,2));
        return dis;
    }

    /**
     * 求角度,角度为pos0,centerPos,pos1形成的角度
     * @param pos0 
     * @param pos1 
     * @param centerPos 
     */
    public static makeAngle(pos0: cc.Vec2, pos1: cc.Vec2, centerPos: cc.Vec2) {
        let vec0 = cc.v2(pos0.x - centerPos.x, pos0.y - centerPos.y);
        let vec1 = cc.v2(pos1.x - centerPos.x, pos1.y - centerPos.y);
        //弧度
        var angle = vec1.signAngle(vec0);
        //将弧度转换为欧拉角
        var degree = angle / Math.PI * 180;
        return -degree;
    }

    /**
     * 向量转化成角度
     * @param dirVec 
     * @returns 
     */
    public static vectorsToDegress(dirVec: cc.Vec2) {
        let comVec: cc.Vec2 = cc.v2(0, 1);    // 水平向上的对比向量
        let radian = dirVec.signAngle(comVec);    // 求方向向量与对比向量间的弧度
        let degree = cc.misc.radiansToDegrees(radian);    // 将弧度转换为角度
        return -degree;
    }

    //从固定数组中随机抽取一个数
    public static getMathInLimitArr_custom(limitArr: number[]) {
        if (limitArr.length < 0) {
            return 0;
        }
        let num = Math.floor(Math.random() * limitArr.length);
        return limitArr[num];
    }

    //从固定数组中随机抽取一个数组,返回为被选中数组和剩下的数组
    public static getMathArrInLimitArr_custom(limitArr: number[], getCount: number) {
        let returnArr = [];
        for (var i = 0; i < getCount; i++) {
            if (limitArr.length <= 0) {

            } else {
                //console.log("limitArr.length", limitArr.length);
                let num = Math.floor(Math.random() * limitArr.length);
                returnArr.push(limitArr[num]);
                limitArr.splice(num, 1);
            }
        }
        let obj = {
            "returnArr": returnArr,
            "limitArr": limitArr
        }
        return obj;
    }

    /**
     * 从min到max随机取count个数,包括min,也包括max, min>=max || count<0 || (max-min+1)<count
     * @param min 最小数
     * @param max 最大数
     * @param count 需要的个数
     */
    public static getRandomNumArr_custom(min: number, max: number, count: number) {
        //console.log("min", min, "max", max, "count", count);
        if (min >= max || count < 0 || (max - min + 1) < count) {
            //console.log("输入参数有误")
            return [];
        }
        //原数组
        var arr = [];
        for (var i = min; i <= max; i++) {
            arr.push(i)
        }
        //输出数组
        var out = [];
        //输出个数-count
        while (out.length < count) {
            var temp = (Math.random() * arr.length) >> 0;
            for (let i = 0; i < out.length; i++) {
                if (temp == out[i]) {
                    continue;
                }
            }
            out.push(arr.splice(temp, 1)[0]);
        }
        return out;
    }
    /**
     * 从min到max取随机数,兼容min>=max的情况 注意取不到最大值
     * @param min 最小数
     * @param max 最大数
     */
    public static getRandomNum(min: number, max: number) {
        let minNumber = Math.min(min, max);
        let maxNumber = Math.max(min, max);
        return Math.floor(Math.random() * (maxNumber - minNumber)) + minNumber;
    }
    /**
     * 从min到max取随机数
     * @param min 最小数
     * @param max 最大数
     */
    public static getRandomNumber(min: number, max: number) {
        let minNumber = Math.min(min, max);
        let maxNumber = Math.max(min, max);
        return Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
    }
    // //
    public static showTips_custom(text: string) {
        let canvas = cc.find("Canvas");
        let node = new cc.Node("tips");
        let label = node.addComponent(cc.Label);
        label.string = text;
        label.enableBold = true;
        label.fontSize = 40;
        let outline = node.addComponent(cc.LabelOutline);
        outline.width = 5;
        outline.color = new cc.Color(0, 0, 0, 255);
        canvas.addChild(node);
        node.x = 0;
        node.y = 0;
        cc.tween(node).delay(2.5).to(1, { y: 555, opacity: 0 }).call(() => {
            node.removeFromParent();
        }).start();

    }
    public static showTips_customTime(text: string, delay: number,) {
        let canvas = cc.find("Canvas");
        let node = new cc.Node("tips");
        let label = node.addComponent(cc.Label);
        label.string = text;
        label.enableBold = true;
        label.fontSize = 40;
        label.lineHeight = 40;
        label.overflow = cc.Label.Overflow.SHRINK
        label.node.height = 85
        label.node.width = 600
        label.horizontalAlign = cc.Label.HorizontalAlign.CENTER
        let outline = node.addComponent(cc.LabelOutline);
        outline.width = 3;
        outline.color = new cc.Color(0, 0, 0, 255);
        canvas.addChild(node);
        node.x = 0;
        node.y = 150;
        cc.tween(node).delay(delay).to(1, { y: 555, opacity: 0 }).call(() => {
            node.removeFromParent();
        }).start();

    }
    public static showTips_customTimeAndPos(text: string, delay: number, node_: cc.Node, deltaY) {
        let canvas = cc.find("Canvas");
        let node = new cc.Node("tips");
        let label = node.addComponent(cc.Label);
        label.string = text;
        label.enableBold = true;
        label.fontSize = 40;
        label.lineHeight = 40;
        label.overflow = cc.Label.Overflow.SHRINK
        label.node.height = 85
        label.node.width = 600
        label.horizontalAlign = cc.Label.HorizontalAlign.CENTER
        let outline = node.addComponent(cc.LabelOutline);
        outline.width = 3;
        outline.color = new cc.Color(0, 0, 0, 255);
        canvas.addChild(node);

        let pos = Common5.getRelativePosition(node_, canvas);

        node.x = pos.x;
        node.y = pos.y;
        let y = pos.y + deltaY;
        cc.tween(node).delay(delay).to(1, { y: y, opacity: 0 }).call(() => {
            node.removeFromParent();
        }).start();

    }
    /**
     * 加载resourse文件夹下目录
     * @param url 预制的路径
     * @param parent 预制的父节点
     * @param callback 
     */
    public static addPrefab(url, parent, callback = null) {
        let parentNode = parent
        cc.loader.loadRes(url, (err, prefab) => {
            if (err) {
                //console.log('加载预制体错误>:', err)
                return;
            }
            var prefabNode = cc.instantiate(prefab);
            prefabNode.parent = parentNode;
            if (callback) {
                callback(prefabNode);
            }
        });
    }

    public static getSoundFromBundle_custom(bundlename = "allRes", url: string, isBgm: boolean = false) {
        if (Common5.isMute == true) {
            return;
        }
        let audioclip: cc.AudioClip = null;
        let subres = cc.assetManager.getBundle(bundlename);
        // url = "Sound/Wedding/" + url
        if (subres) {
            subres.load(url, cc.AudioClip, (err, AudioClip: cc.AudioClip) => {
                if (err) {
                    //console.log('加载音效错误>:', err)
                    return null;
                }
                // //console.log("加载成功:",AudioClip);
                audioclip = AudioClip;
                if (isBgm == true) {
                    this.audioId = cc.audioEngine.playMusic(audioclip, true);

                } else {
                    this.audioId = cc.audioEngine.play(audioclip, false, 1);
                }


            })
        }
        // return audioclip;
    }




    public static ReportDY(event, msg) {


        console.error(msg, 'msg++==')
        if (AppPlatform.is_TT_GAME_custom()) {
            window["tt"].reportAnalytics(event, {
                type: msg,
            });
            ZYSDK.ZYSDK.reportUserAction(msg);
            GEMgr.GEReportEvent(msg);
        }
        if (AppPlatform.is_WECHAT_GAME_custom()) {
            event = event.toLowerCase();
            window["wx"].reportEvent(event, {
                "type": msg,
            });
            ZYSDK.ZYSDK.reportUserAction(msg);
            GEMgr.GEReportEvent(msg);
        }

    }

    public static ReportDYTime(event, level, times) {
        let eventStr = level + '-time-' + Math.round(times / 60)
        if (AppPlatform.is_TT_GAME_custom()) {
            window["tt"].reportAnalytics(event, {
                "type": eventStr,
            });
            ZYSDK.ZYSDK.reportUserAction(eventStr);
        }
        if (AppPlatform.is_WECHAT_GAME_custom()) {
            event = event.toLowerCase();
            window["wx"].reportEvent(event, {
                "type": eventStr,
            });
            ZYSDK.ZYSDK.reportUserAction(eventStr);
        }
    }

    public static stopMusic() {
        cc.audioEngine.stopAll();
    }
    public static playEffect(music) {
        if (this.isNoEffect) {
            return;
        }
        this.getSoundFromBundle_custom("CommonRes", music, false);
    }
    public static playEffectCustom(prefab, music) {
        // cc.audioEngine.stopAllEffects();
        if (this.isNoEffect) {
            return;
        }
        this.getSoundFromBundle_custom(prefab, music, false);
    }

    public static playMusic(music) {
        if (this.isNoMusic) {
            return;
        }
        this.getSoundFromBundle_custom("CommonRes", music, true);
    }

    public static getPlayMusicAudioId() {
        return this.audioId
    }

    public static getSpriteFrameFromBundle(bundlename = "subResAddMode", url: string, targetSprite: cc.Sprite = null, callback = null) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            subres.load(url, cc.SpriteFrame, (err, sprite: cc.SpriteFrame) => {
                if (err) {
                    console.log(err)
                    return null;
                }
                if (targetSprite != null) {
                    targetSprite.spriteFrame = sprite;
                }
                if (callback) {
                    callback(sprite);
                }
            })
        }
    }

    public static getSpriteFrameFromBundlePro(bundlename = "subResAddMode", url: string) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            console.log('预加载图片+++', url)
            subres.preload(url)
        }
    }





    /**
     * 
     * @param bundlename 分包名
     * @param url 预制体地址
     * @param parentNode 父节点
     * @param callback 回调函数
     */
    public static getPrefabFromBundlePrefabLayer(bundlename = "subRes_Resources", url: string, parentNode: cc.Node = null, callback = null) {
        let subres = cc.assetManager.getBundle(bundlename);
        // let startDaDianTime = new Date().getTime();

        if (subres) {
            subres.load(url, cc.Prefab, (err, prefab: cc.Prefab) => {
                if (err) {
                    console.log(err, 'error')
                    return null;
                }
                PrefabManage.curRelesePrefab = prefab
                var prefabNode = cc.instantiate(prefab);


                // if (this.prefabMap.has(url)) {
                //     let prefab2 = this.prefabMap.get(url)
                //     console.log('删除---预制体缓存???-----',url)
                //     cc.assetManager.releaseAsset(prefab2)
                //     console.log('增加---预制体缓存???-----')
                //     this.prefabMap.set(url,prefab)
                // }else{
                //     this.prefabMap.set(url,prefab)
                // }
                this.prefabMap.set(url, prefab)


                if (parentNode != null) {
                    //console.log('addChild2222')
                    if (cc.isValid(parentNode, true)) {
                        parentNode.addChild(prefabNode)
                    }

                } else {
                    //console.log('addChild3333')
                    let prefabLayer = cc.director.getScene().getChildByName("Canvas").getChildByName('prefabLayer')
                    if (cc.isValid(prefabLayer, true)) {
                        prefabLayer.addChild(prefabNode);
                    }


                    //console.log('addChild4444')
                }

                if (callback) {

                    callback(prefabNode);
                }
            })
        }
    }

    public static getPrefabFromBundlePopLayer(bundlename = "subRes_Resources", url: string, parentNode: cc.Node = null, callback = null) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            subres.load(url, cc.Prefab, (err, prefab: cc.Prefab) => {
                if (err) {
                    return null;
                }

                var prefabNode = cc.instantiate(prefab);
                if (parentNode != null) {
                    parentNode.addChild(prefabNode)
                } else {
                    let popLayer = cc.director.getScene().getChildByName("Canvas").getChildByName('popLayer')
                    popLayer.addChild(prefabNode);;

                    //cc.director.getScene().getChildByName("Canvas").addChild(prefabNode);;
                }
                if (callback) {
                    callback(prefabNode);
                }
            })
        }
    }

    /**
     * 
     * @param bundlename 分包名
     * @param url 预制体地址
     * @param parentNode 父节点
     * @param callback 回调函数
     */
    public static getSpineFromBundle(bundlename = "subRes_Resources", url: string, parentNode: cc.Node = null, callback = null) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            subres.load(url, sp.SkeletonData, function (err, spine: sp.SkeletonData) {
                if (err) {
                    cc.log(err.message || err);
                    return;
                }
                let node = new cc.Node('spineNode');
                const ske = node.addComponent(sp.Skeleton);
                ske.skeletonData = spine;
                // ske.setAnimation(0, 'heishan', true);
                // parentNode.addChild(node);

                var prefabNode = cc.instantiate(node);
                // parentNode.addChild(node);
                // prefabNode.parent = parentNode;
                if (callback) {
                    callback(prefabNode);
                }
            });

        }
    }

    //随机排序数组
    public static shuffle(arr) {
        var len = arr.length;
        let setran = []
        for (var i = len - 1; i >= 0; i--) {
            var rand = Math.floor(Math.random() * (arr.length - 0.01));
            //console.log("rand===", rand)
            setran.push(arr[rand]);
            arr.splice(rand, 1);
        }
        return setran;
    }
    public static shuffle_noremove(arr) {
        var len = arr.length;
        let setran = []
        for (var i = len - 1; i >= 0; i--) {
            var rand = Math.floor(Math.random() * (arr.length - 0.01));
            //console.log("rand===", rand)
            setran.push(arr[rand]);
        }
        return setran;
    }

    //对数组进行分组
    public static groupingArr(targetArr: number[], groupCount: number) {
        let returnArr = [];
        for (var i = 0; i < groupCount; i++) {
            if (targetArr.length > 0) {
                let mathIndex = Math.floor(Math.random() * targetArr.length);
                returnArr[i] = [targetArr[mathIndex]];
                targetArr.splice(mathIndex, 1);
            }
        }

        if (targetArr.length > 0) {
            for (var i = 0; i < targetArr.length; i++) {

                let mathIndex = Math.floor(Math.random() * returnArr.length);
                if (returnArr[mathIndex].length == 1) {
                    returnArr[mathIndex].push(targetArr[i]);
                }

            }
        }
        //console.log("---returnArr+++", returnArr)
        return returnArr;
    }

    public static parabolaFunc(parabolaNode: cc.Node, startPos: cc.Vec2, endPos: cc.Vec2, height: number, time: number, func: Function = null) {
        //抛物线运动,从起点到终点
        let controlPos = cc.v2((startPos.x + endPos.x) / 2, ((startPos.y + endPos.y) / 2 + height));
        cc.tween(parabolaNode).bezierTo(time, startPos, controlPos, endPos).call(() => {
            if (func != null) {
                func();
            }
        }).start();
    }


    /**
     * 获取节点在目标节点(容器)下的相对位置
     * @param node 当前节点
     * @param container 目标节点(容器)
     * @param pos 当前节点上的位置(可选)
     */
    public static getRelativePosition(node: cc.Node, container: cc.Node, pos?: cc.Vec2): cc.Vec2 {
        let vpos = pos || cc.Vec2.ZERO;
        const worldPos = node.convertToWorldSpaceAR(vpos);
        return container.convertToNodeSpaceAR(worldPos);
    }

    // update (dt) {}


    /**
   * 创建一个预制体
   * @param prefab 预制体
   * @param parent 接收的父节点 为null 则放到场景中 场景必须要有 Canvas 节点
   */
    public static createPrefab_custom(prefab: cc.Prefab, parent?: cc.Node,) {
        let node = cc.instantiate(prefab);
        if (parent) {
            // parent.addChild(node);
            node.parent = parent
        } else {
            cc.find('Canvas').addChild(node, 0);
        }
        return node;
    }
    public static getJsonFromBundle(bundlename = "subRes_resources", url: string, callback) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            subres.load(url, cc.JsonAsset, (err, essest: cc.JsonAsset) => {
                if (err) {
                    console.log('加载json错误>:', err);
                    return null;
                }

                //console.log('加载json>:', bundlename, essest);
                callback(essest)
            })
        }
    }
    //深拷贝
    public static deepClone = <T>(origin: T, target?: Record<string, any> | T): T => {
        // 判断是否为数组
        let isArr = (origin: any): boolean => {
            let str = '[object Array]'
            return Object.prototype.toString.call(origin) == str ? true : false
        }

        let tar: any = target || []

        for (const key in origin) {
            if (Object.prototype.hasOwnProperty.call(origin, key)) {
                if (typeof origin[key] === 'object' && origin[key] !== null) {
                    tar[key] = isArr(origin[key]) ? [] : {}
                    Common5.deepClone(origin[key], tar[key])
                } else {
                    tar[key] = origin[key]
                }
            }
        }

        return tar as T
    }

    /**
     * !#zh 矩形目标是否包含当前节点。
     * @param rectTargetNode 矩形目标节点
     * @param curNode 当前节点
     */
    public static checkContainsNode(rectTargetNode: cc.Node, curNode: cc.Node) {
        let pworld = rectTargetNode.getBoundingBoxToWorld()
        let pos1 = curNode.convertToWorldSpaceAR(cc.Vec2.ZERO)


        if (pworld.contains(pos1)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * !#zh 当前矩形与目标矩形是否相交。
     * @param curRectNode 当前矩形节点
     * @param targetRectNode 目标矩形节点
     */
    public static checkIntersectsBox(curRectNode: cc.Node, targetRectNode: cc.Node): boolean {
        if (!curRectNode) {
            console.log('curRectNode null')
            return
        }
        if (!targetRectNode) {
            console.log('targetRectNode null')
            return
        }
        let pworld = curRectNode.getBoundingBoxToWorld()
        let box1 = targetRectNode.getBoundingBoxToWorld()


        if (pworld.intersects(box1)) {
            return true;
        } else {
            return false;
        }
    }



    /**
     * 将当前节点移动到为目标节点的位置
     * @param curNode 当前节点
     * @param targetNode 目标节点
     */
    public static setNodeToTargetPos(curNode, targetNode) {
        //目标节点的本地坐标
        if (cc.isValid(curNode)) {

        } else {
            return cc.v2(0, 0)
        }


        if (cc.isValid(targetNode) && cc.isValid(targetNode.parent)) {

        } else {
            return cc.v2(0, 0)
        }

        let targetLocalPos = targetNode.getPosition()
        //目标节点的世界坐标
        let targetWorldPos = targetNode.parent.convertToWorldSpaceAR(targetLocalPos)

        //目标节点相对于当前节点父节点的本地坐标
        let localPos = curNode.parent.convertToNodeSpaceAR(targetWorldPos)
        curNode.setPosition(localPos)
    }

    public static getNodeToTargetPos(curNode, targetNode) {
        //目标节点的本地坐标
        let targetLocalPos = targetNode.getPosition()
        //目标节点的世界坐标
        let targetWorldPos = targetNode.parent.convertToWorldSpaceAR(targetLocalPos)

        //目标节点相对于当前节点父节点的本地坐标
        let localPos = curNode.parent.convertToNodeSpaceAR(targetWorldPos)
        return localPos
    }
    /**
     * //检测多边形物体是否超出多边形区域(节点必须携带PolygonCollider属性) 注意offest距离要变为0和0
     * @param targetNode 要检测的物体
     * @param targetArea 要检测的区域
     * @returns 
     */
    public static checkIsOutOfArea(targetNode, targetArea) {
        let targetCollider = targetNode.getComponent(cc.PolygonCollider)
        let areaCollider = targetArea.getComponent(cc.PolygonCollider)
        //目标节点的本地坐标
        let targetLocalPos = targetNode.getPosition()
        //目标节点的世界坐标
        let targetWorldPos = targetNode.parent.convertToWorldSpaceAR(targetLocalPos)
        //目标节点相对于当前节点的本地坐标
        let localPos = targetArea.convertToNodeSpaceAR(targetWorldPos)

        for (var i = 0; i < targetCollider.points.length; i++) {
            let newPoint = cc.v2(localPos.x + targetCollider.points[i].x, localPos.y + targetCollider.points[i].y)
            if (!cc.Intersection.pointInPolygon(newPoint, areaCollider.points)) {
                console.log("这个点不在区域内", i)
                return false
            }
        }
        console.log("目标物全部在区域内")
        return true
    }


    public static getNumberChangeHanzi(value: number, type = '1', fixedLength = 4) {
        const newValue = ['', '', '']
        let fr = 1000
        let num = 3
        let text1 = ''
        let text2 = ''
        let fm = 1
        if (value == null || isNaN(value)) {
            return !type ? newValue : ''
        }

        if (value < 0) {
            value = Math.abs(value);
            text2 = '-'
        }
        while (value / fr >= 1) {
            fr *= 10
            num += 1
            // console.log('数字', value / fr, 'num:', num)
        }
        if (num <= 4) { // 千
            let power = Math.pow(10, 1)
            newValue[0] = (Math.floor((value / fm) * power) / power) + ''
            newValue[1] = ''

        } else if (num <= 8) { // 万
            // text1 = parseInt(num - 4) / 3 > 1 ? '千万' : '万'
            text1 = '万'
            // tslint:disable-next-line:no-shadowed-variable
            fm = text1 === '万' ? 10000 : 10000000
            if (value % fm === 0) {
                newValue[0] = parseInt((value / fm).toString()) + ''
            } else {
                // newValue[0] = parseFloat((value / fm).toString()).toFixed(fixedLength) + ''
                let power = Math.pow(10, fixedLength)
                newValue[0] = (Math.floor((value / fm) * power) / power) + ''
            }
            newValue[1] = text1
        } else { // 亿 if (num <= 16)
            // text1 = (num - 8) / 3 > 1 ? '千亿' : '亿'
            text1 = '亿'
            text1 = (num - 8) / 4 > 1 ? '兆' : text1
            text1 = (num - 8) / 8 > 1 ? '京' : text1
            text1 = (num - 8) / 12 > 1 ? '垓' : text1
            text1 = (num - 8) / 16 > 1 ? '秭' : text1
            text1 = (num - 8) / 20 > 1 ? '穰' : text1
            text1 = (num - 8) / 24 > 1 ? '沟' : text1
            text1 = (num - 8) / 28 > 1 ? '涧' : text1
            text1 = (num - 8) / 32 > 1 ? '正' : text1
            text1 = (num - 8) / 36 > 1 ? '载' : text1
            text1 = (num - 8) / 40 > 1 ? '极' : text1
            text1 = (num - 8) / 44 > 1 ? '恒' : text1
            text1 = (num - 8) / 48 > 1 ? '僧' : text1
            text1 = (num - 8) / 52 > 1 ? '由' : text1
            text1 = (num - 8) / 56 > 1 ? '思' : text1
            text1 = (num - 8) / 60 > 1 ? '量' : text1
            text1 = (num - 8) / 64 > 1 ? '数' : text1
            text1 = (num - 8) / 68 > 1 ? '全' : text1//76
            text1 = (num - 8) / 72 > 1 ? '亦' : text1
            text1 = (num - 8) / 76 > 1 ? '王' : text1
            text1 = (num - 8) / 80 > 1 ? '肤' : text1
            text1 = (num - 8) / 84 > 1 ? '张' : text1
            text1 = (num - 8) / 88 > 1 ? '战' : text1
            text1 = (num - 8) / 92 > 1 ? '古' : text1
            text1 = (num - 8) / 96 > 1 ? '戈' : text1
            text1 = (num - 8) / 100 > 1 ? '星' : text1
            text1 = (num - 8) / 104 > 1 ? '巨' : text1

            // tslint:disable-next-line:no-shadowed-variable
            fm = 1
            let text3 = ''
            if (text1 === '亿') {
                fm = 100000000
                text3 = '万'
            } else if (text1 === '兆') {
                text3 = '亿'
                fm = Math.pow(10, 12)
            } else if (text1 === '京') {
                text3 = '兆'
                fm = Math.pow(10, 16)
            } else if (text1 === '垓') {
                text3 = '京'
                fm = Math.pow(10, 20)
            } else if (text1 === '秭') {
                text3 = '垓'
                fm = Math.pow(10, 24)
            } else if (text1 === '穰') {
                text3 = '秭'
                fm = Math.pow(10, 28)
            } else if (text1 === '沟') {
                text3 = '穰'
                fm = Math.pow(10, 32)
            } else if (text1 === '涧') {
                text3 = '沟'
                fm = Math.pow(10, 36)
            } else if (text1 === '正') {
                text3 = '涧'
                fm = Math.pow(10, 40)
            } else if (text1 === '载') {
                text3 = '正'
                fm = Math.pow(10, 44)
            } else if (text1 === '极') {
                text3 = '载'
                fm = Math.pow(10, 48)
            } else if (text1 === '恒') {
                text3 = '载'
                fm = Math.pow(10, 52)
            } else if (text1 === '僧') {
                text3 = '恒'
                fm = Math.pow(10, 56)
            } else if (text1 === '由') {
                text3 = '僧'
                fm = Math.pow(10, 60)
            } else if (text1 === '思') {
                text3 = '由'
                fm = Math.pow(10, 64)
            } else if (text1 === '量') {
                text3 = '思'
                fm = Math.pow(10, 68)
            } else if (text1 === '数') {
                text3 = '量'
                fm = Math.pow(10, 72)
            } else if (text1 === '全') {
                text3 = '数'
                fm = Math.pow(10, 76)
            } else if (text1 === '亦') {
                text3 = '全'
                fm = Math.pow(10, 80)
            } else if (text1 === '王') {
                text3 = '亦'
                fm = Math.pow(10, 84)
            } else if (text1 === '肤') {
                text3 = '王'
                fm = Math.pow(10, 88)
            } else if (text1 === '张') {
                text3 = '肤'
                fm = Math.pow(10, 92)
            } else if (text1 === '战') {
                text3 = '张'
                fm = Math.pow(10, 96)
            } else if (text1 === '古') {
                text3 = '战'
                fm = Math.pow(10, 100)
            } else if (text1 === '戈') {
                text3 = '古'
                fm = Math.pow(10, 104)
            } else if (text1 === '星') {
                text3 = '戈'
                fm = Math.pow(10, 108)
            } else if (text1 === '巨') {
                text3 = '星'
                fm = Math.pow(10, 112)
            } else {
                text3 = '星'
                text1 = '巨'
                fm = Math.pow(10, 112)
            }

            if (value % fm === 0) {
                newValue[0] = parseInt((value / fm).toString()) + ''
            } else {
                // newValue[0] = parseFloat((value / fm).toString()).toFixed(fixedLength) + ''
                let power = Math.pow(10, fixedLength)
                newValue[0] = (Math.floor((value / fm) * power) / power) + ''
            }
            newValue[1] = text1
            newValue[2] = text3
        }
        if (value < 1000) {
            newValue[0] = value + ''
            newValue[1] = ''
        }
        newValue[0] = text2 ? text2 + newValue[0] : newValue[0]

        if (text1 === '巨') {
            let num = Number(newValue[0])
            newValue[0] = num.toExponential(0) + ''

        }

        if (fixedLength != 4) {
            return !type ? newValue : (newValue[0] + newValue[1])
        }
        if (newValue[1] == '万') {
            //return !type?newValue:(newValue[0] + newValue[1])
            let str2 = newValue[0].split(".");
            if (str2[1]) {
                let num = Math.floor(Number(0 + '.' + str2[1]) * 10000)
                str2[1] = num + ''
                return !type ? newValue : (str2[0] + newValue[1] + str2[1] + newValue[2])
            } else {
                return !type ? newValue : (newValue[0] + newValue[1])
            }

        } else if (newValue[1].length > 0) {
            let str2 = newValue[0].split(".");
            if (str2[1]) {
                let num = Math.floor(Number(0 + '.' + str2[1]) * 10000)
                str2[1] = num + ''
                return !type ? newValue : (str2[0] + newValue[1] + str2[1] + newValue[2])
            } else {
                return !type ? newValue : (newValue[0] + newValue[1])
            }

        } else {
            return !type ? newValue : (newValue[0] + newValue[1])
        }

    }



    // let array_ = [20,20,20,20,20,20,70,70,70,70,70,70,70,70,10,0]
    // let backi = this.getResult(array_)
    //随机概率
    public static getProbabilityResultIndex(arr) {
        var leng = 0;
        for (var i = 0; i < arr.length; i++) {
            leng += arr[i]                                      //获取总数
        }
        for (var i = 0; i < arr.length; i++) {
            var random = Math.random() * leng;                    //获取 0-总数 之间的一个随随机整数
            if (random < arr[i]) {
                return i                                        //如果在当前的概率范围内,得到的就是当前概率
            }
            else {
                leng -= arr[i]                                  //否则减去当前的概率范围,进入下一轮循环
            }
        }
    }


    //从min到max中随机取出n个值
    public static getNumberFromArray(min, max, count) {
        //原数组
        var arr = [];
        for (var i = min; i < max; i++) {
            arr.push(i)
        }
        //输出数组
        let temp = []
        let length = arr.length
        while (count > 0) {
            var index = Math.floor(Math.random() * length)
            temp.push(arr[index])
            arr.splice(index, 1)

            length--
            count--
        }
        // console.log("temp==",temp)
        return temp
    }
    //获取值在数组中的索引
    public static getIndexInArray(arr, val) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] == val) {
                return i;
            }
        }
        return -1;
    };
    //删除数组的某个值
    public static removeValueInArray(arr, val) {
        var index = this.getIndexInArray(arr, val);
        if (index > -1) {
            arr.splice(index, 1);
        }
        return arr
    };
    /**
     * 目标数组产生随机下标
     * @param targetArr 目标数组
     * @returns 
     */
    public static getTargetArrIndexId(targetArr) {
        let randomIndex = Math.floor(Math.random() * 100)
        // console.log("randomIndex==",randomIndex)
        let sum = 0
        let selectId = 0
        for (var j = 0; j < targetArr.length; j++) {
            sum += targetArr[j]
            if (randomIndex < sum) {
                selectId = j
                break
            }
        }
        // console.log("targetArr==selectId=",targetArr,selectId)
        return selectId
    }


    public static copyex(src: string, first: string, end: string) {
        let len1 = first.length;
        //let len2 = end.length;
        let result = src.substring(src.indexOf(first) + len1, src.indexOf(end) + 0)
        return result;
    }

    /**
     * 判断时间是否为当天
     * @param timeStampA 时间A,number类型
     * @param timeStampB 时间B,number类型
     * @returns true/false
    */
    public static isSameDay(timeStampA: number, timeStampB: number): boolean {
        let dateA = new Date(timeStampA);
        let dateB = new Date(timeStampB);
        return (dateA.setHours(0, 0, 0, 0) == dateB.setHours(0, 0, 0, 0));
    }

    public static getCurSecond() {
        return Date.parse(new Date().toString()) / 1000;
    }

    //格式化时间获取:分秒 00:00
    public static formatTime3_custom(time: number): string {

        let str: string = "";

        let m: number = time / 60;
        m = parseInt(m + "");
        let s: number = time - m * 60;
        s = parseInt(s + "");

        if (m > 9) {
            str += m + ":";
        }
        else {
            str += "0" + m + ":";
        }
        if (s > 9) {
            str += s;
        }
        else {
            str += "0" + s;
        }
        return str;
    }

    //格式化时间获取:时分秒 00:00:00
    public static formatTime_custom(time: number): string {
        let str: string = "";
        let h: number = time / 3600;
        h = parseInt(h + "");
        let m: number = (time - h * 3600) / 60;
        m = parseInt(m + "");
        let s: number = time - h * 3600 - m * 60;
        s = parseInt(s + "");
        if (h > 9) {
            str += h + ":";
        } else {
            str += "0" + h + ":";
        }
        if (m > 9) {
            str += m + ":";
        }
        else {
            str += "0" + m + ":";
        }
        if (s > 9) {
            str += s + "";
        }
        else {
            str += "0" + s;
        }
        return str;
    }
    //格式化时间获取:时分 00:00
    public static formatTimeHM_custom(time: number): string {
        let str: string = "";
        let h: number = time / 3600;
        h = parseInt(h + "");
        let m: number = (time - h * 3600) / 60;
        m = parseInt(m + "");
        // let s: number = time - h * 3600 - m * 60;
        // s = parseInt(s + "");
        if (h > 9) {
            str += h + ":";
        } else {
            str += "0" + h + ":";
        }
        if (m > 9) {
            str += m
        }
        else {
            str += "0" + m
        }

        return str;
    }

    public static getArrDifference(arr1, arr2) {

        let arr3 = []
        for (let value of arr1) {
            arr3.push(value)
        }
        return arr3.concat(arr2).filter(
            (value, i, arr) => {
                return arr.indexOf(value) === arr.lastIndexOf(value);
            }
        )
    }
    public static playMusicCustom(bundle, music) {
        if (this.isNoMusic) {
            return;
        }
        this.getSoundFromBundle_custom(bundle, music, true);
    }
    public static showTips_customTimeNew(text: string, delay: number, pos) {
        let canvas = cc.find("Canvas");
        let node = new cc.Node("tips");
        let label = node.addComponent(cc.Label);
        label.string = text;
        label.enableBold = false;
        label.fontSize = 40;
        label.lineHeight = 50;
        let outline = node.addComponent(cc.LabelOutline);
        outline.width = 5;
        outline.color = cc.Color.RED;//new cc.Color(0, 0, 0, 255);
        canvas.addChild(node);

        let y = pos.y + 100;

        node.x = pos.x;
        node.y = pos.y;
        cc.tween(node).delay(delay).to(1, { y: y, opacity: 0 }).call(() => {
            node.removeFromParent();
        }).start();

    }
    public static formatNumber(num) {
        let str = ""
        if (num >= 100000000) {
            str = num / 100000000 + "亿"
        } else if (num >= 10000) {
            str = num / 10000 + "万"
        }
        return str
    }

    /**
 * 
 * @param bundlename 分包名
 * @param url 预制体地址
 * @param parentNode 父节点
 * @param callback 回调函数
 */
    public static getPrefabFromBundle(bundlename = "subRes_resources", url: string, parentNode: cc.Node = null, callback = null) {
        let subres = cc.assetManager.getBundle(bundlename);
        if (subres) {
            subres.load(url, cc.Prefab, (err, prefab: cc.Prefab) => {
                if (err) {
                    console.log('加载预制体错误>:', err);
                    return null;
                }
                console.log("加载成功:", prefab.name);
                var prefabNode = cc.instantiate(prefab);
                if (parentNode != null) {
                    parentNode.addChild(prefabNode)
                } else {
                    cc.director.getScene().getChildByName("Canvas").addChild(prefabNode);;
                }
                // prefabNode.parent = parentNode;
                if (callback) {
                    callback(prefabNode);
                }
            })
        }
    }

    public static checkEqualOfTwoArr(arr1, arr2) {
        if (arr1.length != arr2.length) {
            return false
        }
        for (let i = 0; i < arr1.length; i++) {
            if ((arr1[i] instanceof Array) && (arr2[i] instanceof Array)) {
                if (arr1[i].length != arr2[i].length) {
                    return false
                }
                // for(let j=0;j<arr1[i].length;j++){
                //     if(!this.isObjectEqual(arr1[i][j],arr2[i][j])){
                //         return false
                //     }
                // }
            } else if ((arr1[i] instanceof Number) && (arr2[i] instanceof Number)) {
                if (arr1[i] != arr2[i]) {
                    return false
                }
            } else {
                return false
            }
        }
        return true
    }


    /**
     * 加载远程图片
     * @param picSp 图片展示sprite
     * @param url 图片地址
     */
    public static addUrlSprite_custom(url: string, picSp: cc.Sprite, pngStr = '.png') {
        let str: string = url;


        if (this.imgMap.has(str)) {
            picSp.spriteFrame = this.imgMap.get(str);

            return;
        }

        if (!Common5.imgMap.has(str)) {
            // console.log("预加载图片:", str);

            let path: string = AppConfig.ResServer_custom + url;
            cc.assetManager.loadRemote(path + pngStr + '?time=test1', { maxRetryCount: 0 }, (err, texture: cc.Texture2D) => {
                if (err) return;
                // console.log("预加载图片:", path + pngStr);

                Common5.imgMap.set(str, new cc.SpriteFrame(texture));
                picSp.spriteFrame = this.imgMap.get(str);

            });
        }
    }

    //从远程url设置sprite资源
    public static setRemoteSpriteFrame(sprite: cc.Sprite, url: string) {
        let path: string = AppConfig.ResServer_custom + url
        console.log('url图片路径:' + path)
        if (this.imgMap.has(path)) {
            sprite.spriteFrame = this.imgMap.get(path);
            return;
        }
        console.log("还没有先下载");

        cc.assetManager.loadRemote(path + ".png" + '?time=test1', { maxRetryCount: 0 }, (err, texture: cc.Texture2D) => {
            if (err) return;
            this.imgMap.set(path, new cc.SpriteFrame(texture));
            sprite.spriteFrame = this.imgMap.get(path);
        });
    }

    //从远程预加载音效/音乐
    public static preloadRemoteAudio(url: string) {
        if (!url) {
            return
        }
        let path: string = AppConfig.ResServer_custom + url
        console.log('url音效路径:' + path)
        if (this.audioMap.has(path)) {
            return;
        }

        cc.assetManager.loadRemote(path + '.mp3', (err, audioClip: cc.AudioClip) => {

        });
    }

    public static proLoadPicBuyUrl(url: string, pngStr = '.png') {
        let str: string = url;
        if (this.imgMap.has(str)) {

            return;
        }

        if (!Common5.imgMap.has(str)) {
            // console.log("预加载图片:", str);

            let path: string = AppConfig.ResServer_custom + url;
            cc.assetManager.loadRemote(path + pngStr, { maxRetryCount: 0 }, (err, texture: cc.Texture2D) => {
                if (err) return;

                Common5.imgMap.set(str, new cc.SpriteFrame(texture));


            });
        }
    }


    //从远程url设置音乐
    public static playRemoteAudioMusic(url: string, isLoop: boolean = true) {
        if (Common5.isNoMusic) {
            return;
        } else if (Common5.isMute == true) {
            return;
        }
        let path: string = AppConfig.ResServer_custom + url
        //console.log('url音乐路径:'+url)
        if (this.audioMap.has(url)) {
            this.audioId = cc.audioEngine.playMusic(this.audioMap.get(url), isLoop);
            return;
        }
        //console.log("还没有先下载");

        cc.assetManager.loadRemote(path + '.mp3', (err, audioClip: cc.AudioClip) => {
            if (err) {
                console.log(err)
                return;
            }
            if (audioClip) {
                this.audioMap.set(url, audioClip);
                this.audioId = cc.audioEngine.playMusic(audioClip, isLoop);
                cc.audioEngine.setMusicVolume(0.5)
            }
        });
    }

    //从远程url设置音效
    public static playRemoteAudioEffect(url: string, isLoop: boolean = false) {
        //cc.audioEngine.stopAllEffects();
        if (Common5.isNoEffect) {
            return;
        } else if (Common5.isMute == true) {
            return;
        }
        let path: string = AppConfig.ResServer_custom + url
        //console.log('url音效路径:'+url)
        if (this.audioMap.has(url)) {
            this.audioId = cc.audioEngine.play(this.audioMap.get(url), isLoop, 1);
            return;
        }
        //console.log("还没有先下载");

        cc.assetManager.loadRemote(path + '.mp3', (err, audioClip: cc.AudioClip) => {
            if (audioClip) {
                this.audioMap.set(url, audioClip);
                this.audioId = cc.audioEngine.play(audioClip, isLoop, 1);
            }
        });
    }

    //从远程url设置音效返回id
    public static playRemoteAudioEffect_id(url: string, isLoop: boolean = false, callfunc?) {
        //cc.audioEngine.stopAllEffects();
        if (Common5.isNoEffect) {
            return;
        } else if (Common5.isMute == true) {
            return;
        }
        let path: string = AppConfig.ResServer_custom + url
        //console.log('url音效路径:'+url)
        if (this.audioMap.has(url)) {
            let id = cc.audioEngine.play(this.audioMap.get(url), isLoop, 1);
            if (callfunc) {
                callfunc(id)
            }
            return;
        }
        //console.log("还没有先下载");

        cc.assetManager.loadRemote(path + '.mp3', (err, audioClip: cc.AudioClip) => {
            if (audioClip) {
                this.audioMap.set(url, audioClip);
                let id = cc.audioEngine.play(audioClip, isLoop, 1);
                if (callfunc) {
                    callfunc(id)
                }
            }
        });
    }

    public static loadRemoteAudioEffect(url: string) {
        if (this.audioMap.has(url)) {

            return;
        }

        let path: string = AppConfig.ResServer_custom + url
        //console.log('预加载url音效路径:'+url)

        cc.assetManager.loadRemote(path + '.mp3', (err, audioClip: cc.AudioClip) => {
            if (audioClip) {
                this.audioMap.set(url, audioClip);

            }
        });
    }


    public static loadRemoteSpine(gamePath: string, spineName: string) {
        let path: string = AppConfig.ResServer_custom + gamePath + '/' + spineName
        let url = gamePath + '/' + spineName

        if (this.spineMap.has(url)) {
            return;
        }
        //console.log('预下载url动效路径:'+url)
        cc.loader.load({ url: path + ".atlas" + '?time=test1', type: 'text' }, (err, spineAtlas) => {
            cc.loader.load({ url: path + ".json" + '?time=test1', type: 'json' }, (err, spineJson) => {
                var asset = new sp.SkeletonData();
                asset.skeletonJson = spineJson;
                asset.atlasText = spineAtlas;
                asset.textures = [];
                cc.loader.load({ url: path + ".png" + '?time=test1', type: 'png' }, (err, texture) => {
                    asset.textures.push(texture);
                    asset["textureNames"] = [spineName + ".png"];
                    this.spineMap.set(url, asset)

                });
            });
        });
    }

    //从远程url设置spine
    public static playRemoteSpine(_node: cc.Node, gamePath: string, spineName: string, aniName: string, isloop: boolean = true, skinName?: string, timeScale = 1, isPlay?: boolean) {
        _node.active = true
        let playSpine = (n: sp.Skeleton | cc.Node, aniName: string, isloop: boolean = true, skinName?: string,) => {
            let _sp: sp.Skeleton;
            if (n instanceof cc.Node) {
                _sp = n.getComponent(sp.Skeleton);
            } else {
                _sp = n;
            }
            _sp.loop = isloop;
            _sp.animation = aniName;
            if (skinName) {
                _sp.setSkin(skinName);
            }
            if (timeScale != 1) {
                _sp.timeScale = timeScale
            }

        };

        let path: string = AppConfig.ResServer_custom + gamePath + '/' + spineName
        let url = gamePath + '/' + spineName

        if (this.spineMap.has(url)) {
            if (cc.isValid(_node, true)) {
                _node.getComponent(sp.Skeleton).skeletonData = this.spineMap.get(url);
                playSpine(_node, aniName, isloop, skinName)
            }
            // _node.getComponent(sp.Skeleton).skeletonData = this.spineMap.get(url);
            // playSpine(_node, aniName, isloop,skinName)
            return;
        }
        //console.log('url动效路径:'+path)
        //console.log("还没有动画先下载", spineName);
        cc.loader.load({ url: path + ".atlas" + '?time=test1', type: 'text' }, (err, spineAtlas) => {
            cc.loader.load({ url: path + ".json" + '?time=test1', type: 'json' }, (err, spineJson) => {
                var asset = new sp.SkeletonData();
                asset.skeletonJson = spineJson;
                asset.atlasText = spineAtlas;
                asset.textures = [];
                cc.loader.load({ url: path + ".png" + '?time=test1', type: 'png' }, (err, texture) => {
                    asset.textures.push(texture);
                    asset["textureNames"] = [spineName + ".png"];
                    this.spineMap.set(url, asset)
                    if (cc.isValid(_node, true)) {
                        _node.getComponent(sp.Skeleton).skeletonData = asset
                        playSpine(_node, aniName, isloop, skinName)
                    }
                });
            });
        });
    }


    public static preLoadRemoteAudioByChatConfig(soundConfig) {
        for (let i = 0; i < soundConfig.length; i++) {
            Common5.preloadRemoteAudio(soundConfig[i].effectUrl)
        }
    }

    //根据时间间隔才能弹插屏
    public static showInterstitialAd() {
        let time = 10 * 60
        let delayTime = 1 * 60
        // 在线10分钟后才能弹 
        // 所有弹插屏间隔要大于1分钟
        if (UserManager.onlineTime >= time && UserManager.onlineTime - delayTime >= UserManager.lastTime) {
            UserManager.lastTime = UserManager.onlineTime
            TTAPI.showInterstitialAd()
        }
    }

    public static addZuanShi(zuanshi, startNode?,endNode?) {
        if (zuanshi > 0) {
            // Common5.playEffect('获得钱币')  
            // if(startNode && endNode){
            //     PrefabManage.showZuanShiFlyEffect(startNode,endNode)
            // }   
        }

        User.setZuanShi(User.getZuanShi() + zuanshi);
        EventMgr.emitEvent_custom(ryw_Event.updateZuanShi, zuanshi);
        
    }
    public static subZuanShi(zuanshi) {
        User.setZuanShi(Math.max(User.getZuanShi() - zuanshi, 0));
        EventMgr.emitEvent_custom(ryw_Event.updateZuanShi, -zuanshi);
    }
    public static getCurZuanShi() {
        let zuanshi = User.getZuanShi()
        return zuanshi
    }
}