從論壇和技術支援的回報來看,很多童鞋在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類。
複制代碼 - // CustomClass.h
- #ifndef __CUSTOM__CLASS
- #define __CUSTOM__CLASS
- #include "cocos2d.h"
- namespace cocos2d {
- class CustomClass : public cocos2d::Ref
- {
- public:
- CustomClass();
- ~CustomClass();
- bool init();
- std::string helloMsg();
- CREATE_FUNC(CustomClass);
- };
- } //namespace cocos2d
- #endif // __CUSTOM__CLASS
|
複制代碼 - // CustomClass.cpp
- #include "CustomClass.h"
- USING_NS_CC;
- CustomClass::CustomClass(){
- }
- CustomClass::~CustomClass(){
- }
- bool CustomClass::init(){
- return true;
- }
- std::string CustomClass::helloMsg() {
- return "Hello from CustomClass::sayHello";
- }
|
2.4 添加cocos2dx_custom.ini檔案
由于使用的是Cocos Framework,是以建立的cocos2dx_custom.ini路徑是 /Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua/(預設安裝路徑)。需要注意的是headers的路徑要指向項目/frameworks/runtime-src/Classes/,這裡我用了絕對路徑,您需要修改為自己的路徑。
複制代碼 - [cocos2dx_custom]
- # the prefix to be added to the generated functions. You might or might not use this in your own
- # templates
- prefix = cocos2dx_custom
- # create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
- # all classes will be embedded in that namespace
- target_namespace =
- 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
- android_flags = -D_SIZE_T_DEFINED_
- clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
- clang_flags = -nostdinc -x c++ -std=c++11
- cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
- cocos_flags = -DANDROID
- cxxgenerator_headers =
- # extra arguments for clang
- 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
- # what headers to parse
- #headers = %(cocosdir)s/cocos/my/CustomClass.h
- headers = /Users/Jacky/Workspace/CocosLuaBinding/frameworks/runtime-src/Classes/CustomClass.h
- # what classes to produce code for. You can use regular expressions here. When testing the regular
- # expression, it will be enclosed in "^$", like this: "^Menu*$".
- classes = CustomClass.*
- # what should we skip? in the format ClassName::[function function]
- # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
- # regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
- # add a single "*" as functions. See bellow for several examples. A special class name is "*", which
- # will apply to all class names. This is a convenience wildcard to be able to skip similar named
- # functions from all classes.
- skip =
- rename_functions =
- rename_classes =
- # for all class names, should we remove something when registering in the target VM?
- remove_prefix =
- # classes for which there will be no "parent" lookup
- classes_have_no_parents =
- # base classes which will be skipped when their sub-classes found them.
- base_classes_to_skip =
- # classes that create no constructor
- # Set is special and we will use a hand-written constructor
- abstract_classes =
- # 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'.
- script_control_cpp = no
|
2.5 修改genbindings.py
genbindings.py腳本是用來運作綁定的腳本。這裡的路徑是/Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua/genbindings.py。
找到cmd_args,加入下面這行:
複制代碼 - 'cocos2dx_custom.ini' : ('cocos2dx_custom', 'lua_cocos2dx_custom'), \
|
output_dir參數指定了綁定檔案的輸出目錄,這裡可以更改為Classes,也可以不改。這裡就不改了。
cmd_args的其他行是引擎的腳本綁定,如果未做修改,可以删除以避免引擎檔案的重複綁定,加快綁定速度。這裡也不改了。
2.6 運作綁定腳本
打開終端,進入tolua目錄,運作剛才修改的genbindings.py腳本。
複制代碼 - cd /Applications/Cocos/frameworks/cocos2d-x-3.4/tools/tolua
- ./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檔案,添加頭檔案
複制代碼 - include "lua_cocos2dx_custom.hpp"
|
在static int lua_module_register(lua_State* L)添加注冊函數
複制代碼 - register_all_cocos2dx_custom(L);
|
3.2 關閉COCOS_IDE_DEBUG_SUPPORT
打開Classes/ide-support/CodeIDESupport.h檔案,修改
複制代碼 - 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()中添加如下測試代碼
複制代碼 - local customClass = CustomClass:create()
- local msg = customClass:helloMsg()
- release_print("customClass's msg is : " .. msg) --注意已經沒有cclog了
|
5.搞定,收工~