cocos2d-js增加客户端日志显示的需求

转载请标明出处:https://blog.csdn.net/lx_asymmetric/article/details/120270207

前言

  cocos2d-js是一个很方便的游戏引擎,可以让我们实现编写游戏时在浏览器里面进行调试,然后发布到Android和IOS两端。当我们在浏览器里面进行调试时,调试信息可以很容易的在浏览器控制台里面看到。但是当我们将游戏在手机上运行时,如果这个时候出现了一些偶现的问题,然后cocos2d-js本身是无法将Android平台上面的日志输出的,哪怕我们连接了Android Studio并打开了调试模式也无济于事,虽然能在Xcode上面调试的话,但是也不是很方便。而且有的时候,我们调试时,想要动态查询一下我们客户端目前某个数据在cocos虚拟机里面的值,这个需求是无法依靠Ide来完成的。这个时候,我们就会想能不能做一个DebugLayer来显示日志,并且增加一个能够运行一些简单JavaScript代码的输入框

第一步:劫持cocos原生的log输出

 cocos客户端的log输出是在引擎里面的jsb_boot.js不是项目里面的script/jsb_boot.js,项目的是html的log输出)里面进行定义的。文件路径在:

引擎目录/cocos/scripting/js-bindings/script/jsb_boot.js

 我们首先把引擎原来自己的log逻辑给注释掉,使用我们自己的log方法劫持掉引擎的log,warn,error方法,并根据日志的级别定义几个不同的颜色,用于DebugLayer的log信息显示。

/**
 * Init Debug setting.
 * @function
 */
cc._initDebugSetting = function (mode) {
    // var ccGame = cc.game;
    // var bakLog = cc._cocosplayerLog || cc.log || log;
    // cc.log = cc.warn = cc.error = cc.assert = function () {
    // };
    // if (mode == ccGame.DEBUG_MODE_NONE) {
    // } else {
    //     cc.error = function () {
    //         bakLog.call(this, "ERROR :  " + cc.formatStr.apply(cc, arguments));
    //     };
    //     cc.assert = function (cond, msg) {
    //         if (!cond && msg) {
    //             var args = [];
    //             for (var i = 1; i < arguments.length; i++)
    //                 args.push(arguments[i]);
    //             bakLog("Assert: " + cc.formatStr.apply(cc, args));
    //         }
    //     };
    //     if (mode != ccGame.DEBUG_MODE_ERROR && mode != ccGame.DEBUG_MODE_ERROR_FOR_WEB_PAGE) {
    //         cc.warn = function () {
    //             bakLog.call(this, "WARN :  " + cc.formatStr.apply(cc, arguments));
    //         };
    //     }
    //     if (mode == ccGame.DEBUG_MODE_INFO || mode == ccGame.DEBUG_MODE_INFO_FOR_WEB_PAGE) {
    //         cc.log = function () {
    //             bakLog.call(this, cc.formatStr.apply(cc, arguments));
    //         };
    //     }
    // }

    cc.log = Function.prototype.bind.call(cc.AppLog.log, cc);
    cc.assert = function (cond, msg) {
        if (!cond && msg) {
            for (var i = 2; i < arguments.length; i++)
                msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
            throw new Error(msg);
        }
    };
    cc.warn = Function.prototype.bind.call(cc.AppLog.warn, cc);
    cc.error = Function.prototype.bind.call(cc.AppLog.err, cc);

    //因为初始化顺序的原因,这两个参数必须放在这里
    cc.AppLog._evalEditboxSize = cc.size(1000, 50);
    cc.AppLog._evalBtnSize = cc.size(170, 50);
    cc.AppLog._logColor = cc.color(0, 0, 255)
    cc.AppLog._infoColor = cc.color(0, 205, 0)
    cc.AppLog._warnColor = cc.color(238, 119, 0)
    cc.AppLog._errColor = cc.color(255, 0, 0)
    cc.AppLog._evalColor = cc.color(28, 0, 207)
};

实际的方法我们在接下来定义:

