cocos2dxで、「放置系」のゲームを作るにはどのように実装をすればいいのか、の第3回目です。
今回は、下記項目の3番目を勉強していきたいと思います。
- 同じCCScene、もしくはCCLayer上の時間の管理
- 別のCCScene、もしくはCCLayer上の時間の管理
- バックグラウンドに移動した時、またバックグラウンドから復帰した時の時間の管理
- アプリを停止した時、アプリを立ち上げた時の時間の管理
前回
【cocos2dx】放置ゲームを作る際の時間の管理-part1 | albatrus.com【cocos2dx】放置ゲームを作る際の時間の管理-part2 | albatrus.com
バックグラウンドに移動した時、またバックグラウンドから復帰した時の時間の管理
アプリは画面に表示されていないが、アプリ起動は起動している。このような状態が「バックグラウンド」です。
ホームボタンを2度押しすれば、バックグラウンド内のアプリを見れます。
バックグラウンドでの時間の管理
バックグラウンドでは、アプリは起動していますが、ルート(Update)などは動いていません。そこで利用するのが以下の2つです。
- AppDelgateのapplicationDidEnterBackground()とapplicationWillEnterForeground()
- (int)time(NULL)
AppDelgateのapplicationDidEnterBackground()とapplicationWillEnterForeground()
「バックグラウンドにアプリが移動した」、また「バックグラウンドからアプリが復帰した」を取得するメソッドががAppDelegateクラスに用意されています。- applicationDidEnterBackground() : バックグラウンドに移動
- applicationWillEnterForeground() : バックグラウンドから復帰
このメソッドを利用して時間の管理をします。
(int)time(NULL)
これに関しては、もっと違ういい方法があるのかもしれませんが、私はこれを利用しました。この時間関数を使えば、int型の秒数を取得できます。
バックグラウンドでは、先ほと述べたようにルート(Update)で、時間の計算ができません。
(int)time(NULL)を使って、「バックグラウンドに移動した秒数」と「バックグラウンドから復帰した時の秒数」を取得します。
後は、この差分を計算してあげればバックグラウンドでの時間の経過が計算できます。
実装
考え方がわかれば、実装はそんなに難しくありません。考えられる実装パターンは2つです。
- バックグラウンド移動->バックグラウンドから復帰
- 別のCCSceneに移動->バックグラウンドに移動->バックグラウンドから復帰->もとのCCSceneに復帰
バックグラウンド移動->バックグラウンドから復帰
まずは、時間を計算しているCCScene・CCLayerから、バックグラウンドに移動した時の実装です。これは、先ほどのメソッドを利用して時間を計算するだけで大丈夫です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void AppDelegate::applicationDidEnterBackground(){ int saveTime = (int)time(NULL); //バックグラウンドに移動した時間を記録 CCUserDefault *userDefalt = CCUserDefault::sharedUserDefault(); userDefalt->setIntegerForKey("saveTime", saveTime); userDefalt ->flush(); CCLOG("AppDelegate バックグラウンドに移動"); CCDirector::sharedDirector()->stopAnimation(); } void AppDelegate::applicationWillEnterForeground(){ int nowTime = (int)time(NULL); CCUserDefault *userDefalt = CCUserDefault::sharedUserDefault(); int saveTime = userDefalt->getIntegerForKey("saveTime"); //差分を計算 int passageTime = nowTime - saveTime; CCLOG("AppDelegate バックグラウンドから復帰"); CCDirector::sharedDirector()->startAnimation(); } |
別のCCSceneに移動->バックグラウンドに移動->バックグラウンドから復帰->もとのCCSceneに復帰
時間を管理していないCCSceneで、バックグラウンドに移動した時に時間の管理をどうしたらよいのでしょうか?これは、前回説明したモノと今回のバックグラウンドへの移動を組み合わせれば実装ができます。
コードに関しては特に新しいことをしなくてもいけます。
1 2 3 4 5 6 7 8 9 10 |
CCUserDefault *userDefalt = CCUserDefault::sharedUserDefault(); //別のSceneでの時間の経過 int addTime = userDefalt->;getIntegerForKey("addtime"); //バックグラウンドでの時間の経過 int saveTime = userDefalt->;getIntegerForKey("saveTime"); time = time + addTime + saveTime; |
最後に
ソーシャルゲームや放置系ゲームでよく見かける「ログインボーナス」は「曜日毎のイベント」などは、先ほどの時間関数を使っていると実装ができそうだと、今思っています。このような考え方で実装をしていますが、もっと良い方法があれば、やり方募集しています。
