關於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)

      

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