Zero4Racer PRO で、AdMob を実装しているのですが、広告の種類によっては、App Store を開くものや、アプリ内でWEBを開いて動かすものなどがあります。cocos2dは、全画面のUIView項目を開く際に、アニメーションの停止と開始を行う必要があるため、正しく停止、開始を行ってあげないと、アプリが落ちることになります。
NSAssert( displayLink == nil, @”displayLink must be nil. Calling startAnimation twice?”);
これを防ぐ方法のヒントが、cocos2d forumにありました。
CCVideoPlayer — calling startAnimation twice? « cocos2d for iPhone
ので、それを元に、サンプルプロジェクトを作成して、githubに公開しました。
作成した GitHub のページです。
tomohisa/cocos2dWithAdMob – GitHub
問題の原因は、
[cc lang=”objc”]
[[CCDirector sharedDirector] stopAnimation];
[[CCDirector sharedDirector] startAnimation];
[/cc]
この2行のコードがセットで呼ばれずに、
[cc lang=”objc”]
[[CCDirector sharedDirector] stopAnimation];
[[CCDirector sharedDirector] startAnimation];
[[CCDirector sharedDirector] startAnimation];
[/cc]
のように、startAnimationが連続で呼ばれてしまうことによって生じます。
この原因としては、AdMobの広告の種類に、
- アプリ内でウィンドウを表示する広告
- AppStoreなど、別のアプリを表示する広告
の2種類あり、アプリ内でウィンドウを表示する広告には、さらに、Safariなどの外部アプリを呼び出すものがあります。その場合、
[cc lang=”objc”]
// AdMobのアプリ内広告を呼ぶ時
– (void)adViewWillPresentScreen:(GADBannerView *)adView {
[[CCDirector sharedDirector] stopAnimation];
}
// AdMobのアプリ内広告から別アプリに飛んだ時
-(void) applicationDidEnterBackground:(UIApplication*)application {
[[CCDirector sharedDirector] stopAnimation];
}
// 別アプリから戻って来てAdMobのアプリ内広告表示に戻る時
-(void) applicationWillEnterForeground:(UIApplication*)application {
[[CCDirector sharedDirector] startAnimation];
}
// AdMobのアプリ内広告表示を閉じるボタンを押したとき
– (void)adViewWillDismissScreen:(GADBannerView *)adView {
[[CCDirector sharedDirector] startAnimation];
}
[/cc]
このような順番で呼ばれて、startAnimationが連続で呼ばれてしまいます。
これでは困るので、isStopAnimationという変数を作成して、アニメーション停止中かを確認するようにしたら、問題なくなりました。
[cc lang=”objc”]
// AdMobのアプリ内広告を呼ぶ時
– (void)adViewWillPresentScreen:(GADBannerView *)adView {
[[CCDirector sharedDirector] stopAnimation];
isStopAnimation = YES;
}
// AdMobのアプリ内広告から別アプリに飛んだ時
-(void) applicationDidEnterBackground:(UIApplication*)application {
[[CCDirector sharedDirector] stopAnimation];
}
// 別アプリから戻って来てAdMobのアプリ内広告表示に戻る時
-(void) applicationWillEnterForeground:(UIApplication*)application {
if (!isStopAnimation) {
//if ad view is showing, don’t start animation yet.
[[CCDirector sharedDirector] startAnimation];
}
}
// AdMobのアプリ内広告表示を閉じるボタンを押したとき
– (void)adViewWillDismissScreen:(GADBannerView *)adView {
if (isStopAnimation) {
[[CCDirector sharedDirector] startAnimation];
isStopAnimation = NO;
}
}
[/cc]
このように、iOS4以降、マルチタスクによって、いろいろ便利になりましたが、その分デバッグも必要になりますね。
このバグを修正した、Zero4Racer Pro 2.0.4 は、サブミットから、約12時間の超速リリースでした。
Zero4Racer PRO for iPhone 3GS, iPhone 4, iPod touch (2nd generation), iPod touch (3rd generation), iPod touch (4th generation) and iPad on the iTunes App Store