cc.AppLog = {
    _logList: new Array(),
    _lastFlag: false,
    _isInited: false,
    
	_getDateString: function () {
        var d = new Date();
        var str = d.getHours();
        var timeStr = "";
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMinutes();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getSeconds();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMilliseconds();
        if (str.length == 1) str = "00" + str;
        if (str.length == 2) str = "0" + str;
        timeStr += str;

        timeStr = "[" + timeStr + "]";
        return timeStr;
    },
    /**
     * index为2的时候,输出为调用函数位置,大于2时,每增加1,输出即向上级调用者回溯一级.当index为-1时,打印全部堆栈
     * @param index
     * @returns {string}
     */
    _stack: function (index) {
        var e = new Error();
        var lines = e.stack.split("\n");
        lines.shift();
        var result = [];
        //获得调用堆栈
        lines.forEach(function (line) {
            line = line.substring(7);
            var lineBreak = line.split(" ");
            if (lineBreak.length < 2) {
                result.push(lineBreak[0]);
            } else {
                result.push([lineBreak[0]] + "|sigma|" + lineBreak[1]);
            }
        });
        //获取调用函数位置
        var fileName;
        var funcName;
        var temp;
        var stackStr = "";
        if (index >= result.length || index == -1) {
            index = result.length - 1;
        }
        for (var i = 2; i <= index; i++) {
            if (i > 2) {
                stackStr += "\n";
            }
            temp = result[i].split("|sigma|");
            if (temp.length > 1) {
                fileName = temp[1].split("/");
                fileName = fileName[fileName.length - 1];
                fileName = fileName.substring(0, fileName.length - 1);
                stackStr += fileName;
            } else {
                stackStr += "来自匿名函数";
            }
            funcName = temp[0].split(".");
            stackStr += " ->" + (funcName.length > 1 ? funcName[1] : funcName[0]);
        }
        stackStr += ": ";

        return stackStr;
    }
};

cc.AppLog.log = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + cc.AppLog._stack(2) + info, cc.AppLog._logColor);
};

cc.AppLog.warn = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + ": " + info, cc.AppLog._warnColor);
};

cc.AppLog.err = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + ": " + info, cc.AppLog._errColor);
};
cc.AppLog.showDebugLayer = function () {
	//判断是否是正式版本的客户端,如果是的话,不进行日志的记录
	//下面这个方法大家可以用自己项目里面的方法来判断
    if (dt.Config.isRelease()) {
        return;
    }

    //当切换到登录界面的时候,清空log信息
    //这个判断大家也可以用自己项目里面的方法来判断,我们这边是在每次进入登陆界面的时候,对保存的数据进行清空
    if (cc.director.getRunningScene()._sceneType == "login" && cc.AppLog._isInited) {
        cc.AppLog._isInited = true;
        cc.AppLog._logList = [];
    }
};

cc.AppLog.addLog = function (msg, color) {
    try {
        cc.AppLog._logList.push({msg:msg,color:color});
        //只保留最近的500条日志,大家可以根据自己的需要进行更改
        if (cc.AppLog._logList.length > 500) {
            cc.AppLog._logList.shift();
        } 
    } catch (e) {
        // console.log(msg);
    }
};

我们还要在应用的最开始进入的scene的onEnter()方法里面调用cc.AppLog.showDebugLayer()来进行DebugLayer的初始化。

if(cc.sys.isNative && cc.AppLog)
	cc.AppLog.showDebugLayer();

第二步:将保存的log数据显示出来,并增加一个能够运行一些简单JavaScript代码的输入框

 在上面我们将获取到的日志信息进行了存储,我们就可以干很多事情了,比如说显示到界面上,或者上传到日志服务器,来对我们线上的客户端情况进行一个监测。不过这里我们首先考虑把日志在界面上显示出来,解决掉我们开发调试的问题。
 需要在调用showDebugLayer时给scene增加一个layer,然后在我们每次调用addLog的时候,将一条日志label添加到layer上显示出来,并且增加一个能够运行一些简单JavaScript代码的输入框。

