cocos2d-x + Adstir 広告の表示/非表示を試してみた

cocos2dで作ったアプリにAdStirを組み込んでみた - おかひろの雑記ではCocos2dのアプリにAdstirを組み込んでみましたが、今回はcocos2d-xのアプリに組み込み、iOSAndroid両方で広告を出してみました。

アプリ起動時に広告を表示して常時表示するのであればそんなに難しくないと思いますが、ちょうど作っているアプリで、タイトル画面では広告表示、ゲームプレイ中は非表示、リザルト画面で表示・・・ということをやりたかったので、チャレンジしてみました。
SceneやLayerの切替時、ボタンタップ時など任意のタイミングで広告の表示/非表示を切り替えられます。

自分なりに試してみた結果です。
間違いなどありましたら、ご指摘いただけたら嬉しいです。

今回使用したバージョン

準備
iOSAndroidそれぞれでライブラリの追加などが必要です。
http://wiki.ad-stir.com/IPhone_SDK%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9
http://wiki.ad-stir.com/Android_SDK%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9

実装
cocos2d-xのソース上からは次の制御をできるようにします。

  • 広告の表示
  • 広告非表示
  • 次の広告に切り替え

NativeCodeLauncherについてはCocos2d-x上からObjective-C/Javaのコードを実行する - おかひろの雑記を見てください。

iOS
iOSでの広告制御はRootViewControllerクラスに実装しました。

RootViewController.h

#import <AdStir/ASTAdView.h>
#import <AdStir/ASTDelegateProtocol.h>


@interface RootViewController : UIViewController<ASTDelegateProtocol> {

}

// Adstir
-(void)startAd;
-(void)stopAd;
-(void)nextAd;

@end

RootViewController.mm

...

@interface RootViewController()<ASTDelegateProtocol>
@property (nonatomic,retain) ASTAdView* adview;
@end

...

// 広告表示
-(void)startAd
{
	if(!self.adview)
	{
		self.adview = [ASTAdView requestWithAppId:@"MEDIA-XXXXXXXX" andSpotNo:@"X" andDelegate:self];
		[self.view addSubview:self.adview];
		
		// 画面下に表示
		CGRect winSize = [[UIScreen mainScreen] bounds];
		CGRect adviewRect = CGRectMake(0, winSize.size.height - 50, winSize.size.width, 50);
		self.adview.frame = adviewRect;
		
		[self.adview start];
	}
	else
	{
		NSLog(@"Ad already started.");
	}
}

// 広告非表示
-(void)stopAd
{
	if(self.adview)
	{
		[self.adview stop];
		[self.adview removeFromSuperview];
		self.adview = nil;
	}
	else
	{
		NSLog(@"Ad already stopped.");
	}
}

// 次の広告を表示
-(void)nextAd
{
	[self.adview nextAd];
}

...

// ASTDelegateProtocol

- (void) didFailToInitView:(NSString *)appId{
	[self.adview stop];
	[self.adview removeFromSuperview];
	self.adview = nil;
}

- (UIViewController *) currentViewController{
	return self;
}

- (void) didFailToUpdateConfig{
	NSLog(@"didFailToUpdateConfig!");
}

- (void) didLoadAdView{
	NSLog(@"didLoadAdView!");
}
- (void) didFailToLoadAdView{
	NSLog(@"didFailToLoadAdView!");
	
	[self.adview nextAd];
}

- (CGPoint) originOfAdView{
	return CGPointMake(0, 0);
}
// テスト版を表示するかどうか
-(BOOL)astTestMode
{
#ifdef DEBUG
	return YES;
#else
	return NO;
#endif
}

AdViewの生成と破棄をしています。


Android
Androidの方は自動生成されたアクティビティクラスに実装しました。

OkahiroCocos2dX.java

	private static Activity me = null;
	private static AdstirView adstirView = null;
	
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		me = this;
	}

