cocos2d-x 3.1 集成 云风pbc

cocos2d-x 3.1 集成 云风pbc,第1张

概述cocos2d-x 3.x版本变动比较大,从改用cmake管理整个项目,到使用python集成一体化的项目工具。这些都是我喜欢的,我可以很容易的在我的ubuntu上面搭建环境,而且根本就不用考虑IDE的事情,sublime-text or emacs足矣。唯一需要自己动手的就是制作一个比较好的调试工具。我是使用lua+cplusplus开发,所以调试就比较的难受,暂时只能这样,后面考虑自己实现一个

cocos2d-x 3.x版本变动比较大,从改用cmake管理整个项目,到使用python集成一体化的项目工具。这些都是我喜欢的,我可以很容易的在我的ubuntu上面搭建环境,而且根本就不用考虑IDE的事情,sublime-text or emacs足矣。唯一需要自己动手的就是制作一个比较好的调试工具。我是使用lua+cplusplus开发,所以调试就比较的难受,暂时只能这样,后面考虑自己实现一个远程lua调试工具。触控有发布一款IDE,可是目前没有linux平台的版本,我想以后也不会做的,所以就干脆胡忽略了吧。下面就说一下如何在cocos2d-x 3.1里面集成pbc吧。

网上有关于如何在quick-cocos2dx里面集成pbc的,不过quick和cocos2d-x的lua集成方式不一样,而且3.x的版本在安卓平台使用的是luajit,不过在开发者方面还是和lua一样,这只是为了提高效率。可以简单的看一下pbc中的lua binding下面的makefile,也是可以使用luajit的。如果对luajit感兴趣,那么就自己去搜罗吧。网上的这些关于集成pbc的文章,我有粗略的看过一些,结合cocos2d-x 3.x的情况,参考意义并不大,下面我也会给出我自己的做法。

我大三的时候写过一篇关于如何在cocos2d-x中集成luasocket的文章,应该也算是比较早的了。不过,那篇文章的做法,在现在看来的确不是什么好方法,不值得推荐。cocos2dx从2.x的某个版本就添加了自己的lua loader,用来加载lua engine运行的脚本,具体可参考Cocos2dxLuaLoader.cpp/.h文件中的函数。

 1  int cocos2dx_lua_loader(lua_State *L) 2     { 3         std::string filename(luaL_checkstring(L,1)); 4         size_t pos = filename.rfind(".lua"); 5         if (pos != std::string::npos) 6         { 7             filename = filename.substr(0,pos); 8         } 9         10         pos = filename.find_first_of(".");11         while (pos != std::string::npos)12         {13             filename.replace(pos,1,"/");14             pos = filename.find_first_of(".");15         }16         filename.append(".lua");17         18         Data data = fileUtils::getInstance()->getDataFromfile(filename);19         20         if (!data.isNull())21         {22             if (luaL_loadbuffer(L,(char*)data.getBytes(),data.getSize(),filename.c_str()) != 0)23             {24                 luaL_error(L,"error loading module %s from file %s :\n\t%s",25                     lua_tostring(L,1),filename.c_str(),lua_tostring(L,-1));26             }27         }28         else29         {30             log("can not get file data of %s",filename.c_str());31         }32         33         return 1;34     }

如果想要实现对自己项目的lua脚本进行解密或者是解压缩处理,都可以在这里下一点功夫。会有不错的收获,这部分我在后面也会做,不过还在写加密算法中,还要再等等。 - -

也许我这里给出的函数只是个开始,准确的说应该是个错误的开始,不要尝试从这里思考。为什么? 因为cocos2d-x修改了lua的文件加载器。具体的原因是lua在5.1版本以后完善了管理机制,