cc.AppLog = {
    _logList: new Array(),
    //在这里我做了一个js代码输入框,可以用来查询一些变量值,这两个背景值大家可以根据自己的项目替换掉
    _btnBgNormal: "nano/sigma/res/Default/Button_Normal.png",
    _btnBgPress: "nano/sigma/res/Default/Button_Press.png",
    _infosInnerBg: null,
    _infosLeftBg: null,
    _infosRightBg: null,
    _infosScrollView: null,
    _lastFlag: false,
    _isInited: false,
    _setDebugLayerVisible: function (flag) {
        this._infosInnerBg.setVisible(flag);
        this._infosLeftBg.setVisible(flag);
        this._infosRightBg.setVisible(flag);
        this._lastFlag = flag;
    },
    _getDateString: function () {
        var d = new Date();
        var str = d.getHours();
        var timeStr = "";
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMinutes();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getSeconds();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMilliseconds();
        if (str.length == 1) str = "00" + str;
        if (str.length == 2) str = "0" + str;
        timeStr += str;

        timeStr = "[" + timeStr + "]";
        return timeStr;
    },
    /**
     * index为2的时候,输出为调用函数位置,大于2时,每增加1,输出即向上级调用者回溯一级.当index为-1时,打印全部堆栈
     * @param index
     * @returns {string}
     */
    _stack: function (index) {
        var e = new Error();
        var lines = e.stack.split("\n");
        lines.shift();
        var result = [];
        //获得调用堆栈
        lines.forEach(function (line) {
            line = line.substring(7);
            var lineBreak = line.split(" ");
            if (lineBreak.length < 2) {
                result.push(lineBreak[0]);
            } else {
                result.push([lineBreak[0]] + "|sigma|" + lineBreak[1]);
            }
        });
        //获取调用函数位置
        var fileName;
        var funcName;
        var temp;
        var stackStr = "";
        if (index >= result.length || index == -1) {
            index = result.length - 1;
        }
        for (var i = 2; i <= index; i++) {
            if (i > 2) {
                stackStr += "\n";
            }
            temp = result[i].split("|sigma|");
            if (temp.length > 1) {
                fileName = temp[1].split("/");
                fileName = fileName[fileName.length - 1];
                fileName = fileName.substring(0, fileName.length - 1);
                stackStr += fileName;
            } else {
                stackStr += "来自匿名函数";
            }
            funcName = temp[0].split(".");
            stackStr += " ->" + (funcName.length > 1 ? funcName[1] : funcName[0]);
        }
        stackStr += ": ";

        return stackStr;
    },
    _initBg: function (size) {
        this._infosLeftBg = new cc.LayerColor(cc.color(202, 220, 235, 125), 145, 750);
        this._infosLeftBg.setName("infosLeftBg");
        this._infosLeftBg.attr({
            x: -145,
            y: 0
        });
        this._root.addChild(this._infosLeftBg);
        this._infosRightBg = new cc.LayerColor(cc.color(202, 220, 235, 125), 145, 750);
        this._infosRightBg.setName("infosRightBg");
        this._infosRightBg.attr({
            x: size.width,
            y: 0
        });
        this._root.addChild(this._infosRightBg);
        this._infosInnerBg = new cc.LayerColor(cc.color(249, 228, 210, 125), 1334, 750);
        this._infosInnerBg.setName("infosInnerBg");
        this._infosInnerBg.ignoreAnchorPointForPosition(false);
        this._infosInnerBg.attr({
            anchorX: 0.5,
            anchorY: 0.5,
            x: size.width / 2,
            y: size.height / 2
        });
        this._root.addChild(this._infosInnerBg);
    },
    _initMsgScrollView: function () {
        var size = cc.director.getWinSize();

        this._infosScrollView = new ccui.ScrollView();
        this._infosScrollView.retain();
        this._infosScrollView.setDirection(ccui.ScrollView.DIR_VERTICAL);
        this._infosScrollView.setTouchEnabled(true);
        this._infosScrollView.setBounceEnabled(true);
        this._infosScrollView.setSize(cc.size(1200, 650));
        this._infosScrollView.attr({
            anchorX: 0.5,
            anchorY: 0,
            x: size.width / 2,
            y: 100
        });

        this._infosInnerBg.addChild(this._infosScrollView);
    },
    _initLayerSwitch: function () {
        var debugVisual = new ccui.Button();
        debugVisual.setTouchEnabled(true);
        debugVisual.setPressedActionEnabled(true);
        debugVisual.setTitleText("DebugLayer");
        debugVisual.setTitleColor(cc.color(255, 255, 255));
        debugVisual.setTitleFontSize(20);
        debugVisual.attr({
            anchorX: 0,
            anchorY: 0,
            x: 5,
            y: 5
        });
        // dt.ButtomLimit.ClickEffect(debugVisual);
        debugVisual.addClickEventListener(function () {
            if (cc.AppLog._infosInnerBg.isVisible()) {
                cc.AppLog._setDebugLayerVisible(false);
            } else {
                cc.AppLog._setDebugLayerVisible(true);
            }
        });
        this._root.addChild(debugVisual, 1099);
    },
    _initEvalFeatures: function () {
        var sp = new cc.Scale9Sprite(this._btnBgNormal);
        sp.setCapInsets(cc.rect(10, 10, 10, 10));
        var ebEval = new cc.EditBox(this._evalEditboxSize, sp);
        ebEval.setPlaceHolder("请输入");
        ebEval.setPlaceholderFontSize(32);
        ebEval.setFont("Marker Felt", 30);
        ebEval.attr({
            anchorX: 0,
            anchorY: 0,
            x: 67,
            y: 30
        });
        ebEval.setPlaceholderFontColor(cc.color.BLACK);
        ebEval.setFontColor(cc.color.BLACK);
        this._infosInnerBg.addChild(ebEval);

        var btn = new ccui.Button();
        btn.setTitleText("运行");
        btn.setTitleColor(cc.color(0, 0, 0));
        btn.setTitleFontSize(32);
        btn.setTouchEnabled(true);
        btn.setPressedActionEnabled(true);
        btn.loadTextures(this._btnBgNormal, this._btnBgPress);
        btn.setScale9Enabled(true);
        //设置9宫格的边角参数
        btn.setCapInsets(cc.rect(10, 10, 10, 10));
        btn.attr({
            anchorX: 0,
            anchorY: 0,
            x: 1097,
            y: 30
        });
        btn.ignoreContentAdaptWithSize(false);
        btn.setContentSize(this._evalBtnSize);
        // dt.ButtomLimit.ClickEffect(btn);
        btn.addClickEventListener(function () {
            var result;
            var evalStr = ebEval.getString();
            if (evalStr == "clc") {
                for (var j = 0; j < cc.AppLog._logList.length; j++) {
                    var logLabel = cc.AppLog._logList[j];
                    logLabel.removeFromParent(true);
                }
                cc.AppLog._logList = [];
                ebEval.setString("");
                return;
            }
            try {
                result = eval(evalStr);
            } catch (syntaxError) {
                result = "语法错误!!!";
            }
            if (result == undefined) {
                result = "运行成功!";
            } else if (result.toString().indexOf("[object") != -1) {
                try {
                    var description = "";
                    for (var i in result) {
                        description += "\"" + i + "\"" + " = " + result[i] + ",";
                    }
                    result = description;
                } catch (objectIsNull) {
                    result = "无法输出空对象!!!";
                }
            }
            ebEval.setString("");
            cc.AppLog.addLog(cc.AppLog._getDateString() + evalStr + " 运行结果为 " + result, cc.AppLog._evalColor);
        });
        this._infosInnerBg.addChild(btn);
    }
};
cc.AppLog.showDebugLayer = function () {
    if (dt.Config.isRelease()) {
        return;
    }

    //当切换到登录界面的时候,清空log信息
    if (cc.director.getRunningScene()._sceneType == "login" && cc.AppLog._isInited) {
        cc.AppLog._isInited = true;
        cc.AppLog._logList = [];
    }
    if (cc.AppLog._infosScrollView != null) {
        cc.AppLog._infosScrollView.release();
    }

    var size = cc.director.getWinSize();
    cc.AppLog._root = new cc.Node();
    cc.AppLog._root.setName("DebugLayer");

    cc.AppLog._initBg(size);
    cc.AppLog._initMsgScrollView();
    cc.AppLog._initEvalFeatures();
    cc.AppLog._initLayerSwitch();

    //在切换场景后,重新绘制log信息
    for (var i = 0; i < cc.AppLog._logList.length; i++) {
        var logLabel = cc.AppLog._logList[i];
        logLabel.removeFromParent(true);
        cc.AppLog._infosScrollView.addChild(logLabel);
    }
    if (cc.AppLog._logList.length > 0) {
        var innerHight = cc.AppLog._logList[0].getPositionY() + cc.AppLog._logList[0].height + 8;
        cc.AppLog._infosScrollView.setInnerContainerSize(cc.size(1200, innerHight));
        cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, 0));
    }
    cc.AppLog._setDebugLayerVisible(cc.AppLog._lastFlag);
    cc.director.getRunningScene().addChild(cc.AppLog._root, 5, 10099);
};

