关于cocos2dx程序的BUG调试解决方案

      今天说一下手机游戏开发的调试问题吧。不得不说的是和PC平台游戏、软件开发相比,手机上开发游戏和软件要困难的多。原因是多方面的,比如说开发环境比较复杂,工具软件不够人性化等等。

      cocos2dx的出现解决了一个很大的问题,因为他是跨平台的,相对来说windows的软件开发环境比较友好,对中国程序员来说更熟悉。这样可以在windows进行日常开发和调试,然后在发布到其它平台的时候进行少量的处理就好了。

      cocos2dx程序的调试,在windows下和端游类似,可以在后台窗口进行打印,也可以直接在vs中挂断点进行跟踪。相对还是比较容易。唯一需要优化的是把后台打印日志导出,以方便根据日志进行分析。

      但是在windows环境OK之后,需要发布到Android平台的时候,就有些麻烦了,顺利运行还好,一旦在运行的过程中出现问题,那再来调试就相当的麻烦了,模拟器满如蜗牛,Esclipe本身支持也不够强大。有时候可能只是一句脚本报错,但是要发现问题缺要费九牛二虎之力。要是在真机上运行出错,那就更加不好跟踪问题了,还需要用到USB调试功能。今天的主要话题就是针对这种情况,提供几个好的方法来方便我们进行游戏开发。

      1、后台打印日志的优化。

      windows下已经有后台日志查看功能,但是大家可能会发现一个问题,后台显示有行数的限制,超过多少行之后就看不到了,但是cocos2dx的输出是相当多的。怎么办?解决方案就是输出log文件。把后台显示的内容输出后,我们可以直接分析log文件。下面提供lua的解决代码,用C++的同学可以自己改造。

      首先,封装一下lua的文件处理功能,比较简单,而且后面的方法可能也需要使用。

--file.lua
--定义lua文件操作的方法
--打开文件:参数(文件名,打开模式),返回文件句柄或nil
function openFile(filename, mode)
	local f = io.open(filename,mode)
	if f then
		return f
	else
		return nil
	end
end
--读取文件全部内容:参数(文件句柄),返回一个string
function readAllFile(f)
	return f:read("*all")
end

--读取文件一行内容:参数(文件句柄),返回一个string
function readLineFile(f)
	return f:read("*line")
end
--写文件内容:参数(文件句柄,字符串)
function writeFile(f, ...)
	local arg = {...}
	f:write(unpack(arg))
end
--关闭文件,参数(文件句柄()
function closeFile(f)
	f:close()
end
      然后,我们要改写print函数和cclog函数,将这些内容输出到文件。

local print_raw = print
-- print
print = function(...)
    require "base.file"
    print_raw(string.format(...))
    local file = openFile("client.log", "a")
    if file then
	writeFile(file, string.format(...).."\n")
	closeFile(file)
    end
end
-- cclog
cclog = function(...)
    print(string.format(...))
end
-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(msg) .. "\n")
    print(debug.traceback())
    print("----------------------------------------")
end
      这样,所有在lua里面的打印信息都会输出到日志文件方便我们分析了。

      2、上面这个方法已经能够让我们分享日志,那还有没有更好的方法呢?如果我是在安卓手机上运行,我要查看日志是不是很不方便呢?

       那我们就更进一步,我们不是把日志输出到文件了吗?那我们直接在游戏里面查看日志不是更方便?所以我们的思路是,在游戏中写一个日志显示界面,然后把日志文件内容一行一行读出来,让他显示在一个RichText控件里面。这样是不是更方便呢?这个方法我暂时没时间写,不过肯定没问题的,有时间写好后补上代码。

      3、方法2已经能够及时的看到日志了,我们还可以使用更强大一点的方法,我们可以建一个日志服务器,客户端在输出日志的时候就发送到日志服务器,这样真机测试就很方便了,和在windows开发很相似了,不过这个方案有点重了,大家使用第二点应该就可以了。
      好了,上面推荐的这三种方案应该能够解决大部分的调试问题了,再也不用为了看日志去启动麻烦的模拟器了。

      一直没时间,今天才抽出时间来完善这个功能并将之加入到开发过程中。实现核心代码如下:      

    --日志控件
    self._richText = ui.RichTextUI:create()
    self._richText:setSize(cc.size(winSize.width - 60, winSize.height - 110))
    self._richText:setAnchorPoint(cc.p(0, 0))
    self._richText:setPosition(cc.p(30, 30))
    self._widget:addChild(self._richText)
    local fHandle = openFile("client.log", "rb")
    if fHandle then
        local idx = 0
        local lineStr = readLineFile(fHandle)
        while lineStr do
            if idx >= self._index then
                local elem = ui.RichItemText:create(0, Color3B.WHITE, 255, strg2u(lineStr), DEFAULT_FONT_TTF, 20) 
                self._richText:insertElement(elem)
                self._richText:insertNewLine()
            end
            idx = idx + 1
            lineStr = readLineFile(fHandle)
        end
        self._index = idx
    end
      下面看看实际的效果吧,对于真机测试来说,这个效果是不是已经很好了呢?

       

      转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章