cocos2d-lua 控制台输入Lua指令方便调试

用脚本进行开发,如果不能实时去输入指令,就丧失了脚本的一大特色,所以对cocos2d-x程序稍微修改下,使其可以直接从控制台读入lua指令,方便调试。

1 首先在行首加入lua的引用,如下

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函数前面插入以下代码

 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] = '';
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 ('' == g_szBuffer_copy[0])
24     {
25         return 0;
26     }
27     lua_pushstring(L, g_szBuffer_copy);
28     g_szBuffer_copy[0] = '';
29     return 1;
30 }
31 #endif
main函数前插入代码

3 在main函数里修改如下

 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
修改main函数

4 添加lua循环

这里使用计时器,其实可以在主循环中添加操作

 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
改写lua函数

这样一来,配合一些全局函数,可以在游戏开发时对游戏实现简单的指令调试,大大节省游戏开发时间,特别是对于我这些初学者来说,每次一个bug要去找好久,甚至在每行都加入print函数去查找问题出在哪。

但是这样的弊端在于取不到包中定义的局部变量,具体的实现需要利用lua debug库中的debug.getupvalue()和debug.setupvalue()来实现,由于技术有限,本身对于lua 的debug库掌握的不是很多,而且感觉这个样子已经

足够开发使用,就没有深入去研究。

如果以后有机会的话我回去完善这个东西

其中大部分的实现是参照http://yestein.com/2014/09/24/%E3%80%90cocos2d-x%E3%80%91%E6%8E%A7%E5%88%B6%E5%8F%B0%E7%9B%B4%E6%8E%A5%E8%BE%93%E5%85%A5lua%E6%8C%87%E4%BB%A4%E6%94%B9%E8%BF%9B%E7%89%88/中实现的

原文地址:https://www.cnblogs.com/kpxy/p/11202287.html