cc.AppLog.addLog = function (msg, color) {
    try {
        var msgLabel = new cc.LabelTTF(msg, "", 25);
        msgLabel.retain();
        msgLabel.setName("msgLabel");
        msgLabel.setDimensions(1200, 0);
        msgLabel.attr({
            anchorX: 0,
            anchorY: 0,
            x: 0,
            y: 0
        });
        msgLabel.setColor(color);

        var logLabel;
        for (var i = 0; i < cc.AppLog._logList.length; i++) {
            logLabel = cc.AppLog._logList[i];
            logLabel.setPositionY(logLabel.getPositionY() + msgLabel.height + 4);
        }
        cc.AppLog._logList.push(msgLabel);
        if (cc.AppLog._logList.length > 500) {
            var deleteObj = cc.AppLog._logList.shift();
            deleteObj.removeFromParent(true);
            deleteObj.release()//每次都会删除最顶层的,也就是第一个元素
        }

        var oldPos = cc.AppLog._infosScrollView.getInnerContainerPosition().y;
        var newPos = oldPos - msgLabel.height - 4;
        var innerHight = cc.AppLog._logList[0].getPositionY() + cc.AppLog._logList[0].height + 8;
        cc.AppLog._infosScrollView.setInnerContainerSize(cc.size(1200, innerHight));
        // cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, 0));
        cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, newPos));
    } catch (e) {
        // console.log(msg);
    }
    if (cc.AppLog._infosScrollView != null) {
        cc.AppLog._infosScrollView.addChild(msgLabel);
    }
};

