UIViewController と Cocos2d の両方を利用して実装してるアプリがあります。
具体的には、
AppDelegate にて下記のように切り替えて利用しています。
- (void)setDirector{ navController_ = [[UINavigationController alloc] initWithRootViewController:director_]; [navController_ setNavigationBarHidden:NO animated:YES]; [window_ setRootViewController:navController_]; } - (void)setUIView{ navController_ = [[UINavigationController alloc] initWithRootViewController:self.viewController]; [navController_ setNavigationBarHidden:NO animated:YES]; [window_ setRootViewController:navController_]; }
とある 1 画面でこのように利用するだけなら特に問題ないのですが、
2 画面(ある画面とある画面で利用目的は別)の場合、
うまく切り替えないと別の機能で利用していた画面が表示されてしまうことがあります。
簡単に言うと
UIView1 → Cocos2d1 → UIView2 → Cocos2d2
のように切り替えると、うまく切り替えないと Cocos2d2 が表示される瞬間に Cocos2d1 の画面が
一瞬表示されてしまいます。
これは、下記のように
[[CCDirector sharedDirector] replaceScene:[SampleLayer scene]]; [window_ setRootViewController:navController_];
シーンを呼び出して、CCDirector をセットしても、
シーンを呼び出した瞬間は レンダリングが停止していますので、呼び出す前のシーンが表示されままだからです。
そして、 CCDirector を呼び出した後にレンダリングが開始されますので一瞬前のシーンの残像が表示されるからです。
回避方法として、インスタンスを分けることも考えましたが、CCDirector はシングルトンなので、
2つのインスタンスにすることができません。
(頑張ればできます。)
ちなみに一瞬表示される理由ですが、CCDirector は、UIView が表示時(画面がCCDirectorでない時)
は レンダリング が停止します。
アプリの動きによっては非表示時も レンダリングが停止しない方が残像が残らないので、
好ましい場合もあります。
そこで今回は、この自動停止機能を削除してみました。
多分本当はオーバライドの方が好ましいのですが、少々アプリを改造しなくてはならなくなるため、
今回は、直接ソースを修正してしまいました。バージョンアップしたら、上書きされてしまいますね。
修正したソースは、CCDirectorIOS の 575行目あたり。
バージョンによって恐らく行数は違うと思いますのでそこは検索でお願いします。
Modify の上下でコメントアウトしました。
- (void) stopAnimation { if(!_isAnimating) return; CCLOG(@"cocos2d: animation stopped"); // Modify //#if CC_DIRECTOR_IOS_USE_BACKGROUND_THREAD // [_runningThread cancel]; // [_runningThread release]; // _runningThread = nil; //#endif // // [_displayLink invalidate]; // _displayLink = nil; // _isAnimating = NO; // Modify }
CCDirector が非表示になると、この stopAnimation が呼ばれるのですが、
この中で、負荷対策でスレッドを停止して、メモリを開放しています。
コメントアウトすることで、スレッドが動き続けますので、残像対策になります。
ただ、注意としては、CCDirector 以外のUIが表示されている時も
レンダリング処理が走りますので、CPU、メモリーの無駄になります。
もしどうしても残像にお困りの方がいらっしゃいましたら、お試し下さい。