天天看點

Cocos如何綁定lua自定義類

從論壇和技術支援的回報來看,很多童鞋在Cocos中進行lua綁定時遇到了不少問題,因為Cocos使用的是預編譯庫的方式,是以和之前用Cocos2d-x綁定又不太一樣。原有的教程也需要做調整,這篇文章目的是在Cocos中建立一個自定義類,并進行lua綁定,然後在lua中調用C++。  

關于如何在Cocos2d-x中進行lua綁定自定義類,請看 Binding_Custom_Class_To_Lua_Runtime 。本文是基于此教程做的調整。  

1.版本說明  

環境: Mac OSX  

Cocos: v2.1  

Cocos2d-x: v3.4Final  

Cocos Code IDE: v1.2.0  

Cocos Studio: v2.1.2 beta(這裡沒用到)  

2.在Cocos中進行lua綁定自定義類  

2.1 建立項目  

首先,建立一個Cocos項目,名字為CocosLuaBinding。  

2.2 釋出項目  

建立後預設會使用Cocos Studio打開,選擇釋出為XCode工程。  

2.3 添加自定義類  

在XCode中,項目的Classes目錄下添加Custom類。  

複制代碼
  1. // CustomClass.h
  2. #ifndef __CUSTOM__CLASS
  3. #define __CUSTOM__CLASS
  4. #include "cocos2d.h"
  5. namespace cocos2d {
  6. class CustomClass : public cocos2d::Ref
  7. {
  8. public:
  9.     CustomClass();
  10.     ~CustomClass();
  11.     bool init();
  12.     std::string helloMsg();
  13.     CREATE_FUNC(CustomClass);
  14. };
  15. } //namespace cocos2d
  16. #endif // __CUSTOM__CLASS
複制代碼
  1. // CustomClass.cpp
  2. #include "CustomClass.h"
  3. USING_NS_CC;
  4. CustomClass::CustomClass(){
  5. }
  6. CustomClass::~CustomClass(){
  7. }
  8. bool CustomClass::init(){
  9.     return true;
  10. }
  11. std::string CustomClass::helloMsg() {
  12.     return "Hello from CustomClass::sayHello";
  13. }

2.4 添加cocos2dx_custom.ini檔案  

由于使用的是Cocos Framework,是以建立的cocos2dx_custom.ini路徑是 /Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua/(預設安裝路徑)。需要注意的是headers的路徑要指向項目/frameworks/runtime-src/Classes/,這裡我用了絕對路徑,您需要修改為自己的路徑。  

複制代碼
  1. [cocos2dx_custom]
  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. # create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
  6. # all classes will be embedded in that namespace
  7. target_namespace =
  8. android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/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
  9. android_flags = -D_SIZE_T_DEFINED_
  10. clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
  11. clang_flags = -nostdinc -x c++ -std=c++11
  12. cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
  13. cocos_flags = -DANDROID
  14. cxxgenerator_headers =
  15. # extra arguments for clang
  16. 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
  17. # what headers to parse
  18. #headers = %(cocosdir)s/cocos/my/CustomClass.h
  19. headers = /Users/Jacky/Workspace/CocosLuaBinding/frameworks/runtime-src/Classes/CustomClass.h
  20. # what classes to produce code for. You can use regular expressions here. When testing the regular
  21. # expression, it will be enclosed in "^$", like this: "^Menu*$".
  22. classes = CustomClass.*
  23. # what should we skip? in the format ClassName::[function function]
  24. # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
  25. # regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
  26. # add a single "*" as functions. See bellow for several examples. A special class name is "*", which
  27. # will apply to all class names. This is a convenience wildcard to be able to skip similar named
  28. # functions from all classes.
  29. skip =
  30. rename_functions =
  31. rename_classes =
  32. # for all class names, should we remove something when registering in the target VM?
  33. remove_prefix =
  34. # classes for which there will be no "parent" lookup
  35. classes_have_no_parents =
  36. # base classes which will be skipped when their sub-classes found them.
  37. base_classes_to_skip =
  38. # classes that create no constructor
  39. # Set is special and we will use a hand-written constructor
  40. abstract_classes =
  41. # 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'.
  42. script_control_cpp = no

2.5 修改genbindings.py  

genbindings.py腳本是用來運作綁定的腳本。這裡的路徑是/Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua/genbindings.py。  

找到cmd_args,加入下面這行:  

複制代碼
  1.   'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom'), \

output_dir參數指定了綁定檔案的輸出目錄,這裡可以更改為Classes,也可以不改。這裡就不改了。  

cmd_args的其他行是引擎的腳本綁定,如果未做修改,可以删除以避免引擎檔案的重複綁定,加快綁定速度。這裡也不改了。  

2.6 運作綁定腳本  

打開終端,進入tolua目錄,運作剛才修改的genbindings.py腳本。  

複制代碼
  1. cd /Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua
  2. ./genbindings.py

這裡不讨論綁定失敗的情況,大部分是環境變量沒配好的原因,在運作之前請先閱讀/Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua/README.mdown。  

2.7 拷貝綁定檔案到項目目錄  

在成功運作完綁定腳本後,綁定檔案會生成在/Applications/Cocos/frameworks/cocos2d-x-3.4/cocos/scripting/lua-bindings/auto/lua_cocos2dx_custom.cpp(h)  

将這倆個檔案剪切到Classes目錄,并添加到XCode項目中。  

到此為止,基本上是和Binding_Custom_Class_To_Lua_Runtime一緻的。  

3.編譯運作  

由于使用的是Cocos Framework,是以引擎沒有源碼了,隻有預編譯庫,這也就是為什麼在第二步中我們主要做的調整:把自定義類及其綁定檔案放到Classes中。  

3.1 注冊自定義類  

打開Classes/lua_module_register.h檔案,添加頭檔案  

複制代碼
  1. include "lua_cocos2dx_custom.hpp"

在static int lua_module_register(lua_State* L)添加注冊函數  

複制代碼
  1. register_all_cocos2dx_custom(L);

3.2 關閉COCOS_IDE_DEBUG_SUPPORT  

打開Classes/ide-support/CodeIDESupport.h檔案,修改  

複制代碼
  1. define CC_CODE_IDE_DEBUG_SUPPORT 0

3.3 在Cocos IDE中建構自定義模拟器  

在Cocos IDE中打開項目,選中CocosLuaBinding項目,右鍵,Cocos工具,建構自定義模拟器,選擇相應的模拟器,點選生成。  

因為Cocos Framework預設使用自帶的模拟器,是以如果修改了C++檔案,仍然使用預設模拟器,修改的C++檔案不會生效。  

建構自定義模拟器後,以後每次都會使用自定義的模拟器。  

3.4 如何知道目前使用的是自定義模拟器還是預設模拟器?  

選中CocosLuaBinding項目,右鍵,調試方式,調試配置。  

以Mac平台為例:  

自定義模拟器路徑為/Users/Jacky/Workspace/CocosLuaBinding/runtime/mac/CocosLuaBinding Mac  

預設模拟器路徑為/Applications/Cocos/cocos-simulator-bin/mac/Simulator.app  

4.測試綁定是否成功  

在src/app/views/MainScene.lua的function MainScene:onCreate()中添加如下測試代碼  

複制代碼
  1. local customClass = CustomClass:create()
  2.     local msg = customClass:helloMsg()
  3.     release_print("customClass's msg is : " .. msg) --注意已經沒有cclog了

5.搞定,收工~  

繼續閱讀