这样就大工告成了。

最终代码:

一定要记得在游戏最开始进入的scene的onEnter()方法里面调用cc.AppLog.showDebugLayer()来进行DebugLayer的初始化。

if(cc.sys.isNative && cc.AppLog)
	cc.AppLog.showDebugLayer();

jsb_boot.js代码修改如下:

/**
 * Init Debug setting.
 * @function
 */
cc._initDebugSetting = function (mode) {
    // var ccGame = cc.game;
    // var bakLog = cc._cocosplayerLog || cc.log || log;
    // cc.log = cc.warn = cc.error = cc.assert = function () {
    // };
    // if (mode == ccGame.DEBUG_MODE_NONE) {
    // } else {
    //     cc.error = function () {
    //         bakLog.call(this, "ERROR :  " + cc.formatStr.apply(cc, arguments));
    //     };
    //     cc.assert = function (cond, msg) {
    //         if (!cond && msg) {
    //             var args = [];
    //             for (var i = 1; i < arguments.length; i++)
    //                 args.push(arguments[i]);
    //             bakLog("Assert: " + cc.formatStr.apply(cc, args));
    //         }
    //     };
    //     if (mode != ccGame.DEBUG_MODE_ERROR && mode != ccGame.DEBUG_MODE_ERROR_FOR_WEB_PAGE) {
    //         cc.warn = function () {
    //             bakLog.call(this, "WARN :  " + cc.formatStr.apply(cc, arguments));
    //         };
    //     }
    //     if (mode == ccGame.DEBUG_MODE_INFO || mode == ccGame.DEBUG_MODE_INFO_FOR_WEB_PAGE) {
    //         cc.log = function () {
    //             bakLog.call(this, cc.formatStr.apply(cc, arguments));
    //         };
    //     }
    // }
    cc.log = Function.prototype.bind.call(cc.AppLog.log, cc);
    cc.assert = function (cond, msg) {
        if (!cond && msg) {
            for (var i = 2; i < arguments.length; i++)
                msg = msg.replace(/(%s)|(%d)/, cc._formatString(arguments[i]));
            throw new Error(msg);
        }
    };
    cc.warn = Function.prototype.bind.call(cc.AppLog.warn, cc);
    cc.error = Function.prototype.bind.call(cc.AppLog.err, cc);

    //因为初始化顺序的原因,这两个参数必须放在这里
    cc.AppLog._evalEditboxSize = cc.size(1000, 50);
    cc.AppLog._evalBtnSize = cc.size(170, 50);
    cc.AppLog._logColor = cc.color(0, 0, 255)
    cc.AppLog._infoColor = cc.color(0, 205, 0)
    cc.AppLog._warnColor = cc.color(238, 119, 0)
    cc.AppLog._errColor = cc.color(255, 0, 0)
    cc.AppLog._evalColor = cc.color(28, 0, 207)
};
//+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
/**
 * sigma框架的日志部分
 * @author JiangXian
 * @time 2018/04/03
 */
