let pg = {};
//打印
pg.logger = {
    d: (str) => {
        cc.log(str);
    },
    w: function (str) {
        cc.warn(str);
    }
}
const log = pg.logger;
//显示常用
pg.view = {
    //显示隐藏

    //添加节点

    //删除节点

    //加载网络节点


    touchEnable(item, isEnable) {
        if (!item) return pg.logger.w("设置按钮响应失败,传入了错误的item");
        let node = item.node ? item.node : item;
        if (!node) return pg.logger.w("设置按钮响应失败,传入了错误的item");
        let btn = node.getComponent(cc.Button);
        if (!btn) return pg.logger.w("当前节点没有添加button->" + node.name);
        btn.interactable = isEnable;
        return true;
    },
    touchOn(item, callback, target) {
        if (!item) return pg.logger.w("添加按钮响应失败,传入了错误的item");
        if (!callback || !target) return pg.logger.w("添加按钮响应失败,传入了空回调");
        let node = item.node ? item.node : item;
        node.on(cc.Node.EventType.TOUCH_END, callback, target);
        return true;
    },
    touchOff(item, callback, target) {
        if (!item) return log.w("移除按钮响应失败,传入了错误的item");
        if (!callback || !target) return log.w("移除按钮响应失败,传入了空回调");
        let node = item.node ? item.node : item;
        if (!node || !node.parent) return log.w("节点已移除");
        node.off(cc.Node.EventType.TOUCH_END, callback, target);
        return true;
    },

    //更换图片
    setImg(item, res) {
        return new Promise((resolve, reject) => {
            if (!item) return log.w("图片更换失败,传入了错误的item");
            if (!res) return log.w("图片更换失败,传入了错误的res");
            pg.load.loadImg(res).then((spriteFrame) => {
                if (!cc.isValid(item)) return log.i("节点已销毁");
                let node = item.node ? item.node : item;
                if (!cc.isValid(node)) return log.i("节点已销毁");
                let component = node.getComponent(cc.Sprite);
                let { width, height } = spriteFrame._rect;
                component.spriteFrame = spriteFrame;
                resolve({ width, height });
            })
        })
    },
    setNetImg(item, res) {
        return new Promise((resolve, reject) => {
            if (!item) return log.w("图片更换失败,传入了错误的item");
            let node = item.node ? item.node : item;
            if (!res) {
                node.active = false;
                return log.w("图片更换失败,传入了错误的res");
            }
            if (!node) return log.w("图片更换失败,传入了错误的item");
            if (node.net_url == res) return;
            let w = node.width;
            let h = node.height;
            node.active = false;//
            pg.load.loadNetImg(res).then((texture) => {
                if (!cc.isValid(node)) return log.i("节点已销毁");
                let nw = node.width = texture.width;
                let nh = node.height = texture.height;
                let component = node.getComponent(cc.Sprite);
                let spriteFrame = new cc.SpriteFrame(texture);
                component.spriteFrame = spriteFrame;
                node.net_url = res;
                let a = w / nw;//100 2000  0.05
                let b = h / nh;//100 1000  0.1
                if (a < b) {
                    node.width = a * nw;
                    node.height = a * nh;
                } else {
                    node.width = b * nw;
                    node.height = b * nh;
                }
                node.active = true;
                resolve({ w: nw, h: nh });
            })
        })
    },
    visible(item, isVisible) {
        if (!item) return log.w("节点显示失败,传入了错误的item");
        let node = item.node ? item.node : item;
        if (!node || !node.parent) return log.w("节点已移除");
        node.active = isVisible;
        return true;
    },
    setString(item, text, count = 0) {

        if (!item) return log.w("节点text失败,传入了错误的item");
        if (count > 0) {
            function parse_str(str, count) {
                if (!str) return "";
                var segmants = str.split('+');
                str = segmants.join('');
                var len = 0;
                var idx = 0;
                for (var i = 0; i < str.length; i++) {
                    var p = /[^x00-xff]/g;
                    var a = str.charAt(i);
                    if (p.test(a)) {
                        len += 2;
                        idx++;
                    }
                    else {
                        len += 1;
                        idx++;
                    }
                    if (len >= count * 2)
                        break;
                }
                return str.substr(0, idx);
            }
            text = parse_str(text, count);
        }
        let node = item.node ? item.node : item;
        if (!node) return;
        let component = node.getComponent(cc.Label);//组件功能 非node的功能
        component.string = text;
        return true;
    },

    setColor(item, color, outlineWidth = -1) {
        if (!item) return log.w("setColor warn->传入了错误的item");
        let RGB = this.colorRgb(color);
        if (!RGB || RGB.length == 0) return log.w("color ->传入了错误的color");
        item.color = new cc.Color(RGB[0], RGB[1], RGB[2]);
        if (outlineWidth < 0) return;
        let LabelOutline = item.getComponent(cc.LabelOutline);
        if (!LabelOutline) return log.w("LabelOutline warn->未添加描边");
        LabelOutline.width = outlineWidth;
    },
    colorRgb(color) {
        var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
        var sColor = color;
        if (sColor && reg.test(sColor)) {
            if (sColor.length === 4) {
                var sColorNew = "#";
                for (var i = 1; i < 4; i += 1) {
                    sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
                }
                sColor = sColorNew;
            }
            //处理六位的颜色值
            var sColorChange = [];
            for (var i = 1; i < 7; i += 2) {
                sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
            }
            return sColorChange;
        } else {
            return sColor;
        }
    },

    find(item, childPath) {
        if (typeof item == "string") {
            childPath = item;
            item = null;
        }
        if (!childPath || childPath == '' || typeof childPath != 'string') return log.w("findChildByPath error->" + "请传入路径");
        let child = null;
        if (item) {
            let node = item.node ? item.node : item;
            if (!node.children || node.children.length == 0) return log.w("findChild error->" + "找不到此节点，请检查层级路径:" + childPath);
            child = cc.find(childPath, node);
        } else {
            child = cc.find(childPath);
        }
        if (!child) return log.w("findChildByPath error->" + "找不到此节点，请检查层级路径:" + childPath);
        return child;
    },
    addChild(item, child, zIndex) {
        if (!child) return console.log("addChild error ->请传入子节点");
        if (!item) return console.log("addChild error ->请传入父节点");
        let node = item.node ? item.node : item;
        if (!node) return console.log("addChild error ->请传入父节点");
        if (child.parent)
            return log.w("此节点已经有父节点->" + child.name);
        if (zIndex >= 0) {
            node.addChild(child, zIndex)
        } else {
            node.addChild(child);
        }
        return true;
    },
    removeSelf(item) {
        if (!item) return log.w("节点移除失败,传入了错误的item");
        let node = item.node ? item.node : item;
        node.removeFromParent();
        node.destroy();
    },
    removChildren(item) {
        if (!item) return log.w("节点remove失败,传入了错误的item");
        let node = item.node ? item.node : item;
        if (!node.parent) return log.w("节点remove失败,传入了错误的item");
        node.removeAllChildren();
        return true;
    },
    removeChild(item, child) {
        if (!item) return log.w("节点remove失败,传入了错误的item");
        let node = item.node ? item.node : item;
        if (child.parent && child.parent == node) {
            node.removeChild(child);
            node.destroy();
        }
        return true;
    },
    playSpineAnimation(item, aniName, loop) {
        if (!item || !cc.isValid(item)) return log.w("动画播放失败,传入了错误的item");
        if (!aniName) return log.w("动画播放失败,传入了错误的aniName");
        let node = item.node ? item.node : item;
        if (!cc.isValid(node)) return log.w("节点已销毁");
        let skl = node.getComponent(sp.Skeleton);
        skl.setAnimation(0, aniName, loop);
        return skl;
    },
    playDragonBone(item, aniName, loop) {
        if (!item || !cc.isValid(item)) return log.w("动画播放失败,传入了错误的item");
        if (!aniName) return log.w("动画播放失败,传入了错误的aniName");
        let node = item.node ? item.node : item;
        if (!cc.isValid(node)) return log.w("节点已销毁");
        let dba = node.getComponent(dragonBones.ArmatureDisplay);
        dba.playAnimation(aniName, loop);
        return dba;
    },
    cloneNode(node) {
        return cc.instantiate(node);
    }
}
//加载 未封装bundle
pg.load = {
    loadRes: function (res, type, bundleName) {
        // cc.assetManager.loadBundle('hall', (err, bundle) => {
        //     if (err) return cc.error(err);
        //     cc.director.loadScene("hall", () => { });
        // });

        // cc.assetManager.loadBundle('chess', (err, bundle) => {
        //     if (err) return cc.error(err);
        //     cc.director.loadScene("chess", () => {
        //         // //清理hall的资源
        //         // let hallBundle = cc.assetManager.getBundle(`hall`);
        //         // hallBundle.releaseAll();
        //         // cc.assetManager.removeBundle(hallBundle);
        //     });
        // });

        //此处需要二次封装，新的存在assetbundle
        return new Promise((resolve, reject) => {
            cc.loader.loadRes(res, type, (err, data) => {
                if (err && !data) return resolve(pg.logger.d('loading loadRes error-> ', res));
                resolve(data);
            });
        })
    },
    loadImg: function () {
        return new Promise((resolve, reject) => {
            this.loadRes(url, cc.SpriteFrame).then((data) => {
                if (!data || data.length == 0) return;
                resolve(data);
            })
        })
    },
    loadPrefab: function (path = "") {
        return new Promise((resolve, reject) => {
            url = "/prefabs/" + path;
            this.loadRes(url, cc.Prefab).then((data) => {
                if (!data || data.length == 0) return reject();
                return resolve(cc.instantiate(data));
            })
        })
    },
    loadNetImg: function (url) {
        return new Promise((resolve, reject) => {
            cc.loader.load({ url }, (err, texture) => {
                if (err && !data) return resolve(pg.logger.w('loading loadRes warn-> ', res));
                resolve(texture);
            });
        })
    },
}
//本地存储
pg.localStorage = {
    setItem: function (key, val) {
        cc.sys.localStorage.setItem(key, val);
    },
    getItem: function (key, defVal) {
        return cc.sys.localStorage.getItem(key) || defVal;
    }
}
//HTTP网络请求
pg.http = {
    send: function (type = "GET", url, data, callback) {
        let xhr = cc.loader.getXMLHttpRequest();
        xhr.timeout = 5000;
        xhr.responseType = "text";
        xhr.open(type, url, true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = () => {
            if (xhr.readyState !== 4) return;
            if (xhr.status >= 200 && xhr.status < 300) {
                try {
                    let resp = xhr.responseText;
                    pg.logger.d("resp->" + JSON.stringify(resp));
                    callback(resp);
                } catch (e) {
                }
            }
            else {

            }
        };
        xhr.onerror = (e) => {
            pg.logger.w("onerror->" + url);
        };
        xhr.ontimeout = (e) => {
            pg.logger.w("ontimeout->" + url);
        };
        xhr.send(data);

    }
}
/**事件监听部分
 * 
 * 
 * 
 */
class Emitter {

    static instance;
    static getInstance() {
        if (!Emitter.instance) {
            Emitter.instance = new Emitter();
        }
        return Emitter.instance;
    }

    constructor() {
        this._callbacks = {};
        return this;
    }
    on(event, fn) {
        (this._callbacks[event] = this._callbacks[event] || []).push(fn);
    };
    once(event, fn) {
        function on() {
            this.off(event, on);
            fn.apply(this, arguments);
        }
        on.fn = fn;
        this.on(event, on);
    };
    off(event, fn) {
        // all
        if (0 == arguments.length) {
            this._callbacks = {};
            return;
        }

        // specific event
        let callbacks = this._callbacks[event];
        if (!callbacks) return;

        // remove all handlers
        if (1 == arguments.length) {
            delete this._callbacks[event];
            return;
        }

        // remove specific handler
        let cb;
        for (let i = 0; i < callbacks.length; i++) {
            cb = callbacks[i];
            if (cb === fn || cb.fn === fn) {
                callbacks.splice(i, 1);
                break;
            }
        }
        return;
    }
    emit(event, ...args) {
        this._callbacks = this._callbacks || {};
        // let args = [].slice.call(arguments, 1); 
        let callbacks = this._callbacks[event];
        if (callbacks) {
            callbacks = callbacks.slice(0);
            for (let i = 0, len = callbacks.length; i < len; ++i) {
                callbacks[i].apply(this, args);
            }
        }
    }
    listeners(event) {
        this._callbacks = this._callbacks || {};
        return this._callbacks[event] || [];
    };
    hasListeners(event) {
        return !!this.listeners(event).length;
    };

}
class SceneStruct {
    constructor() {
        this.nowScene = "hb_login";
        this.sceneObject = {};
        this.sceneObject[this.nowScene] = [];
    }
    addScene(sceneName) {
        this.nowScene = sceneName;
        //if (!this.sceneObject[this.nowScene])
        this.sceneObject[this.nowScene] = [];
    }
    addLayer(layerName) {

        if (!this.sceneObject[this.nowScene]) return console.log("sceneStruct err->scene未初始化：" + this.nowScene)
        if (!this.sceneObject[this.nowScene].includes(layerName)) {
            this.sceneObject[this.nowScene].push(layerName);
        }
    }
    removeLayer(layerName) {
        if (!this.sceneObject[this.nowScene]) return console.log("sceneStruct err->scene未初始化：" + this.nowScene)
        let arr = this.sceneObject[this.nowScene];
        let isSuccess = false;
        for (let i = arr.length - 1; i >= 0; i--) {
            let laName = arr[i];
            if (layerName == laName) {
                isSuccess = true;
                arr.splice(i, 1);
            }
        }
        if (!isSuccess) {
            console.log("sceneStruct err->scene没有对应layer：" + this.nowScene + ">" + layerName);
        }
    }
    clearLayer() {
        this.sceneObject[this.nowScene] = [];
    }
    getLayers() {
        return this.sceneObject[this.nowScene] || [];
    }
}
class SceneManager {
    static debug = true;

    static instance;
    static getInstance() {
        if (!SceneManager.instance) {
            SceneManager.instance = new SceneManager();
        }
        return SceneManager.instance;
    }
    //py [-zIndex.bottom-]
    //py [-zIndex.login-]
    //py [-zIndex.hall-]
    //py [-zIndex.club-]
    //py [-zIndex.clubPop-]
    //py [-zIndex.game-]
    //py [-zIndex.game_1-]
    //py [-zIndex.game_2-]
    //py [-zIndex.game_3-]
    //py [-zIndex.notice-]
    //py [-zIndex.tip-]
    //py [-zIndex.tips-]
    //py [-zIndex.top-]
    constructor() {
        this.sceneStruct = new SceneStruct();
        //addLayer之前和之后要对scene进行一次对比，如果异常，不进行添加。  继续游戏能看到大厅的bug。
        this.zIndex = {
            bottom: 0,
            login: 1,
            hall: 2,
            game: 5,
            notice: 9,
            tip: 10,
            top: 12,
            webView: 90,//webView 会在最上层，防止出现无法关闭活动界面
        }
    }
    nameScene;
    scene;
    get stage() {
        return cc.find("Canvas");
    }
    get bottom() {
        return cc.find("Canvas/bottom");
    }
    get camera() {
        return cc.find('Canvas/Main Camera')
    }
    beforeLoadScene() {
        let layers = [].concat(this.sceneStruct.getLayers());
        if (!layers || layers.length == 0) return;
        layers.forEach(layerName => {
            this.removeLayer(layerName, true);
        })
    }
    //py [-loadScene(${1:sceneName})-]
    loadScene(sceneName, data, prepareFunc) {
        // pg.loading.releaseAllRes();
        return new Promise((resolve, reject) => {
            if (this.nameScene == sceneName) {
                resolve();
                return console.warn("加载重复的scene->" + sceneName);
            }
            // this.beforeLoadScene();
            setTimeout(() => {
                this.sceneStruct.clearLayer();
                // if (sceneName != "coclub" && sceneName != "cohall_login") {
                //     pg.loading.releaseAddAssetList();
                // }
                // pg.loading.releaseAddAssetList();
                // if (!cc.game.isPaused()) {
                //     cc.game.pause();
                //     cc.loader.releaseAll();
                // }
                prepareFunc && prepareFunc();

                cc.director.loadScene(sceneName, () => {
                    // cc.game.resume();
                    this.beforeLoadScene();//等待加载完成再移除当前场景 3.11 王林
                    this.nameScene = sceneName;
                    this.sceneStruct.addScene(sceneName);
                    event.call(sceneName + "_open", data);
                    resolve();
                });
            }, 0);
        })
    }
    preloadScene(sceneName) {
        // cc.isValid  判断节点是否被销毁。
        return cc.director.preloadScene(sceneName);
    }

    preLoadLayer(layerName) {
        return new Promise((resolve, reject) => {
            loading.loadPrefab(layerName).then(prefab => {
                resolve();
            })
        })
    }
    /*
    !#zh
    添加子层，并且可以修改该层的层级顺序和名字。
    @param layerName 层的预制文件名称（路径在loadPrefab中自动填写）
    @param zIndex 层级|zIndex.bottom /zIndex.login
    @param data layerName_opn|传输得值
    @example 
    ```js
    sceneManager.addLayer('login_layer', 1);
    ``` 
    */
    //py [-addLayer(${1:layerName},${2:pg.scene.zIndex.},${3:data})-]
    addLayer(layerName, zIndex, data, forceRepeat = false, path = "") {
        return new Promise((resolve, reject) => {
            if (!zIndex && zIndex != 0) {
                console.warn("addLayer warn->" + "未添加zIndex:" + layerName);
                zIndex = this.zIndex.top;
            }
            if (!forceRepeat && this.sceneStruct.getLayers().some(ln => { return ln == layerName })) {
                event.call(layerName + "_open_repeat", data);
                return resolve(log.w("addLayer warn->" + "重复添加界面:" + layerName));
            }
            let uuid = this.stage && this.stage.uuid ? this.stage.uuid : 0;
            loading.loadPrefab(layerName, path).then(prefab => {
                if (window.game_center.isLoadingGame || window.game_center.isRunningGame) {//|| !window.isInHall
                    return reject(log.w("dating ..."));
                }
                if (!this.stage) return reject(log.w("addLayer warn->" + "场景已切换：" + layerName));
                if (uuid && uuid != this.stage.uuid) return reject(log.w("addLayer warn->" + "场景已切换：" + layerName));
                if (this.sceneStruct.getLayers().indexOf(layerName) != -1) return resolve(log.w("addLayer warn->" + "多次添加界面:" + layerName));
                if (zIndex == this.zIndex.bottom) {
                    this.bottom && this.bottom.addChild(prefab, zIndex, layerName);
                    // this.sceneStruct.addLayer(layerName);
                } else {
                    this.stage.addChild(prefab, zIndex, layerName);
                }
                event.call(layerName + "_open", data);
                this.sceneStruct.addLayer(layerName);
                resolve(prefab);
            })
        })
    }
    //py [-removeLayer(${1:layerName})-]
    removeLayer(layerName, isRelease = false) {
        // if (layerName == "cohall_WaitLayer") {
        //     console.log("请求移除等待界面");
        // }
        if (!this.stage) return console.log("removeLayer warn->" + "找不到当前stage")
        let node = this.stage.getChildByName(layerName);
        if (!node && this.bottom) node = this.bottom.getChildByName(layerName);
        if (!node) return (layerName != "cohall_WaitLayer" && layerName != "cohall_SceneWaitLayer") && console.log("removeLayer warn->" + "当前stage找不到“" + layerName + "”");
        node.removeFromParent(false);
        node.destroy();
        // if (layerName == "cohall_WaitLayer") {
        //     console.log("等待界面移除成功");
        // }
        this.sceneStruct.removeLayer(layerName);
        if (isRelease) loading.releasePrefab(layerName, isRelease);
    }
    backLayer(layerName, isVisible = false) {
        return new Promise((resolve, reject) => {
            let layer = this.getLayerByName(layerName);
            if (!layer) {
                pg.scene.addLayer(layerName, pg.scene.zIndex.bottom, {}, false, false).then(layer => {
                    layer.active = isVisible;
                    return resolve();
                });
                return;
            }
            layer.parent = this.bottom;
            layer.zIndex = this.zIndex.bottom;
            layer.active = isVisible;
            return resolve();
        })
    }
    frontLayer(layerName) {
        return new Promise((resolve, reject) => {
            let layer = this.getLayerByName(layerName);
            if (!layer) {
                pg.scene.addLayer(layerName, pg.scene.zIndex.hall).then(layer => {
                    layer.active = true;
                    return resolve();

                });
                return;
            } else {
                layer.parent = this.stage;
                layer.zIndex = this.zIndex.hall;
                layer.active = true;
            }
            return resolve();
        })
    }
    //py [-getLayerByName(${1:layerName})-]
    getLayerByName(layerName) {
        let node = this.stage.getChildByName(layerName);
        if (!node) node = this.bottom.getChildByName(layerName);
        return node;
    }
    clearLayer() {
        this.sceneStruct.clearLayer();
    }
    //py [-isHaveLayer(${1:layerName})-]
    isHaveLayer(layerName) {
        return !!this.getLayerByName(layerName);
    }
    getSceneName() {
        return this.nameScene;
    }
}

/**音频播放部分
 * 
 * 
 * 
 */
let KEY_MUSIC_VOL = "music_vol";
let KEY_EFFECT_VOL = "effect_vol";
class AudioUtil {
    static instance;
    static getInstance() {
        if (!AudioUtil.instance) {
            AudioUtil.instance = new AudioUtil();
        }
        return AudioUtil.instance;
    }

    constructor() {
        this.bgm_volume = 1.0;
        this.sfx_volume = 1.0;
        this.sfx_button = "button";
        this.cur_bgm = "";
        this.updateVolume();
        // cc.game.on(cc.game.EVENT_HIDE, function () {
        //     cc.audioEngine.pauseAll();
        // });
        // cc.game.on(cc.game.EVENT_SHOW, function () {
        //     cc.audioEngine.resumeAll();
        // });
    }
    updateVolume() {
        let vvol = cc.sys.localStorage.getItem(KEY_MUSIC_VOL);
        if (vvol != null) {
            this.bgm_volume = parseFloat(vvol);
        }
        let evol = cc.sys.localStorage.getItem(KEY_EFFECT_VOL);
        if (evol != null) {
            this.sfx_volume = parseFloat(evol);
        }
    }

    get_audio_url(url) {
        return url;
    }

    getSfxVolume() {
        return this.sfx_volume;
    }

    getBgmVolume() {
        return this.bgm_volume;
    }

    clickButton() {
        this.playSFX(this.sfx_button);
    }

    playBGM(url, ispath) {
        this.updateVolume();
        let us = url.split("/");
        let len = us.length;
        if (len < 1) return;
        let surl = us[len - 1];
        if (this.cur_bgm == surl) return;
        let audioUrl = ispath ? url : this.get_audio_url(url);
        this.load(audioUrl).then((audio) => {
            if (this.bgm_audio_id >= 0) {
                cc.audioEngine.stop(this.bgm_audio_id);
            }
            this.bgm_audio_id = cc.audioEngine.play(audio, true, this.bgm_volume);
            this.cur_bgm = surl;
        })
    }

    playSFX(url, ispath) {
        return new Promise((resolve, reject) => {
            let audioUrl = ispath ? url : this.get_audio_url(url);
            if (this.sfx_volume > 0) {
                this.load(audioUrl).then((audio) => {
                    let audioId = cc.audioEngine.play(audio, false, this.sfx_volume);
                    cc.audioEngine.setFinishCallback(audioId, () => {
                        resolve(audio);
                    });
                })
            }
        })
    }

    stopAll() {
        cc.audioEngine.stopAll();
        this.bgm_audio_id = -1;
        this.cur_bgm = "";
    }

    setSFXVolume(v) {
        v = Number(v);
        if (this.sfx_volume != v) {
            cc.sys.localStorage.setItem("sfxVolume_hbhall", "" + v);
            this.sfx_volume = v;
        }
    }

    setBGMVolume(v, force) {
        v = Number(v);
        if (this.bgm_audio_id >= 0) {
            if (v > 0) {
                cc.audioEngine.resume(this.bgm_audio_id);
            }
            else {
                cc.audioEngine.pause(this.bgm_audio_id);
            }

            if (this.bgm_volume != v || force) {
                cc.sys.localStorage.setItem("bgmVolume_hbhall", "" + v);
                this.bgm_volume = v;
                cc.audioEngine.setVolume(this.bgm_audio_id, v);
            }
        }
    }

    pauseAll() {
        cc.audioEngine.pauseAll();
    }

    resumeAll() {
        cc.audioEngine.resumeAll();
    }

    load(audioUrl) {
        return new Promise((resolve, reject) => {
            cc.resources.load(audioUrl, cc.AudioClip, (err, audio) => {
                if (err) {
                    return cc.warn("音效加载失败->" + audioUrl);
                }
                if (!audio) return cc.warn("音效加载失败->" + audioUrl);
                resolve(audio);
            });
        })
    }
    playAudioByUrl(audio_url) {
        return new Promise((resolve, reject) => {
            if (!audio_url) return resolve(null);
            cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
                const audioId = cc.audioEngine.play(audioClip, false, 0.8);
                cc.audioEngine.setFinishCallback(audioId, () => {
                    resolve(audioId);
                });
            });
        });
    }
}
pg.event = Emitter.getInstance();
pg.audio = AudioUtil.getInstance();
pg.scene = SceneManager.getInstance();
export default pg;
// window.pg = pg;

//EVENT  CONFIG  DATA NET
//SYSTEM——MANAGER   ---配置文件管理，网络管理，事件管理，数据管理
//VIEW——MANAGER  ---界面管理，网络数据本地同步，界面事件推送
//VIEW  ---界面效果，滚动等等