自分用の手順書です。
なにか抜けてたら逐次追記します。
開発環境
Cocos2d-x 3.3 rc0
NDK r9d
本稿ではCocos2d-x 3.3 rc0を使用していますが、3.0 beta2くらいの頃から使い倒している手段なので、3.xなら大丈夫だと思います。
やりたいこと
広告を表示させたり、OSのポップアップを表示させたり、外部に遷移させたりなどを行う際、本家のplugin-xが中々使いづらく、且つ開発の進捗も怪しいのでPluginWrapperだけ使いたい。
PluginWrapperはplugin-xで共通で使用されている、UIスレッドでの処理をいい感じにしてくれるコンポーネント。
下準備
plugin-xをパブリッシュ
空の状態でパブリッシュしたいので、config.shで、余計なプラグインを削除する。
パブリッシュ自体はプロジェクト個別にコピーされたcocos2dリソースからも行えるが、PluginProtocolを全プロジェクト統一して使いたい場合は、本体の方のリソースで行ったほうが良い。
$ cd cocos2d/plugin/tools/
$ vi config.sh
# define plugins array
# export ALL_PLUGINS=("flurry" "umeng" \
# "alipay" "nd91" "googleplay" \
# "admob" \
# "twitter" "weibo" \
# "qh360" "uc" \
# "facebook" "facebookads")
export ALL_PLUGINS=()
...
そしてパブリッシュ。
この際、NDK等のパスを聞かれるので適宜入力する。
$ ./publish.sh
Please input the android-ndk path:
/Users/smith/lib/ndk/
Get ANDROID_NDK_ROOT=/Users/smith/lib/ndk
Please input the andoid-sdk path:
/Users/smith/lib/adt-bundle-mac-x86_64-20140702/sdk
Get ANDROID_SDK_ROOT=/Users/smith/lib/adt-bundle-mac-x86_64-20140702/sdk
Please input the ant tool path(such as '/Users/MyAccount/tools/ant/bin'):
/Users/smith/lib/apache-ant-1.9.4/bin
Get ANT_PATH=/Users/smith/lib/apache-ant-1.9.4/bin
mkファイルを編集
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)
# パスの追加
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/plugin/publish)
LOCAL_MODULE := cocos2dcpp_shared
LOCAL_MODULE_FILENAME := libcocos2dcpp
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
LOCAL_STATIC_LIBRARIES := cocos2dx_static
# .aの追加 PluginProtocol以外に使うものもついでに
LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,.)
# モジュールの追加 PluginProtocol以外に使うものもついでに
$(call import-module,protocols/android)
$(call import-module,audio/android)
$(call import-module,network)
$(call import-module,extensions)
また、ndkのバージョンとかバグとかstdとかの煩雑な問題から開放されるため、私はSTLをgnustl_staticにすることが習慣になってしまっています。
# APP_STL := c++_static
APP_STL := gnustl_static
libPluginProtocolプロジェクトのインポートと参照の追加
Eclipseにプロジェクトをインポートした上で、プロジェクトのプロパティからlibPluginProtocolへの参照を加える
antに署名の設定
今回の題目とは関係ないけど、おまけ。
key.alias.password=my_fantastic_app_password
key.store.password=my_fantastic_app_password
key.store=/Users/smith/keys/apk/my_fantastic_app/my_fantastic_app_key
key.alias=my_fantastic_app_key
実装
PluginWraperを使用するためには、適宜初期化する必要があります。
javaVM
# include "AppDelegate.h"
# include "cocos2d.h"
# include "platform/android/jni/JniHelper.h"
# include <jni.h>
# include <android/log.h>
# include "PluginJniHelper.h"
# define LOG_TAG "main"
# define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
void cocos_android_app_init (JNIEnv* env, jobject thiz)
{
AppDelegate *pAppDelegate = new AppDelegate();
JavaVM* vm;
env->GetJavaVM(&vm);
PluginJniHelper::setJavaVM(vm);
}
Cocos2dxActivityとCocos2dxGLSurfaceView
ClippingNodeとか使ってると、Cocos2dxGLSurfaceViewは必然的に設定することになるんじゃないかと。
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.plugin.PluginWrapper;
public class AppActivity extends Cocos2dxActivity
{
@Override public Cocos2dxGLSurfaceView onCreateView()
{
Cocos2dxGLSurfaceView glsView = super.onCreateView();
glsView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
PluginWrapper.init(this);
PluginWrapper.setGLSurfaceView(glsView);
H3NativeLifeCycle.applicationDidFinishLaunching();
return glsView;
}
...
}
使い方
GameFeatなど、ContextやActivityを欲しがるSDKにはPluginWrapper.getContext() を与える。
public static void initGamefeat()
{
gamefeatController = new GameFeatAppController();
gamefeatController.init(PluginWrapper.getContext());
gamefeatController.setRefreshInterval(30);
gamefeatController.activateGF(PluginWrapper.getContext(), false, true, true);
}
Viewへの追加はrunOnMainThreadで行う必要がある。
じゃないとクラッシュする。
public static void showIntersticial()
{
PluginWrapper.runOnMainThread(new Runnable(){
@Override
public void run()
{
aidController.showDialog(AdController.DialogType.ON_EXIT);
}
});
}
殊の外、jniのデバッグはめんどいので、とにかくtry / catch(Exception e) でエラーメッセージを見るという残念な手法が推奨される。
ビルド
通らなかったらごめんなさい。
$ cocos run -p android -m release --ap 14