現時点で最新の、
cocos2d-x v2.2.2ベース+Nend SDK for Android 2.3.3で説明します。
特にcocos2d-xは3.0以降で大幅に仕様変更予定だそうですが、
とりあえず現状最新の安定版という事で2.2.2を選択しました。
サンプルのソースコード(iOS/Android共通)ありますので、
コードだけ欲しい方は下の方のgithubへのリンクからどうぞ。
この記事ではcocos2d-xのプロジェクト作成から書いております。
広告表示に関する箇所は、中段の「 Icon広告表示制御コード追加」以降です。
以下、Cocos2d-x,NendSDKのダウンロード、ビルド環境作成が済んでいる人は読み飛ばしてOK
ーーー【事前準備】ここから
Nend SDKのダウンロードは、Nend登録後、アプリを登録した後に行えます。
(アプリ公開前でもGooglePlayの予定URLを登録で大丈夫です)
1.Cocos2d-x v2.2.2 をダウンロード
Download Cocos2d-x Cocos2d-html5 CocoStudio | Cocos2d-x
↑からCocos2d-xのv2.2.2を選択
2.Nend新規登録
nend.net(ネンド)スマートフォン広告で日本最大級の運用型アドネットワーク(スマホweb広告/アプリ広告/アイコン広告対応)
↑からアプリ・メディアパートナー様を選択、登録。
3.GooglePlay登録用のアプリパッケージ名を作成しておく
Nendにアプリを登録する時に必要。まだ登録前でも大丈夫なので、登録予定のものを考えておく。
例) com.maxigundan.App.BikeKawasakiBike
4.Nendにログインし、広告枠の管理−サイト/アプリ−新規サイト/アプリの作成
上のパッケージ名含む、必要な情報を申請、登録。
5.広告枠の管理−広告枠
登録されている項目に、”SDK“があると思いますので、そこからDL。
※この記事を書いた時の仕様です。
使い方が分からない場合、サポート様に問い合わせてみてください
丁寧に教えて頂けると思います。
6.libcocos2dx.jarを作成
cocos2d-xでゲーム作成するのに、最初に一度だけ必要になる。
メニューのFile-Import選択、General-Existing Projects into Workspaceで
Select root directoryのBrowseボタンから、
~/cocos2d-x-2.2.2/cocos2dx/ のフォルダを指定。
自動的にいくつかプロジェクトが認識されるので、
“libcocos2dx”のみを選択、Finishを押すと環境が読み込まれる。
Build Project から、ライブラリを作成する。
binフォルダにlibcocos2dx.jarができていれば正常終了
【プロジェクト作成手順】
1.Cocos2d-xプロジェクト作成
作成するアプリ名は”TestGameNendIconAd”、パッケージは”com.MyCompany.TestApp”
フォルダは”~/cocos2d-x-2.2.2/”としています。
各自、自分の環境のパスに読み替えてください。
ターミナルを起動し、以下のコマンド実行
cd ~/cocos2d-x-2.2.2/tools/project-creator/ python create_project.py -project TestGameNendIconAd -package com.MyCompany.TestApp -language cpp
正常に各プラットフォーム全部Done!が表示されればOK
(失敗する場合は大抵パーミッション周りかpythonバージョンかpythonパス関連)
2.Nend SDKライブラリのコピー
cocos2d-x-2.2.2/projects/TestGameNendIconAd/ というフォルダができている。
その中に色々なプラットフォームのプロジェクトができているので、
proj.android 内に “libs” フォルダを作成して、
Nend SDKの環境内にある、nendSDK-2.3.2.jar をlibsフォルダにコピーする
3.Native(cpp)のビルド
Eclipse用のプロジェクトに組み込まれているので
Eclipseからできるみたいだけどよく分からないので手動で行った。
手動で./build_native.shを実行
cd ~/cocos2d-x-2.2.2/projects/TestGameNendIconAd/proj.android ./build_native.sh
ビルドが走るのでしばらく待つ。
エラーが発生せず、
Install : libcocos2dcpp.so => libs/armeabi/libcocos2dcpp.so make: Leaving directory(略
まで終わっていればNative側は正常終了している。
4. Eclipse起動、環境インポート(最初の1回のみ必要)
メニューのFile-Import選択、General-Existing Projects into Workspaceで
Select root directoryのBrowseボタンから、
~/cocos2d-x-2.2.2/projects/TestGameNendIconAd/proj.android のフォルダを指定。
自動的にTestGameNendIconAdプロジェクト環境が認識されるので、
Finishを押すと環境が読み込まれる。
5. ビルド設定
./build_native.sh を手動で実行しているので、Eclipseからはビルドしないよう、
Propatires – Builders から “CDT Builder”を外しておく。
ーーー【事前準備・組み込み手順】ここまで
以上で、サンプルのHelloworldが動く環境と、
Nendアイコンを表示できる環境が整いました。
Icon広告表示制御コード追加
使い回しができるように、広告表示専用のstatic Classを作成し、
さらに、cppファイルから制御するために、JNIを作成します。
JniHelperを使う方法は、おかひろさんの記事、zaruさんのコードを参考にさせていただきました。
Cocos2d-x上からObjective-C/Javaのコードを実行する – おかひろの雑記
zaru/Cocos2DX_AdStir · GitHub
static Classは、Activity起動時にそのActivityを登録する方法で保持し、
後々cppから呼ばれた時に、保持していたActivityオブジェクトを使って、
runOnUiThread()を使って制御する仕組みです。
com/MyCompany/NativeIF/IconAdMgr.java
・Activity登録用メソッド
ここでついでにアイコン周りの初期化もしています。
TestGameNendIconAdのonCreate()の中から、
IconAdMgr.setActivity(this); のように呼び出します。
public static void setActivity(Activity activity) { mActivity = activity; mDensity = activity.getResources().getDisplayMetrics().density; _iconAdLayout = new RelativeLayout(mActivity); RelativeLayout.LayoutParams rootParams = new RelativeLayout.LayoutParams(FP, FP); rootParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); mActivity.addContentView(_iconAdLayout, rootParams); initIconAdParameters(); }
・アイコンパラメータ初期化
IconViewの一つ一つを制御するのは非常に面倒で、
NendAdIconLayoutを使う方が格段に楽なのですが、
せっかく作りましたのでこれをサンプルコードに含んでいます。
//initialize global icon params private static void initIconAdParameters() { if(NEND_ICON_NUMS>4) { ICNAD_SPACE = false; ICNAD_WIDTH = 50; ICNAD_HEIGHT = 50; ICNAD_SHOW_TITLE = false; }else{ ICNAD_SPACE = true; ICNAD_WIDTH = 75; ICNAD_HEIGHT = 75; ICNAD_SHOW_TITLE = true; } //手動でIconViewを設定しておく //(細かい配置にこだわらなければ、絶対にNendAdIconLayout使った方が楽! // Nend SDK同梱サンプルソースやalbatrusさんのページが参考になります) mIconViewArray = new NendAdIconView[NEND_ICON_NUMS]; //alloc array for(int i=0; i<NEND_ICON_NUMS; i++) { mIconViewArray[i] = new NendAdIconView(mActivity); //initialize mIconViewArray[i].setTitleColor(Color.WHITE); mIconViewArray[i].setIconSpaceEnabled(ICNAD_SPACE); mIconViewArray[i].setTitleVisible(ICNAD_SHOW_TITLE); if(NEND_ICON_NUMS>4) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ //Honeycomb以降はsetScaleが使えるのでViewごと縮小する(それ以外は諦める) float scaleX = (float)ICNAD_WIDTH/(float)NEND_DEFAULT_SIZE; float scaleY = (float)ICNAD_HEIGHT/(float)NEND_DEFAULT_SIZE; mIconViewArray[i].setScaleX(scaleX); mIconViewArray[i].setScaleY(scaleY); } } } // get resolution WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); Display disp = wm.getDefaultDisplay(); // 手動で各アイコンのマージン計算する mIconDispWid = ICNAD_WIDTH*mDensity; mIconOffset = ((float)(disp.getWidth()/NEND_ICON_NUMS)- mIconDispWid)/2; mIconMargin = (float)(disp.getWidth()/NEND_ICON_NUMS) - mIconDispWid; }
・アイコン広告の作成・表示
// ---------------- For Native Methods --------------- // C2dxのNativeから呼ばれるもの public static void createView(float yPos) { if(_iconAdLoader!=null) return; final float mYPos = yPos; mActivity.runOnUiThread(new Runnable() { @Override public void run() { DbgLogD(TAG, "createView:"+mYPos); _iconAdLoader = new NendAdIconLoader(mActivity, ICON_SPOT_ID, ICON_API_KEY); //一個一個追加していく for(int i=0; i<NEND_ICON_NUMS; i++) { //位置調整は手動 NendAdIconView iconView = mIconViewArray[i]; //temp obj pointer RelativeLayout.LayoutParams iconParam = new RelativeLayout.LayoutParams(WC, WC); iconParam.setMargins((int)mIconOffset+(int)(mIconMargin+mIconDispWid)*i, (int)mYPos, 0, 0); iconView.setLayoutParams(iconParam); _iconAdLayout.addView(iconView); _iconAdLoader.addIconView(iconView); } _iconAdLoader.loadAd(); } }); }
・アイコン位置変更
public static void locateView(float yPos) { if(_iconAdLoader==null) return; final float mYPos = yPos; mActivity.runOnUiThread(new Runnable() { @Override public void run() { DbgLogD(TAG, "locateView:"+mYPos); //一個一個変更 for(int i=0; i<NEND_ICON_NUMS; i++) { NendAdIconView iconView = mIconViewArray[i]; //temp obj pointer RelativeLayout.LayoutParams iconParam = new RelativeLayout.LayoutParams(WC, WC); iconParam.setMargins((int)mIconOffset+(int)(mIconMargin+mIconDispWid)*i, (int)mYPos, 0, 0); iconView.setLayoutParams(iconParam); } } }); }
・アイコン広告の表示・解放
VisibleをGONEでも良いかもしれないがなんとなく・・・
public static void releaseView() { if(_iconAdLoader==null) return; mActivity.runOnUiThread(new Runnable() { @Override public void run() { DbgLogD(TAG, "releaseView"); //IconView解放 _iconAdLayout.removeAllViews(); _iconAdLoader.pause(); _iconAdLoader = null; } }); }
C++コードから呼び出すためのJNIとC++ラッパー追加
cppファイルの中身は同じような物が長くなりそうなので割愛します・・・
下側のgithub内に全く同じコードがありますので、
興味がある方はご覧ください。
IconAdNative.h
ここで定義されているメソッドを他のコードから呼び出す。
namespace Cocos2dExt { class IconAdNative { public: static void createView(float yPos); static void locateView(float yPos); static void releaseView(); static void pauseView(); static void resumeView(); static void refreshView(); }; }
IconAdNative.cpp
完全にただのラッパー
namespace Cocos2dExt { void IconAdNative::createView(float yPos) { IconAdNative_createViewJNI(yPos); } void IconAdNative::locateView(float yPos) { IconAdNative_locateViewJNI(yPos); } void IconAdNative::releaseView() { IconAdNative_releaseViewJNI(); } void IconAdNative::pauseView() { IconAdNative_pauseViewJNI(); } void IconAdNative::resumeView() { IconAdNative_resumeViewJNI(); } void IconAdNative::refreshView() { IconAdNative_refreshViewJNI(); } }
IconAdNativeJni.h
extern "C" { extern void IconAdNative_createViewJNI(float yPos); extern void IconAdNative_locateViewJNI(float yPos); extern void IconAdNative_releaseViewJNI(); extern void IconAdNative_pauseViewJNI(); extern void IconAdNative_resumeViewJNI(); extern void IconAdNative_refreshViewJNI(); }
IconAdNativeJni.cpp
createのところだけ
void IconAdNative_createViewJNI(float yPos) { JniMethodInfo methodInfo; if (!getStaticMethodInfo(methodInfo, ADMANAGER_CLASS, "createView", "(F)V")) { return; } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (jfloat)yPos); methodInfo.env->DeleteLocalRef(methodInfo.classID); }
これで、”IconAdNative.h”をcppからincludeして、
Cocos2dExt::IconAdNative::createView(100);
と実行すると、上から100pixelの所からアイコン広告が表示される。
みたいなのが実現できます。
【アレンジ】
・消去前にアイコン位置を画面外に
なんかのバグで万が一アイコンが消えなかった事を考えて、
アイコン位置を画面外にずらしてから消去処理をすると、
万が一の時のユーザークレームを防げるかも
・表示前にアイコン位置を画面外に
広告表示まで、ロード時間がどうしてもかかるため、
表示するタイミングより早い段階で
アイコン位置を画面外にして「先読み」をしておく。
そして、実際の表示したいタイミングではアイコン位置をずらすだけ。
すると、ロード時間無く表示されているように見える。
サンプルコード
よくある使い方として、上記のコードを使った、
サンプルのゲームを作りました。
1〜5の何が出るか当てるだけの数当てゲームです。
超能力の調査みたいな感じで。
下のgithubからどうぞ。
MaxiGundan/TestGameNendIconAd · GitHub
ページ右メニューの”Download ZIP”から、一式ZIPでダウンロードできます。
組み込み手順、ビルド手順は、README.md(テキストファイル)に書いてありますので、
一つ一つ、実行してみて下さい!
以下のようなゲームができていればOK!(下はiOSのもの)
以上、つらつら書きましたが、我流ですので、
こうした方がいいよ!これダメだよ!っていうのがあれば、
教えて頂けると大変うれしいですm(_ _)m
ではでは。
ブログだけ見て帰るん?(´・ω・`)
↓いつでもフォローしてくれていいねんで?
twitter: @maxigundan
facebook: マキシぐんだん | Facebook
コメント