Cocos2d-x 3.1 Lua Binding

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.1 Lua Binding前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://my.oschina.net/skyhacker2/blog/298397



摘要 Cocos2d-x 3.1 Lua 绑定

Cocos2d-x 3.1 Lua Binding

参考:http://www.cocos2d-x.org/docs/manual/code-ide/binding-custom-class-to-lua/en

添加需要绑定的C++类

在xcode中,把my文件夹拖到cocos2d_libs.xcodeproj中

HNLuaTest.h

  1. //
  2. // HNLuaTest.h
  3. // cocos2d_libs
  4. //
  5. // Created by Eleven Chen on 14-8-5.
  6. //
  7. //
  8.  
  9. #ifndef __cocos2d_libs__HNLuaTest__
  10. #define __cocos2d_libs__HNLuaTest__
  11.  
  12. #include "cocos2d.h"
  13. #include <string>
  14.  
  15.  
  16. class Test : public cocos2d::Ref
  17. {
  18. public:
  19.  
  20. static std::string helloMsg();
  21.  
  22. static Test* create();
  23.  
  24. bool init();
  25. static cocos2d::Vec2 left();
  26. };
  27.  
  28. #endif /* defined(__cocos2d_libs__HNLuaTest__) */

HNLuaTest.cpp

  1. //
  2. // HNLuaTest.cpp
  3. // cocos2d_libs
  4. //
  5. // Created by Eleven Chen on 14-8-5.
  6. //
  7. //
  8.  
  9. #include "HNLuaTest.h"
  10. using namespace cocos2d;
  11.  
  12. std::string Test::helloMsg()
  13. {
  14. return "Hello from HNLuaTest::helloMsg()";
  15. }
  16.  
  17. Test* Test::create()
  18. {
  19. return new Test();
  20. }
  21.  
  22. bool Test::init()
  23. {
  24. return true;
  25. }
  26.  
  27. Vec2 Test::left()
  28. {
  29. return Vec2(0,0);
  30. }

编写ini文件

进入到tolua目录:$(PROJECT_ROOT)/frameworks/cocos2d-x/tools/tolua

在之前先看看README文件,并安装好环境。

README文件中提到必须要用android ndk r9b来编译,因为编译的时候用到了C++ std 4.7的头文件,而r9b包含了4.7,我用的是r9d,只有4.6和4.8。我把*.ini文件里面的4.7改成4.8来编译。

新建一个cocos2dx_custom.ini文件,然后从其他文件里面copy一份代码过来修改代码里面每一个设置都有详细的注释。

  1. clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
  2. # the prefix to be added to the generated functions. You might or might not use this in your own
  3. # templates
  4. prefix = cocos2dx_custom
  5.  
  6. # create a target namespace (in javascript,this would create some code like the equiv. to `ns = ns || {}`)
  7. # all classes will be embedded in that namespace
  8. target_namespace = cc
  9.  
  10. # the native namespace in which this module locates,this parameter is used for avoid conflict of the same class name in different modules,as "cocos2d::Label" <-> "cocos2d::ui::Label".
  11. cpp_namespace =
  12.  
  13. android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
  14. android_flags = -D_SIZE_T_DEFINED_
  15.  
  16. clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
  17. clang_flags = -nostdinc -x c++ -std=c++11
  18.  
  19. cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android
  20.  
  21. cocos_flags = -DANDROID
  22.  
  23. cxxgenerator_headers =
  24.  
  25. # extra arguments for clang
  26. extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
  27.  
  28. # what headers to parse
  29. headers = %(cocosdir)s/cocos/my/HNLuaTest.h
  30.  
  31. # what classes to produce code for. You can use regular expressions here. When testing the regular
  32. # expression,it will be enclosed in "^$",like this: "^Menu*$".
  33. classes = Test.*
  34.  
  35. # what should we skip? in the format ClassName::[function function]
  36. # ClassName is a regular expression,but will be used like this: "^ClassName$" functions are also
  37. # regular expressions,they will not be surrounded by "^$". If you want to skip a whole class,just
  38. # add a single "*" as functions. See bellow for several examples. A special class name is "*",which
  39. # will apply to all class names. This is a convenience wildcard to be able to skip similar named
  40. # functions from all classes.
  41.  
  42. skip =
  43.  
  44. rename_functions =
  45.  
  46. rename_classes =
  47.  
  48. # for all class names,should we remove something when registering in the target VM?
  49. remove_prefix =
  50.  
  51. # classes for which there will be no "parent" lookup
  52. classes_have_no_parents = Test
  53.  
  54. # base classes which will be skipped when their sub-classes found them.
  55. base_classes_to_skip =
  56.  
  57. # classes that create no constructor
  58. # Set is special and we will use a hand-written constructor
  59. abstract_classes =
  60.  
  61. # Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
  62. script_control_cpp = no

