自然界でのcocos2d-x Luaの使用については、英語の情報源を考慮しても、非常に多くの情報資料があります。 したがって、多くの点であなたは自分自身を理解し、他の誰かのコードを掘り下げて(多くの場合非常に有益ではない)ドキュメントを読む必要があります。
この記事では、この不正を少なくとも部分的に修正し、ネイティブクラスを使用してcocos2d-x Luaで利用可能な標準機能を拡張することについて説明します。
Lua自身のわずかな知識に気付いた後、私はこの挑戦に直面しました。 その後、決定は成熟し、古き良きC ++でゲームロジックの一部を記述しました。
だから、このプロセスに興味がある人は猫をお願いします。
出発点として、CocosCode IDEをインストールして構成したものを見てみましょう。 そうでない場合、これはロシア語の良い記事です 。
1. C ++クラスを作成します
Luaに接続するクラスを作成することから始めましょう。
Myclass.hpp
#ifndef MyClass_hpp #define MyClass_hpp #include "cocos2d.h" #include <string> using std::string; namespace cocos2d { class MyClass : public cocos2d::Ref { public: MyClass(); ~MyClass(); bool init(); string myFunction(); CREATE_FUNC(MyClass); }; } //namespace cocos2d #endif
ここでは、クラスがRefの子孫であるという事実に注意を払う必要があります。これは、cocos2d-xのメモリ管理の特性によって引き起こされます。
Myclass.cpp
#include "MyClass.hpp" using namespace cocos2d; MyClass::MyClass() {} MyClass::~MyClass() {} bool MyClass::init() { return true; } string MyClass::myMethod() { return "Hello, Habrahabr!"; }
クラスのファイルを「myclass」ディレクトリに配置し、/ framework / cocos2d-x / cocos /(プロジェクト内)に作成します。 フレームワークフォルダーがない場合は、CocosCodeで次を実行する必要があります。
プロジェクトを右クリック-> Cocos Tools-> Add Native Code Support
2.クラスのLuaラッパーを作成する
これを行うには、/ frameworks / cocos2d-x / tools / toluaフォルダーに次のファイルを作成します。
cocos2dx_myclass.ini
[cocos2dx_myclass]
#生成された関数に追加されるプレフィックス。 あなたは自分でこれを使うかもしれないし、使わないかもしれない
#テンプレート
prefix = cocos2dx_myclass
#ターゲット名前空間を作成します(javascriptでは、これは `ns = ns || {}`と同等のコードを作成します)
#すべてのクラスはその名前空間に埋め込まれます
target_namespace =
android_headers = -I%(androidndkdir)s / platform / 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 %(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 / myclass -I%(cocosdir)s / cocos / base -I%(cocosdir)s / cocos / platform / android
cocos_flags = -DANDROID
cxxgenerator_headers =
#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
#解析するヘッダー
headers =%(cocosdir)s / cocos / myclass / MyClass.hpp
#コードを生成するクラス。 ここで正規表現を使用できます。 レギュラーをテストするとき
#式、「^ Menu * $」のように、「^ $」で囲まれます。
クラス= MyClass *
#何をスキップしますか? ClassName :: [function function]の形式で
#ClassNameは正規表現ですが、次のように使用されます。「^ ClassName $」関数も
#正規表現、「^ $」で囲まれません。 クラス全体をスキップしたい場合は、
#単一の「*」を関数として追加します。 いくつかの例については、以下を参照してください。 特別なクラス名は「*」で、これは
#はすべてのクラス名に適用されます。 これは、同様の名前をスキップできる便利なワイルドカードです
#すべてのクラスの関数。
スキップ=
rename_functions =
rename_classes =
#すべてのクラス名について、ターゲットVMに登録するときに何かを削除する必要がありますか?
remove_prefix =
#「親」ルックアップがないクラス
classes_have_no_parents =
#サブクラスがそれらを見つけたときにスキップされる基本クラス。
base_classes_to_skip =
#コンストラクターを作成しないクラス
#セットは特別であり、手書きのコンストラクタを使用します
abstract_classes =
#ネイティブ(cpp)オブジェクトのライフサイクルを制御するためにスクリプトオブジェクト(jsオブジェクト)を使用するか、またはその逆を行うかを決定します。 サポートされる値は「yes」または「no」です。
script_control_cpp = no
#生成された関数に追加されるプレフィックス。 あなたは自分でこれを使うかもしれないし、使わないかもしれない
#テンプレート
prefix = cocos2dx_myclass
#ターゲット名前空間を作成します(javascriptでは、これは `ns = ns || {}`と同等のコードを作成します)
#すべてのクラスはその名前空間に埋め込まれます
target_namespace =
android_headers = -I%(androidndkdir)s / platform / 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 %(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 / myclass -I%(cocosdir)s / cocos / base -I%(cocosdir)s / cocos / platform / android
cocos_flags = -DANDROID
cxxgenerator_headers =
#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
#解析するヘッダー
headers =%(cocosdir)s / cocos / myclass / MyClass.hpp
#コードを生成するクラス。 ここで正規表現を使用できます。 レギュラーをテストするとき
#式、「^ Menu * $」のように、「^ $」で囲まれます。
クラス= MyClass *
#何をスキップしますか? ClassName :: [function function]の形式で
#ClassNameは正規表現ですが、次のように使用されます。「^ ClassName $」関数も
#正規表現、「^ $」で囲まれません。 クラス全体をスキップしたい場合は、
#単一の「*」を関数として追加します。 いくつかの例については、以下を参照してください。 特別なクラス名は「*」で、これは
#はすべてのクラス名に適用されます。 これは、同様の名前をスキップできる便利なワイルドカードです
#すべてのクラスの関数。
スキップ=
rename_functions =
rename_classes =
#すべてのクラス名について、ターゲットVMに登録するときに何かを削除する必要がありますか?
remove_prefix =
#「親」ルックアップがないクラス
classes_have_no_parents =
#サブクラスがそれらを見つけたときにスキップされる基本クラス。
base_classes_to_skip =
#コンストラクターを作成しないクラス
#セットは特別であり、手書きのコンストラクタを使用します
abstract_classes =
#ネイティブ(cpp)オブジェクトのライフサイクルを制御するためにスクリプトオブジェクト(jsオブジェクト)を使用するか、またはその逆を行うかを決定します。 サポートされる値は「yes」または「no」です。
script_control_cpp = no
このファイルの内容の詳細については説明しません。詳細については、 こちらをご覧ください 。
ここで、作成したばかりのiniファイルをLuaラッパー生成スクリプトに追加する必要があります。 これを行うには、genbindings.pyを開き、閉じ括弧の前に次の行を追加します。
cmd_args = {'cocos2dx.ini' : ('cocos2d-x', 'lua_cocos2dx_auto'), \ 'cocos2dx_extension.ini' : ('cocos2dx_extension', 'lua_cocos2dx_extension_auto'), \ 'cocos2dx_ui.ini' : ('cocos2dx_ui', 'lua_cocos2dx_ui_auto'), \ 'cocos2dx_studio.ini' : ('cocos2dx_studio', 'lua_cocos2dx_studio_auto'), \ 'cocos2dx_spine.ini' : ('cocos2dx_spine', 'lua_cocos2dx_spine_auto'), \ 'cocos2dx_physics.ini' : ('cocos2dx_physics', 'lua_cocos2dx_physics_auto'), \ 'cocos2dx_experimental_video.ini' : ('cocos2dx_experimental_video', 'lua_cocos2dx_experimental_video_auto'), \ 'cocos2dx_experimental.ini' : ('cocos2dx_experimental', 'lua_cocos2dx_experimental_auto'), \ 'cocos2dx_controller.ini' : ('cocos2dx_controller', 'lua_cocos2dx_controller_auto'), \ 'cocos2dx_myclass.ini' : ('cocos2dx_myclass', 'lua_cocos2dx_myclass_auto') \ }
genbindings.pyを開始します。 上記のすべての操作が正常に完了した場合、次のファイルが表示されます(/ frameworks / cocos2d-x / cocos / scripting / lua-bindingディレクトリ):
- lua_cocos2dx_myclass_auto.hpp
- lua_cocos2dx_myclass_auto.cpp
- ./api/MyClass.lua
これで、クラスをLuaに接続するために必要なものがすべて揃いました。 このプロセスは、同じタイプの2つの手順で構成されます。1つはiOS用、もう1つはAndroid用です。
3.1。 ファイルをiOSに接続する
アプリケーションプロジェクトを開きます。 まず、C ++ソースをcocos2d_libsに追加します。
生成されたファイルをcocos2d_lua_bindingsに追加します。
cocos2d_lua_bindings-> Build Settings-> User Header Search Pathsでヘッダーファイルへのパスも設定することを忘れないでください
この機会を利用して、クラスをAppDelegate.cppに登録します。
... #include "ConfigParser.h" // #include "lua_cocos2dx_myclass_auto.hpp" using namespace CocosDenshion; bool AppDelegate::applicationDidFinishLaunching() { ... // set FPS. the default value is 1.0/60 if you don't call this director->setAnimationInterval(1.0 / 60); auto engine = LuaEngine::getInstance(); ScriptEngineManager::getInstance()->setScriptEngine(engine); LuaStack* stack = engine->getLuaStack(); stack->setXXTEAKeyAndSign("2dxLua", strlen("2dxLua"), "XXTEA", strlen("XXTEA")); // register_all_cocos2dx_myclass(stack->getLuaState()); #if (COCOS2D_DEBUG>0) if (startRuntime()) return true; #endif engine->executeScriptFile(ConfigParser::getInstance()->getEntryFile().c_str()); return true; } ...
これが、iOSでの冒険の終わりです。
3.2。 ファイルをAndroidに接続する
ここでは、本質的に、すべてが前のセクションに似ています。 クラスソースをcocos2d-xプロジェクトに接続し、生成されたファイルをcocos2dx_luaプロジェクトに接続する必要があります。 唯一の違いは、テキストファイルAndroid.mkを処理する必要があることです。
クラスファイルをcoconutプロジェクトに追加します。 これを行うために、/ frameworks / cocos2d-x / cocos / Android.mkファイルにいくつかの追加を行います
ここ(* .cppファイルを指定):
そして、ここで(ヘッダーファイルへのパスを指定します):
ここで、生成されたファイルをcocos2d_luaに接続します。 これを行うには、ファイル/frameworks/cocos2d-x/cocos/scripting/lua-bindings/Android.mkを編集します
ここ(* .cppファイルを指定):
そして、ここにあります(ヘッダーファイルへのパスを指定します):
4.ランタイムの更新
原則として、XcodeまたはEclipseでプロジェクトを実行すると、すべてがすでに機能します。 CocosCode IDEですべてが機能するには、ランタイムを再構築する必要があります。 これを行うには、プロジェクト-> Cocos Tools-> Build Custom Runtimesを右クリックします。 以上です。
5.起動、喜ぶ
結果をコンソールの1行のスクリーンショットとして表示することにはあまり意味がありません。 ただし、出力は次のようになります。
[Lua Debug]: Hello, Habrahabr!
同様に、binding-generator-aを使用して、クラスをcocos2d-jsに追加できます。 ただし、発電機自体の通常の起動に数時間を費やさなければならなかったことに注意する必要があります。 必要なさまざまなライブラリの不一致をいじる。 書かれているとおりにすべてが完了していれば、問題はないはずです(ジェネレーターのセットアップ手順については、 こちらを参照してください )。
PS
私の意見では、スクリプト言語のエンジンの「ガーター」は、場合によっては人生を大幅に簡素化できます。 彼女が最後に私の人生を簡素化したかどうかはわかりませんが、興味深い経験を得ました。