cc.AppLog = {
    _logList: new Array(),
    _btnBgNormal: "nano/sigma/res/Default/Button_Normal.png",
    _btnBgPress: "nano/sigma/res/Default/Button_Press.png",
    _infosInnerBg: null,
    _infosLeftBg: null,
    _infosRightBg: null,
    _infosScrollView: null,
    _lastFlag: false,
    _isInited: false,
    _setDebugLayerVisible: function (flag) {
        this._infosInnerBg.setVisible(flag);
        this._infosLeftBg.setVisible(flag);
        this._infosRightBg.setVisible(flag);
        this._lastFlag = flag;
    },
    _getDateString: function () {
        var d = new Date();
        var str = d.getHours();
        var timeStr = "";
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMinutes();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getSeconds();
        timeStr += (str.length == 1 ? "0" + str : str) + ":";
        str = d.getMilliseconds();
        if (str.length == 1) str = "00" + str;
        if (str.length == 2) str = "0" + str;
        timeStr += str;

        timeStr = "[" + timeStr + "]";
        return timeStr;
    },
    /**
     * index为2的时候,输出为调用函数位置,大于2时,每增加1,输出即向上级调用者回溯一级.当index为-1时,打印全部堆栈
     * @param index
     * @returns {string}
     */
    _stack: function (index) {
        var e = new Error();
        var lines = e.stack.split("\n");
        lines.shift();
        var result = [];
        //获得调用堆栈
        lines.forEach(function (line) {
            line = line.substring(7);
            var lineBreak = line.split(" ");
            if (lineBreak.length < 2) {
                result.push(lineBreak[0]);
            } else {
                result.push([lineBreak[0]] + "|sigma|" + lineBreak[1]);
            }
        });
        //获取调用函数位置
        var fileName;
        var funcName;
        var temp;
        var stackStr = "";
        if (index >= result.length || index == -1) {
            index = result.length - 1;
        }
        for (var i = 2; i <= index; i++) {
            if (i > 2) {
                stackStr += "\n";
            }
            temp = result[i].split("|sigma|");
            if (temp.length > 1) {
                fileName = temp[1].split("/");
                fileName = fileName[fileName.length - 1];
                fileName = fileName.substring(0, fileName.length - 1);
                stackStr += fileName;
            } else {
                stackStr += "来自匿名函数";
            }
            funcName = temp[0].split(".");
            stackStr += " ->" + (funcName.length > 1 ? funcName[1] : funcName[0]);
        }
        stackStr += ": ";

        return stackStr;
    },
    _initBg: function (size) {
        this._infosLeftBg = new cc.LayerColor(cc.color(202, 220, 235, 125), 145, 750);
        this._infosLeftBg.setName("infosLeftBg");
        this._infosLeftBg.attr({
            x: -145,
            y: 0
        });
        this._root.addChild(this._infosLeftBg);
        this._infosRightBg = new cc.LayerColor(cc.color(202, 220, 235, 125), 145, 750);
        this._infosRightBg.setName("infosRightBg");
        this._infosRightBg.attr({
            x: size.width,
            y: 0
        });
        this._root.addChild(this._infosRightBg);
        this._infosInnerBg = new cc.LayerColor(cc.color(249, 228, 210, 125), 1334, 750);
        this._infosInnerBg.setName("infosInnerBg");
        this._infosInnerBg.ignoreAnchorPointForPosition(false);
        this._infosInnerBg.attr({
            anchorX: 0.5,
            anchorY: 0.5,
            x: size.width / 2,
            y: size.height / 2
        });
        this._root.addChild(this._infosInnerBg);
    },
    _initMsgScrollView: function () {
        var size = cc.director.getWinSize();

        this._infosScrollView = new ccui.ScrollView();
        this._infosScrollView.retain();
        this._infosScrollView.setDirection(ccui.ScrollView.DIR_VERTICAL);
        this._infosScrollView.setTouchEnabled(true);
        this._infosScrollView.setBounceEnabled(true);
        this._infosScrollView.setSize(cc.size(1200, 650));
        this._infosScrollView.attr({
            anchorX: 0.5,
            anchorY: 0,
            x: size.width / 2,
            y: 100
        });

        this._infosInnerBg.addChild(this._infosScrollView);
    },
    _initLayerSwitch: function () {
        var debugVisual = new ccui.Button();
        debugVisual.setTouchEnabled(true);
        debugVisual.setPressedActionEnabled(true);
        debugVisual.setTitleText("DebugLayer");
        debugVisual.setTitleColor(cc.color(255, 255, 255));
        debugVisual.setTitleFontSize(20);
        debugVisual.attr({
            anchorX: 0,
            anchorY: 0,
            x: 5,
            y: 5
        });
        // dt.ButtomLimit.ClickEffect(debugVisual);
        debugVisual.addClickEventListener(function () {
            if (cc.AppLog._infosInnerBg.isVisible()) {
                cc.AppLog._setDebugLayerVisible(false);
            } else {
                cc.AppLog._setDebugLayerVisible(true);
            }
        });
        this._root.addChild(debugVisual, 1099);
    },
    _initEvalFeatures: function () {
        var sp = new cc.Scale9Sprite(this._btnBgNormal);
        sp.setCapInsets(cc.rect(10, 10, 10, 10));
        var ebEval = new cc.EditBox(this._evalEditboxSize, sp);
        ebEval.setPlaceHolder("请输入");
        ebEval.setPlaceholderFontSize(32);
        ebEval.setFont("Marker Felt", 30);
        ebEval.attr({
            anchorX: 0,
            anchorY: 0,
            x: 67,
            y: 30
        });
        ebEval.setPlaceholderFontColor(cc.color.BLACK);
        ebEval.setFontColor(cc.color.BLACK);
        this._infosInnerBg.addChild(ebEval);

        var btn = new ccui.Button();
        btn.setTitleText("运行");
        btn.setTitleColor(cc.color(0, 0, 0));
        btn.setTitleFontSize(32);
        btn.setTouchEnabled(true);
        btn.setPressedActionEnabled(true);
        btn.loadTextures(this._btnBgNormal, this._btnBgPress);
        btn.setScale9Enabled(true);
        //设置9宫格的边角参数
        btn.setCapInsets(cc.rect(10, 10, 10, 10));
        btn.attr({
            anchorX: 0,
            anchorY: 0,
            x: 1097,
            y: 30
        });
        btn.ignoreContentAdaptWithSize(false);
        btn.setContentSize(this._evalBtnSize);
        // dt.ButtomLimit.ClickEffect(btn);
        btn.addClickEventListener(function () {
            var result;
            var evalStr = ebEval.getString();
            if (evalStr == "clc") {
                for (var j = 0; j < cc.AppLog._logList.length; j++) {
                    var logLabel = cc.AppLog._logList[j];
                    logLabel.removeFromParent(true);
                }
                cc.AppLog._logList = [];
                ebEval.setString("");
                return;
            }
            try {
                result = eval(evalStr);
            } catch (syntaxError) {
                result = "语法错误!!!";
            }
            if (result == undefined) {
                result = "运行成功!";
            } else if (result.toString().indexOf("[object") != -1) {
                try {
                    var description = "";
                    for (var i in result) {
                        description += "\"" + i + "\"" + " = " + result[i] + ",";
                    }
                    result = description;
                } catch (objectIsNull) {
                    result = "无法输出空对象!!!";
                }
            }
            ebEval.setString("");
            cc.AppLog.addLog(cc.AppLog._getDateString() + evalStr + " 运行结果为 " + result, cc.AppLog._evalColor);
        });
        this._infosInnerBg.addChild(btn);
    }
};