...

    public static void startAd()
    {
    	me.runOnUiThread(new Runnable(){
    		public void run()
    		{
    			if(adstirView == null)
    			{
	    			adstirView = new AdstirView(me, "MEDIA-XXXXXXXX", 1);
	    			
	    			RelativeLayout relativeLayout = new RelativeLayout(me);
	    			me.addContentView(relativeLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
	    																						ViewGroup.LayoutParams.WRAP_CONTENT));
	    	    	
	    			RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
	    																						ViewGroup.LayoutParams.WRAP_CONTENT);
	    			layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
	    	    	relativeLayout.addView(adstirView, layoutParams);
    			}
    		}
    	});
    }
    public static void stopAd()
    {
    	me.runOnUiThread(new Runnable(){
    		public void run()
    		{
    			if(adstirView != null)
    			{
	    			adstirView.stop();
	    			AdstirTerminate.init(me);
	    			adstirView = null;
    			}
    		}
    	});
    	
    }
    public static void nextAd()
    {
    	if(adstirView != null)
    	{
    		adstirView.start();
    	}
    }

NativeCodeLauncher
cocos2d-xから呼び出すメソッドを実装します。

NativeCodeLauncher.h

namespace Cocos2dExt {
    class NativeCodeLauncher
    {
    public:
		static void startAd();
		static void stopAd();
		static void nextAd();
    };
}

NativeCodeLauncher.mm

static void static_startAd()
{
	[NativeCodeLauncher startAd];
}
static void static_stopAd()
{
	[NativeCodeLauncher stopAd];
}
static void static_nextAd()
{
	[NativeCodeLauncher nextAd];
}

namespace Cocos2dExt
{
	void NativeCodeLauncher::startAd()
	{
		static_startAd();
	}
	void NativeCodeLauncher::stopAd()
	{
		static_stopAd();
	}
	void NativeCodeLauncher::nextAd()
	{
		static_nextAd();
	}
}

NativeCodeLauncher_objc.h

@interface NativeCodeLauncher : NSObject

+(void)startAd;
+(void)stopAd;
+(void)nextAd;

@end

NativeCodeLauncher_objc.m

@implementation NativeCodeLauncher

+(void)startAd
{
	AppController *appController = (AppController *)[UIApplication sharedApplication].delegate;
	[appController.viewController startAd];
}
+(void)stopAd
{
	AppController *appController = (AppController *)[UIApplication sharedApplication].delegate;
	[appController.viewController stopAd];
}
+(void)nextAd
{
	AppController *appController = (AppController *)[UIApplication sharedApplication].delegate;
	[appController.viewController nextAd];
}

@end

NativeCodeLauncher.cpp

namespace Cocos2dExt
{
	void NativeCodeLauncher::startAd()
	{
		startAdJNI();
	}
	void NativeCodeLauncher::stopAd()
	{
		stopAdJNI();
	}
	void NativeCodeLauncher::nextAd()
	{
		nextAdJNI();
	}
}

NativeCodeLauncherJni.h

extern "C"
{
	extern void startAdJNI();
	extern void stopAdJNI();
	extern void nextAdJNI();
}

NativeCodeLauncherJni.cpp

...

//#define  CLASS_NAME "org/cocos2dx/lib/Cocos2dxActivity"
#define CLASS_NAME "jp/milt/okahiro/OkahiroCocos2dX"

...

extern "C"
{

...

	void startAdJNI()
	{
		JniMethodInfo methodInfo;
        
        if (!getStaticMethodInfo(methodInfo, "startAd", "()V"))
        {
            return;
        }
        
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
	void stopAdJNI()
	{
		JniMethodInfo methodInfo;
        
        if (!getStaticMethodInfo(methodInfo, "stopAd", "()V"))
        {
            return;
        }
        
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
	void nextAdJNI()
	{
		JniMethodInfo methodInfo;
        
        if (!getStaticMethodInfo(methodInfo, "nextAd", "()V"))
        {
            return;
        }
        
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
}

呼び出し
Cocos2d-Xのコードから呼び出す場合はそれぞれ1行でOKです。

// 広告表示
Cocos2dExt::NativeCodeLauncher::startAd();
// 広告非表示
Cocos2dExt::NativeCodeLauncher::stopAd();
// 次の広告に切り替え
Cocos2dExt::NativeCodeLauncher::nextAd();