cocos2d-xのライブラリにカスタマイズのc++クラスを追加し、luaから呼び出せる方法です。
環境はcocos2d-x 3.15 + Xcode v8.3.2 + macOS Sierra v10.12.4です。注1
-
クラスを作成
- プロジェクトルート/frameworks/cocos2d-x/cocos/の下にcustom(任意)というフォルダを作成
- customの下にc++のクラスGameData(任意)を作成
- Xcodeでプロジェクトを開き、追加したクラス(フォルダごと)をcocos2d_libs.xcodeprojの直下に追加
-
binding用設定ファイルを作成
- プロジェクトルート/frameworks/cocos2d-x/tools/tolua/の下にある比較的簡単な設定ファイルcocos2dx_csloader.iniをコピーしてcustom_game_data.iniにリネーム
- custom_cpp.iniを開き、下記のように変更を加え
- genbinding.pyに使う名前を変更
[cocos2dx_csloader] を
[custom_game_data] に変更 - 自動生成されるc++ブリッジ関数の接頭語
prefix = cocos2dx_csloader を
prefix = custom_game_data に変更 - lua用のモジュール接頭語(ネームスペースと似たもの)
target_namespace = cc を
target_namespace = に変更(ネームスペースが必要なければccを削除 ※注2) - 生成したc++クラスのヘッダー位置
headers = %(cocosdir)s/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h を
headers = %(cocosdir)s/cocos/custom/GameData.h に変更 - luaで使うためのクラスですので、スキップする関数はないはず。
skip = CSLoader::[nodeFromXML nodeFromProtocolBuffers createTimeline nodeWithFlatBuffers createActionTimelineNode createNodeWithDataBuffer createTimelineWithDataBuffer ^createNode$] を
skip = に変更
- genbinding.pyに使う名前を変更
- プロジェクトルート/frameworks/cocos2d-x/tools/tolua/genbindings.pyを開き、141行あたりにあるcmd_argsキーの最後に上記のcustom_game_data.iniを追加
‘custom_game_data.ini’ : (‘custom_game_data’, ‘lua_custom_game_data_auto’), \
※もし2番めのパラメーター’custom_game_data’がiniファイル1行目に定義された名前と一致しなければ、Section not found in config file的なエラーができます。 - 以下のようにgenbindings.pyを実行してc++のブリッジクラスを生成
python genbindings.py
※ImportError: No module named yamlというようなエラーが出た場合、genbindings.pyと同ディレクトリにあるREADMEを参考にして、以下のコマンドで必要なモジュールをインストールsudo easy_install pip
sudo pip install PyYAML
sudo pip install Cheetah
こうすれば、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/の下に、lua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppが生成されます。
c++クラスの関数名変更するたびに、このステップを再実行する必要があります。
-
生成されたファイルをプロジェクトに追加
- 自動生成されたlua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppをXcodeのプロジェクトのcocos2d_lua_bindings.xcodeproj/autoの直下に追加
- cocos2d_lua_bindings.xcodeproj/CCLuaStack.cppに今回追加したクラスへの参照を追加
#include "scripting/lua-bindings/auto/lua_custom_game_data_auto.hpp"
同ファイルのbool LuaStack::init(void)関数に新しいクラスを登録
register_all_custom_game_data(_state);
- Android向けに、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/proj.android/Android.mkの140行あたりに以下のようにソースファイル参照を追加
LOCAL_SRC_FILES += ../../../custom/GameData.cpp \
  ../auto/lua_custom_game_data_auto.cpp \
-
リビルド
- プロジェクトをリビルドすれば、luaで以下のように使えるはずです。
local gameData = GameData:new()
gameData:getName() --仮にgetName()を実装したとして
- プロジェクトをリビルドすれば、luaで以下のように使えるはずです。
※注1: 現時点Xcode8以上のバージョンだと、luaのプロジェクトはiOSシミュレーター上で動きません。
Xcode7以前のバージョンを使うか、iPhone実機もしくはmac(***-desktopプロジェクト)でデバッグ必要があります。
参考:https://github.com/cocos2d/cocos2d-x/issues/17043
2017/05/29追記:上記ページに紹介されたように、luajitをアップデートすれば実行できます。
具体的には、https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/blob/v3/lua/luajit/prebuilt/ios/libluajit.aをダウンロードして、プロジェクトルート/frameworks/cocos2d-x/external/lua/luajit/prebuilt/ios/libluajit.aと置き換えれば良いです。
※注2: target_namespaceを指定すれば、ネームスペースをppと仮定して下記の作業が必要になります。
- custom_game_data.iniにcpp_namespace = ppを追加
※そうしなければ、クラスに定義した関数にもかかわらず、CCLuaStack.cpp: error: undefined reference to的なエラーが出ます。 - プロジェクトルート/frameworks/cocos2d-x/tools/bindings-generator/targets/lua/conversions.yamlの20行あたりにあるns_map:のキーの一番最後に
"pp::": "pp."
を追加
※そうしなければ、The namespace (%s) conversion wasn’t set in ‘ns_map’ section of the conversions.yaml” % namespace_class_nameというようなエラーができます。