转载请标明出处: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);
}
};