编写genbindings.py

为了方便,每次绑定时不需要生成cocos2d-x的绑定代码,新建一个genbindings_custom.py文件,然后复制genbindings.py代码过来,把下面的地方:

  1. cmd_args = {'cocos2dx.ini' : ('cocos2d-x','lua_cocos2dx_auto'),\
  2. 'cocos2dx_extension.ini' : ('cocos2dx_extension','lua_cocos2dx_extension_auto'),\
  3. 'cocos2dx_ui.ini' : ('cocos2dx_ui','lua_cocos2dx_ui_auto'),\
  4. 'cocos2dx_studio.ini' : ('cocos2dx_studio','lua_cocos2dx_studio_auto'),\
  5. 'cocos2dx_spine.ini' : ('cocos2dx_spine','lua_cocos2dx_spine_auto'),\
  6. 'cocos2dx_physics.ini' : ('cocos2dx_physics','lua_cocos2dx_physics_auto'),\
  7. 'custom.ini': ('custom','lua_custom_auto'),\
  8. 'cocos2dx_custom.ini' : ('cocos2dx_custom','lua_cocos2dx_custom_auto'),\
  9. }

改为

  1. cmd_args = {'cocos2dx_custom.ini' : ('cocos2dx_custom',\
  2. }

运行genbindings_custom.py

  1. ./genbindings_custom.py

生成代码cocos/scripting/lua-bindings/auto里面

mac和ios的集成

  • 生成的hpp和cpp拖到cocos2d_lua_bindings.xcodeproj/auto中

Android集成

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3.  
  4. LOCAL_MODULE := cocos_custom_static
  5.  
  6. LOCAL_MODULE_FILENAME := libmy
  7.  
  8. LOCAL_SRC_FILES := \
  9. HNLuaTest.cpp
  10.  
  11. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
  12. $(LOCAL_PATH)./
  13.  
  14. LOCAL_C_INCLUDES := $(LOCAL_PATH) \
  15. $(LOCAL_PATH)./
  16.  
  17. LOCAL_CFLAGS += -Wno-psabi
  18. LOCAL_EXPORT_CFLAGS += -Wno-psabi
  19.  
  20. LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
  21.  
  22. include $(BUILD_STATIC_LIBRARY)
  23.  
  24. $(call import-module,.)
  • 打开lua-bindings文件夹的Android.mk文件添加以下内容
    1. LOCAL_SRC_FILES := manual/CCLuaBridge.cpp \
    2. #省略
    3. auto/lua_cocos2dx_custom_auto.cpp \
    4. ../../../external/lua/tolua/tolua_event.c \
    5. #省略

注册到Lua

修改AppDelegate.cpp

  1. //register custom function
  2. //LuaStack* stack = engine->getLuaStack();
  3. //register_custom_function(stack->getLuaState());
  4. LuaStack *stack = engine->getLuaStack();
  5. auto L = stack->getLuaState();
  6. if (L)
  7. {
  8. lua_getglobal(L,"_G");
  9. register_all_cocos2dx_custom(L);
  10. lua_settop(L,0);
  11. }
  12.  
  13. #if (COCOS2D_DEBUG>0)
  14. if (startRuntime())
  15. return true;
  16. #endif
  17. engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str());
  18. return true;

这里不能按照原本代码注释的方法那样做,那样会出错。

而且都是tolua_module这个函数里面的lua_rawget(L,-2);这一行出错。

原因是:

  1. auto engine = LuaEngine::getInstance();
  2. _defaultEngine->init();
  3. executeScriptFile(“Deprecated.lua”);
  4. _stack->clean();
  5. lua_settop(_state,0);

LuaEngine初始化的时候会运行3个lua文件,把stack给清空了。

tolua_module函数中,lua_pushstring(L,name);后,栈只有一个元素,所以 只需要把_G放到栈中,再运行register_all_cocos2dx_custom(L);,如果模块不在_G中,就添加_G中,就可以全局访问了。

cocos code ide build custom runtime

测试

  1. -- test custom
  2. local msg = cc.Test:helloMsg()
  3. print(msg)

输出

绑定时候使用自己的命名空间

打开:cocos2d-x/tools/bindings-generator/targets/lua/conversions.yaml文件
在ns_map添加自己的命名空间:

  1. ns_map:
  2. "cocos2d::extension::": "cc."
  3. "cocos2d::ui::": "ccui."
  4. "cocos2d::": "cc."
  5. "spine::": "sp."
  6. "cocostudio::": "ccs."
  7. "cocosbuilder::": "cc."
  8. "CocosDenshion::": "cc."
  9. # 我自己的命名空间
  10. "hunuo::": "hn."

猜你在找的Cocos2d-x相关文章