cocos2d-x で Objective-C / Java のコードを実行する
マルチプラットフォーム開発できる cocos2d-x で、iOS の Objective-C、Android の Java のコードを実行する方法を紹介します。
ここでは、ログを出力させるコードをネイティブで書きます。ログを出力するコードは、iOS なら AppController.m、Android なら MyProject.java に記述し、それをコールする処理を想定しています。
作成するファイル
以下のファイルを プロジェクト名/Classes に作成します。
- NativeLauncher.h(iOS, Android 共通)
- NativeLauncher.mm(iOS)
- NativeLauncher.cpp(Android)
iOS 及び Android 共通の作業
NativeLauncher.h を作成し、以下の内容を記述します。返り値 void で、引数を必要としない launchNative() クラスを宣言します。
// NativeLauncher.h
#ifndef MyProject_NativeLauncher_h
#define MyProject_NativeLauncher_h
class NativeLauncher
{
public:
static void launchNative();
};
#endif
NativeLauncher.h で宣言したクラスを HelloWorldScene.cpp から呼び出すように追加します。標準で作成される HelloWorldScene.cpp の menuCloseCallback に記述します。これで、ボタンが押されるたびにログが吐かれるようになります。
// HelloWorldScene.cpp
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
NativeLauncher::launchNative();
/*
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
*/
}
iOS 側で行う作業(Xcode)
プロジェクト名/proj.ios/プロジェクト名.xcodeproj を Xcode で起動します。
AppController.h および AppController.m にログを吐き出すだけのメソッドを追加します。
// AppController.h
#import <UIKit/UIKit.h>
@class RootViewController;
@interface AppController : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
}
- (void)launchNative; // 追加
@end
// AppController.m
// ...
- (void)launchNative
{
NSLog(@"%s", __FUNCTION__);
}
// ...
こちらを cocos2d-x から呼び出すために、NativeLauncher.mm を作成し、以下の内容を記述します。拡張子 *.mm は、Objective-C 及び C++ を混在しても問題なく動作します。
// NativeLauncher.mm
#include "NativeLauncher.h"
#include "AppController.h"
void NativeLauncher::launchNative()
{
AppController *appController = (AppController *)[UIApplication sharedApplication].delegate;
[appController launchNative];
}
以上で、Xcode からビルドを行うと iOS アプリが起動します。cocos2d-x から Objective-C のコードが実行できるのが確認できます。
Android 側で行う作業(Eclipse)
基本的に、Android も iOS と同じ手順を踏みますが、Java のコードを実行する際に、JNI を実装する必要があります。JNI とは、Java と C/C++ を連携する機能のことです。
プロジェクト名/proj.android を Eclipse で起動します。src/パッケージ名/プロジェクト名.java にログを吐き出すだけのメソッドを追加します。ここでのプロジェクト名は MyProject です。
// MyProject.java
public class MyProject extends Cocos2dxActivity{
// …
public static void launchNative()
{
System.out.println("launchNative()");
}
// …
}
こちらを cocos2d-x から呼び出すために、NativeLauncher.cpp を作成し、以下の内容を記述します。CLASS_NAME は、パッケージ名と Java クラス名をスラッシュで区切った文字列になります。
// NativeLauncher.cpp
#include "NativeLauncher.h"
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
// パッケージ名と Java クラス名
#define CLASS_NAME "com/rakuishi/myproject/MyProject"
void NativeLauncher::launchNative()
{
cocos2d::JniMethodInfo t;
if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchNative", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
また、.cpp ファイルを追加したので、Eclipse のビルドに含めるように明示する必要があります。Android.mk に以下の内容を記述します。
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/NativeLauncher.cpp
また、Xcode でファイルを追加したのに Eclipse で表示されないなどの場合は、[File] → [Refresh] を選択すると正しく表示されます。
以上で、Eclipse からビルドを行うと Android アプリが起動します。cocos2d-x から Java のコードが実行できるのが確認できます。