cc.AppLog.log = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + cc.AppLog._stack(2) + info, cc.AppLog._logColor);
};

cc.AppLog.warn = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + ": " + info, cc.AppLog._warnColor);
};

cc.AppLog.err = function () {
    var info = cc.formatStr.apply(cc, arguments);
    if (info == "[object Object]") {
        info = JSON.stringify(info);
    }
    cc.AppLog.addLog(cc.AppLog._getDateString() + ": " + info, cc.AppLog._errColor);
};
cc.AppLog.showDebugLayer = function () {
    if (dt.Config.isRelease()) {
        return;
    }

    //当切换到登录界面的时候,清空log信息
    if (cc.director.getRunningScene()._sceneType == "login" && cc.AppLog._isInited) {
        cc.AppLog._isInited = true;
        cc.AppLog._logList = [];
    }
    if (cc.AppLog._infosScrollView != null) {
        cc.AppLog._infosScrollView.release();
    }

    var size = cc.director.getWinSize();
    cc.AppLog._root = new cc.Node();
    cc.AppLog._root.setName("DebugLayer");

    cc.AppLog._initBg(size);
    cc.AppLog._initMsgScrollView();
    cc.AppLog._initEvalFeatures();
    cc.AppLog._initLayerSwitch();

    //在切换场景后,重新绘制log信息
    for (var i = 0; i < cc.AppLog._logList.length; i++) {
        var logLabel = cc.AppLog._logList[i];
        logLabel.removeFromParent(true);
        cc.AppLog._infosScrollView.addChild(logLabel);
    }
    if (cc.AppLog._logList.length > 0) {
        var innerHight = cc.AppLog._logList[0].getPositionY() + cc.AppLog._logList[0].height + 8;
        cc.AppLog._infosScrollView.setInnerContainerSize(cc.size(1200, innerHight));
        cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, 0));
    }
    cc.AppLog._setDebugLayerVisible(cc.AppLog._lastFlag);
    cc.director.getRunningScene().addChild(cc.AppLog._root, 5, 10099);
};

