用腳本進行開發,若是不能實時去輸入指令,就喪失了腳本的一大特點,因此對cocos2d-x程序稍微修改下,使其能夠直接從控制檯讀入lua指令,方便調試。html
1 首先在行首加入lua的引用,以下windows
1 #include "main.h" 2 #include "AppDelegate.h" 3 #include "cocos2d.h" 4 #include <assert.h> 5 #include <windows.h> 6 #include <sys/stat.h> 7 #include "CCLuaEngine.h"
2 在main函數前面插入如下代碼app
1 #ifdef USE_WIN32_CONSOLE 2 BOOL g_bAppRun = FALSE; 3 char g_szBuffer[1024]; 4 char g_szBuffer_copy[1024]; 5 DWORD WINAPI ThreadReadConsole(LPVOID lpParam) 6 { 7 HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); 8 while(g_bAppRun) 9 { 10 DWORD dwNum = 0; 11 ReadConsoleA(hConsole, g_szBuffer, 1023, &dwNum, NULL); 12 if (dwNum) 13 { 14 g_szBuffer[dwNum] = '\0'; 15 memcpy(g_szBuffer_copy, g_szBuffer, dwNum + 1); 16 } 17 } 18 return 0; 19 } 20 21 int FetchConsoleCmd(lua_State* L) 22 { 23 if ('\0' == g_szBuffer_copy[0]) 24 { 25 return 0; 26 } 27 lua_pushstring(L, g_szBuffer_copy); 28 g_szBuffer_copy[0] = '\0'; 29 return 1; 30 } 31 #endif
3 在main函數裏修改以下ide
1 #ifdef USE_WIN32_CONSOLE 2 AllocConsole(); 3 freopen("CONIN$", "r", stdin); 4 freopen("CONOUT$", "w", stdout); 5 freopen("CONOUT$", "w", stderr); 6 7 g_bAppRun = TRUE; 8 CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadReadConsole,NULL,0,NULL); 9 #endif 10 11 // create the application instance 12 AppDelegate app; 13 lua_State* L = LuaEngine::getInstance()->getLuaStack()->getLuaState(); 14 lua_register(L, "FetchConsoleCmd", FetchConsoleCmd); 15 int ret = Application::getInstance()->run(); 16 17 #ifdef USE_WIN32_CONSOLE 18 FreeConsole(); 19 g_bAppRun = FALSE; 20 #endif
4 添加lua循環函數
這裏使用計時器,其實能夠在主循環中添加操做ui
1 cc.Director:getInstance():getScheduler():scheduleScriptFunc(function() 2 if FetchConsoleCmd then 3 local string = FetchConsoleCmd() 4 if string then 5 local cmd = loadstring(string) 6 if cmd then 7 xpcall(cmd, __G__TRACKBACK__) 8 end 9 end 10 end 11 end, 0, false)
5 改編碼
1 local printByte = 36 -- "$"號的內部數字編碼 2 local debug_console = setmetatable({}, {__index = _G}) 3 4 -- 對輸入的字符串進行操做(可自行擴展) 5 function debug_console:runConsloe() 6 if FetchConsoleCmd then 7 self.str = FetchConsoleCmd() 8 self.isPrint = false 9 if self.str then 10 -- 重載 $ 符號的字符串操做 11 if string.byte(self.str, 1) == printByte then 12 self.str = string.sub(self.str, 2) 13 self.str = "return " .. self.str 14 self.isPrint = true 15 end 16 17 local cmd = loadstring(self.str) 18 if cmd then 19 -- 設置函數執行環境 20 local msg = setfenv(cmd, debug_console)() 21 if self.isPrint then 22 print(dump(msg)) 23 end 24 end 25 end 26 end 27 end 28 29 -- 更新文件 30 function debug_console.updateFile(filePath) 31 local pos = string.find(filePath,"[^%/.]*$"); 32 local module_name = string.sub(filePath, pos); 33 34 local mod = package.loaded[module_name]; 35 if not mod then 36 mod = package.loaded[module_name.."_manager"]; 37 end 38 39 package.loaded[filePath] = false; 40 local ret = require(filePath); 41 42 mod = package.loaded[module_name]; 43 if not mod then 44 mod = package.loaded[module_name.."_manager"]; 45 end 46 47 return ret; 48 end 49 50 return debug_console
這樣一來,配合一些全局函數,能夠在遊戲開發時對遊戲實現簡單的指令調試,大大節省遊戲開發時間,特別是對於我這些初學者來講,每次一個bug要去找很久,甚至在每行都加入print函數去查找問題出在哪。lua
可是這樣的弊端在於取不到包中定義的局部變量,具體的實現須要利用lua debug庫中的debug.getupvalue()和debug.setupvalue()來實現,因爲技術有限,自己對於lua 的debug庫掌握的不是不少,並且感受這個樣子已經spa
足夠開發使用,就沒有深刻去研究。debug
若是之後有機會的話我回去完善這個東西