采用统一的require加载,这也不难在cocos2d-x里面看出来,可以随便看看Lua引擎入口加载执行的函数,如下:(ccluaStack.cpp)

 1 int LuaStack::executeScriptfile(const char* filename) 2 { 3 #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 4     std::string code("require \""); 5     code.append(filename); 6     code.append("\""); 7     return executeString(code.c_str()); 8 #else 9     std::string fullPath = fileUtils::getInstance()->fullPathForfilename(filename);10     ++_callFromLua;11     int nRet = luaL_dofile(_state,fullPath.c_str());12     --_callFromLua;13     CC_ASSERT(_callFromLua >= 0);14     // lua_gc(_state,LUA_GCColLECT,0);15     16     if (nRet != 0)17     {18         cclOG("[LUA ERROR] %s",lua_tostring(_state,-1));19         lua_pop(_state,1);20         return nRet;21     }22     return 0;23 #endif24 }
如果你需要写自己的脚本资源管理模块,那么这里就需要注意了,在android和其他平台处理的时候有明显的不同,不过仅仅是在入口的不同,在后续的require加载中都是一样的,因为在注册

lua loader(也就是上面的cocos2dx_lua_loader)是一样的。 - - 当作一个友善的提示吧。然而lua本身提供的lua loader有四个,用于加载,在Lua源码下的loadlib.c中可以找到:

1 static const lua_CFunction loaders[] =2   {loader_preload,loader_Lua,loader_C,loader_Croot,NULL};

对应luajit中也是可以找到的.源码在luajit源码目录下的lib_package.c中:

1 static const lua_CFunction package_loaders[] =2 {3   lj_cf_package_loader_preload,4   lj_cf_package_loader_lua,5   lj_cf_package_loader_c,6   lj_cf_package_loader_croot,7   NulL8 };
经过cocos2d-x修改loader之后,lua在加载c lib的时候就有问题了,加载不到。不过,还是可以通过修改lua的环境表来做到加载pbc。具体做法如下,修改lua_extension.c:

 1 #include "pbc-master/src/pbc-lua.h" //add 2  3 static luaL_Reg luax_exts[] = { 4     {"socket.core",luaopen_socket_core}, 5     {"mime.core",luaopen_mime_core}, 6     {"protobuf.c",luaopen_protobuf_c},// add 7     {NulL,NulL} 8 }; 9 10 voID luaopen_lua_extensions(lua_State *L)11 {12     // load extensions13     luaL_Reg* lib = luax_exts;14     lua_getglobal(L,"package");15     lua_getfIEld(L,-1,"preload");16     for (; lib->func; lib++)17     {18         lua_pushcfunction(L,lib->func);19         lua_setfIEld(L,-2,lib->name);20     }21     lua_pop(L,2);22 }
将下载的pbc源码(如果是http下载的话那应该是pbc-master,如果是git clone的话那就是pbc)放到coco/lua目录下面去,将binding下面的pbc-lua.c拷贝到src目录下面,将pbc.h也同样拷贝过去,

然后在创建一个pbc-lua.h文件,内容就是luaopen_protobuf_c的函数声明,如下:

 1 #ifndef PBC_LUA_H 2 #define PBC_LUA_H 3  4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7  8 extern int luaopen_protobuf_c(lua_State *L);     9 10 #ifdef __cplusplus    11 }12 #endif13 14 #endif/* PBC_LUA_H */
由于目标平台是安卓,所以下面就去修改ndk的Android.mk文件,目标就是coco/scripting/lua-bindings下面的Android.mk文件: 修改的部分如下:

 1 LOCAL_SRC_fileS := manual/ccluaBrIDge.cpp \ 2           manual/ccluaEngine.cpp \ 3           manual/ccluaStack.cpp \ 4           manual/lua_deBUGger.c \ 5           manual/ccluaValue.cpp \ 6           manual/Cocos2dxLuaLoader.cpp \ 7           manual/CCBProxy.cpp \ 8           manual/Lua_web_socket.cpp \ 9           manual/LuaOpengl.cpp \10           manual/LuaScriptHandlerMgr.cpp \11           manual/LuaBasicConversions.cpp \12           manual/LuaSkeletonAnimation.cpp \13           manual/lua_cocos2dx_manual.cpp \14           manual/lua_cocos2dx_extension_manual.cpp \15           manual/lua_cocos2dx_coco_studio_manual.cpp \16           manual/lua_cocos2dx_ui_manual.cpp \17           manual/lua_cocos2dx_spine_manual.cpp \18           manual/lua_cocos2dx_physics_manual.cpp \19           manual/lua_cocos2dx_deprecated.cpp \20           manual/lua_xml_HTTP_Request.cpp \21           manual/platform/androID/ccluaJavaBrIDge.cpp \22           manual/platform/androID/jni/Java_org_cocos2dx_lib_Cocos2dxLuaJavaBrIDge.cpp \23           manual/tolua_fix.cpp \24           manual/lua_extensions.c \25           auto/lua_cocos2dx_auto.cpp \26           auto/lua_cocos2dx_extension_auto.cpp \27           auto/lua_cocos2dx_studio_auto.cpp \28           auto/lua_cocos2dx_ui_auto.cpp \29           auto/lua_cocos2dx_spine_auto.cpp \30           auto/lua_cocos2dx_physics_auto.cpp \31           ../../../external/lua/tolua/tolua_event.c \32           ../../../external/lua/tolua/tolua_is.c \33           ../../../external/lua/tolua/tolua_map.c \34           ../../../external/lua/tolua/tolua_push.c \35           ../../../external/lua/tolua/tolua_to.c \36           ../../../external/lua/luasocket/auxiliar.c \37           ../../../external/lua/luasocket/buffer.c \38           ../../../external/lua/luasocket/except.c \39           ../../../external/lua/luasocket/inet.c \40           ../../../external/lua/luasocket/io.c \41           ../../../external/lua/luasocket/luasocket.c \42           ../../../external/lua/luasocket/mime.c \43           ../../../external/lua/luasocket/options.c \44           ../../../external/lua/luasocket/select.c \45           ../../../external/lua/luasocket/serial.c \46           ../../../external/lua/luasocket/tcp.c \47           ../../../external/lua/luasocket/timeout.c \48           ../../../external/lua/luasocket/udp.c \49           ../../../external/lua/luasocket/unix.c \50           ../../../external/lua/luasocket/usocket.c \51           ../../../external/lua/pbc-master/src/alloc.c \    -- begin52           ../../../external/lua/pbc-master/src/array.c \53           ../../../external/lua/pbc-master/src/bootstrap.c \54           ../../../external/lua/pbc-master/src/context.c \55           ../../../external/lua/pbc-master/src/decode.c \56           ../../../external/lua/pbc-master/src/map.c \57           ../../../external/lua/pbc-master/src/pattern.c \58           ../../../external/lua/pbc-master/src/proto.c \59           ../../../external/lua/pbc-master/src/register.c \60           ../../../external/lua/pbc-master/src/rmessage.c \61           ../../../external/lua/pbc-master/src/stringpool.c \62           ../../../external/lua/pbc-master/src/varint.c \63           ../../../external/lua/pbc-master/src/wmessage.c \64           ../../../external/lua/pbc-master/src/pbc-lua.c \  -- end
之后就不需要任何的修改了,也不需要在c++代码部分手动去加载pbc的库,因为一切都已经昨晚了。可以很容易的看出来,这种做法的好处。PS:最后别忘记将protobuf.lua拷贝到你的src或者是res下面,都是可以的,这个就不需要解释了。

测试是我将addressbook.pb拷贝到src目录下面,在AppDelegate.cpp中添加了比较简单的拷贝代码,将addressbook.pb拷贝到writablepath,原因就是后面我使用了lua io库去读pb文件,这也是直接参考pbc中的小例子写的,如果有更好的做法请告诉我。谢谢。

1  ssize_t __len = 0;2     auto writablepath = fileUtils::getInstance()->getWritablePath()+"addressbook.pb";3     unsigned char *data = fileUtils::getInstance()->getfileData("assets/src/addressbook.pb","r",&__len);4 5     file *fp = fopen(writablepath.c_str(),"w");6     fwrite(data,sizeof(char),__len,fp);7     fclose(fp);8     delete[] data;9     data = NulL;
下面我给出lua部分的测试代码,实际运行是通过的,我的环境是ubuntu 14.04 x64 + ndk r9 + android

 1     local tf = cc.Label:create() 2         tf:setString(package.loaded) 3  4         local writablepath = cc.fileUtils:getInstance():getWritablePath() 5  6         local addr = io.open(writablepath .. "addressbook.pb","rb") 7         local buffer = addr:read "*a" 8         addr:close() 9         protobuf.register(buffer)10 11         local t = protobuf.decode("Google.protobuf.fileDescriptorSet",buffer)12         local proto = t.file[1]13 14         tf:setString(proto.name .. " " .. proto.package)15 16 17         local addressbook = {18                 name = "Alice",19                 ID = 12345,20                 phone = {21                 { number = "1301234567" },22                 { number = "87654321",type = "WORK" },23             }24         }25 26         local code = protobuf.encode("tutorial.Person",addressbook)27 28         local decode = protobuf.decode("tutorial.Person",code)29 30         tf:setString(decode.name .. " | " .. decode.ID)
我使用fileUtils:getInstance():getfileData无法获取数据,所以也就改为在C++那边拷贝,知道这部分如何使用的可以告诉我,先谢过。

补充:

o.open是lua的原生函数quick里自己封装了一个io.readfile,本质是用io.read实现的为了实现不同系统下文件安放位置的不同需要使用cocos内置函数来获取文件的完全路径名简单范例如下:local DataCsv = io.readfile(cc.fileUtils:getInstance():fullPathForfilename("/Data/Csv/GameAudio.csv"))     



pbc lua binding 文摘:http://blog.csdn.net/kaitiren/article/details/28865725

总结

以上是内存溢出为你收集整理的cocos2d-x 3.1 集成 云风pbc全部内容,希望文章能够帮你解决cocos2d-x 3.1 集成 云风pbc所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1059658.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存