cc.AppLog.addLog = function (msg, color) {
    try {
        var msgLabel = new cc.LabelTTF(msg, "", 25);
        msgLabel.retain();
        msgLabel.setName("msgLabel");
        msgLabel.setDimensions(1200, 0);
        msgLabel.attr({
            anchorX: 0,
            anchorY: 0,
            x: 0,
            y: 0
        });
        msgLabel.setColor(color);

        var logLabel;
        for (var i = 0; i < cc.AppLog._logList.length; i++) {
            logLabel = cc.AppLog._logList[i];
            logLabel.setPositionY(logLabel.getPositionY() + msgLabel.height + 4);
        }
        cc.AppLog._logList.push(msgLabel);
        if (cc.AppLog._logList.length > 500) {
            var deleteObj = cc.AppLog._logList.shift();
            deleteObj.removeFromParent(true);
            deleteObj.release()//每次都会删除最顶层的,也就是第一个元素
        }

        var oldPos = cc.AppLog._infosScrollView.getInnerContainerPosition().y;
        var newPos = oldPos - msgLabel.height - 4;
        var innerHight = cc.AppLog._logList[0].getPositionY() + cc.AppLog._logList[0].height + 8;
        cc.AppLog._infosScrollView.setInnerContainerSize(cc.size(1200, innerHight));
        // cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, 0));
        cc.AppLog._infosScrollView.setInnerContainerPosition(cc.p(0, newPos));
    } catch (e) {
        // console.log(msg);
    }
    if (cc.AppLog._infosScrollView != null) {
        cc.AppLog._infosScrollView.addChild(msgLabel);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值