網上有很多cocos2d-x lua綁定c++類的接口教程,這篇文章也是總結他們的經驗。
其中重點參考了 http://cn.cocos2d-x.org/tutorial/show?id=1295,
整個過程步驟很詳細,會比較傻瓜式,希望對新手讀者入門有用。
教程基本環境:
1.使用引擎是v3.3 beta版本
2.開發環境:OSX Yosemite
3. Cocos code IDE
4. Xcode 6
1、在Mac上用Cocos code IDE 寫lua還是比較便利的,我們用cocos code 新建一個工程,命名LuaBindingTest,選擇Add Nativie Code(為什么選這個可以去了解一下),工程新建完成后打開運行。如沒問題,我們進行下一步。
2、用Xcode打開以上工程,選擇ios 模擬器運行,第一次運行會有錯誤和異常問題,我們修改一下:在Xcode -》General,把Device Orientation的Portrait選項去掉(游戲一般橫屏或豎屏),只保留Langscape Left/Right,修改AppDelegate.cpp的applicationDidFinishLaunching方法,注釋掉 initRuntime() ,run,應該能看到畫面了。
3. xcode中,新建Class類(放在AppDelegate.cpp所在目錄),命名MClass,打開cpp,我們隨便加一些方法,MClass類執行綁定過程,並導出lua接口。
MClass.h
#ifndef __LUaBindingTest__MClass__
#define __LUaBindingTest__MClass__
#include <stdio.h>
#include "cocos2d.h"
using namespace cocos2d;
class MClass : public Ref { public: bool init() { return true; } CREATE_FUNC(MClass); void doLog() { CCLOG("MClass 綁定成功!"); } };
#endif /* defined(__LUaBindingTest__MClass__) */
關於上面的c++類,構造函數是必須寫上的
4. 回到工程的Finder下,打開以下這個目錄,
。。。 LuaBindingTest ▸ frameworks ▸ cocos2d-x ▸ tools ▸ tolua
我們會看到很多ini文件和一個genbindings.py,ini是引擎模塊的lua綁定配置,genbindings.py腳本會配置這些已存在的ini文件然后導出一個c++導出給lua的接口文件(hpp和cpp文件)。為了不干擾引擎現有的lua接口代碼,我們依葫蘆畫瓢,配置一個我們自己項目用到的lua綁定接口。 拷貝 cocos2dx_spine.ini,重命名為game.ini ;拷貝genbindings.py,重命名為genbindings_game.py. 剩下的就是修改這兩個文件。
game.ini
修改處:
[game] prefix = game #target_namespace,有點命名空間的作用,我舉個例子,cocos2dx.ini的這個參數是cc,所以在lua里面調用Director 需要在#前面cc,這個參數可有可無,但建議寫了就不要修改,我們這里不寫 target_namespace = headers = %(cocosdir)s/../runtime-src/Classes/MClass.h classes = MClass skip = abstract_classes =
genbindings_game.py
只修改第129行
cmd_args = {'game.ini' : ('game', 'lua_game_auto'), \
}
5. 終端,cd 到tolua目錄,python genbindings_game.py。
如果遇到錯誤,請閱讀tolua目錄下的 README.mdown文件,參照上面的方法解決(特別注意,需要的是NDK r9b)
6. 上面過程運行成功后我們會得到兩個文件 lua_game_auto.cpp 和lua_game_auto.hpp,
回到Xcode,導入這兩個文件,注意導入到 cocos2d_lua_bindings.xcodeproj庫工程而不是項目工程!
添加 cocos2d_lua_bindings.xcodeproj 的Header Search Paths. (小技巧,五個..)
7. 把我們的game模塊注冊進lua環境中,以往注冊,我們需要在AppDelegate里面添加,v3.3之后,這些模塊注冊過程全部放到
lua_module_register.h里面的lua_module_register 方法中
...
//主要代碼 #include "lua_game_auto.hpp" int lua_module_register(lua_State* L) { //Dont' change the module register order unless you know what your are doing register_cocosdenshion_module(L); register_network_module(L); register_cocosbuilder_module(L); register_cocostudio_module(L); register_ui_moudle(L); register_extension_module(L); register_spine_module(L); register_cocos3d_module(L); #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS register_audioengine_module(L); #endif lua_getglobal(L, "_G"); if (lua_istable(L,-1))//stack:...,_G, { register_all_game(L); } lua_pop(L, 1); return 1; }
8. 至此,MClass的綁定過程已完成,我們在main.lua 中測試一下
local test = MClass:create()
test:doLog()
xcode 運行,看是否打印log,親測是可以的。如果想在 cocos code運行,需要編譯一次 ,工程右鍵 Cocos tools-》Build custom runtimes(筆者操作之后,Build提示成功,但運行提示MClass 為nil,未解決,還請指教)
注意,如果要刪除c++導出到lua的類對象,直接把引用賦為nil就會調用c++類的析構
9.當然,我們一個項目不可能只寫一個類導出給lua用,如何實現多個c++類導出給lua呢?過程也非常簡單, 這里,我們可以參考引擎的做法如cocos2dx.ini,即把多個類配置到同一個ini文件中。
為了避免需要在ini中引入多個c++頭文件,我們新建一個lua_c_export.h文件,把需要綁定的類(自己完成這三個類的代碼)的頭文件include到這個頭文件里,然后game.ini文件只配置這個lua_c_export.h的路徑,這樣可避免做多余修改,要知道配路徑非常容易出錯,如果多人協作,更容易混亂。可參考下面的圖例
game.ini
終端,cd 到tolua目錄,python genbindings_game.py。我們在lua文件 調用我們綁定的c++類,運行
打印log,下圖說明我們多個類綁定成功
以上就是整個lua綁定c++類過程,希望對讀者有用!