[ cocos2d-x ] -JNIによるJava連携4-

前回の記事までで、一通り必要なクラスは用意出来たことと思います。
ですが、cocos2dxを使用してJavaからC++の関数を呼ぶには proj.android内にある
main.cppに処理を追加する必要があります。

proj.android
┗jni
 ┗main
  ┗main.cpp

下記のように追記してください。

#include "AppDelegate.h"
#include "cocos2d.h"
#include "CCEventType.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>
#include "Java2C.h"

#define  LOG_TAG    "main"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

using namespace cocos2d;

extern "C"
{
    
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JniHelper::setJavaVM(vm);

    return JNI_VERSION_1_4;
}

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
    if (!CCDirector::sharedDirector()->getOpenGLView())
    {
        CCEGLView *view = CCEGLView::sharedOpenGLView();
        view->setFrameSize(w, h);

        AppDelegate *pAppDelegate = new AppDelegate();
        CCApplication::sharedApplication()->run();
    }
    else
    {
        ccGLInvalidateStateCache();
        CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
        ccDrawInit();
        CCTextureCache::reloadAllTextures();
        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_FOREGROUND, NULL);
        CCDirector::sharedDirector()->setGLDefaultValues(); 
    }
}

//下記を追記
void Java_com_test_test_JNItest_Java2CEvent(JNIEnv* env, jobject thiz, jstring filePath)
{
    const char* str = env->GetStringUTFChars(filePath, 0);
    char *sendStr = strdup(str);
    env->ReleaseStringUTFChars(filePath, str);

    Java2C::Java2CEvent(sendStr);
}

}

関数名はJava・パッケージ名・クラス名・関数名を”_”でつなげて書きます。
第3引数である、jstring型のfilePathがC++へ渡すために受け取る画像の保存パスです。

関数内では受け取った文字列をutf-8に変換してからC++に渡しています。
Releaseで開放することも忘れずに行いましょう。

JNIで使用する変数は次のように違いがあります。

short jshort
int jint
long jlong
float jfloat
double jdouble
char jchar
String jstring
boolean jboolean
byte jbyte
Object jobject

最後に、HelloWorldSceneにスプライトを追加する処理を記載します。

HelloWorldScene.cpp

void HelloWorld::addImageSprite(char* filePath)
{
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	CCSprite* imgSprite = CCSprite::create(filePath);
	imgSprite->setPosition(ccp(visibleSize.width/2, visibleSize.height/2));
	helloWorldInstance->addChild(imgSprite);
}

以上で、カメラで撮影した写真でスプライトを生成する処理の全実装が終了しました。

さっそく、アプリを起動してみましょう。

まずは、カメラの起動です。
ここまでは前々回までの記事にて実装できていると思います。

   

適当に、撮影してみます。

   

どうですか?
撮影した画像が画面の中心に表示されていることが確認できます。

今回の実装では、スプライト生成時にリサイズや切り取り等をする処理は入れていないので
高解像度設定で撮影した方は、画面からはみ出していると思います。

例えば、これを”setScale”や”CCRect”で任意にサイズを指定しサムネイルのように表示させたのであれば
そのサムネイルをタップした時に撮影した画像を全画面表示させる処理を追加するだけで
アルバムアプリなんかも作れてしまいますね。

4回に渡って説明してきましたJNIも本記事にて終了となります。

今回は撮影したものからスプライトを生成する簡単な処理でしたが
ほかにも下記のようなことが実現可能です。

  • カメラ系(etc:バーコードリーダーを起動して、その情報をcocosで使用する)
  • 課金系(課金処理をNativeで行い、その結果を元にcocosを動作させる)
  • GPS系(現在位置をNativeで取得して、cocosで画面を描画する)

このように、JNIを使用して出来ることはまだたくさんあるので
皆さんもいろいろと試してみてください。

<次回以降の更新について>
次回は、Parse.comについてご紹介いたします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*