明滅するプログラマの思索

WEBエンジニアとして勤務している一介の男が、日々気づいたことをまとめるブログです

前回のバックグラウンド移行が特定の時間より前なら Scene 移動する

最近cocos2d-xをいじる機会が多いです。
アプリ開発は、国内ではUnity一択な風潮がありますが、2Dメインだとか、WebViewメインなアプリの場合、cocos2d-xで開発したほうが楽な場合も多いなと思います。
今回は、前回のバックグラウンド移行(アプリを起動したまま閉じる)が特定の時間より前だった場合、次回のフォアグラウンド移行(閉じたアプリを開く)で別の Scene に移動する場合のコードを書いてみたいと思います。

今回の記述では、午前5時を境に、それ以前にバックグラウンド移行し、それ以後にフォアグラウンド移行した場合、Title Scene に移動するよう記述します。

まずは、バックグラウンド移行時に、そのタイミングの時刻をデータ保存します。
AppDelegate.cpp の applicationDidEnterBackground() メソッドに記述をします。
time() を使用するため、time.h を include しておきましょう。

#include <time.h>

......

void AppDelegate::applicationDidEnterBackground()
{
  time_t btime = time(NULL);
  UserDefault::getInstance->setDoubleForKey("btime", btime);
}

これでバックグラウンド移行時に時刻をを保存できます。
time_t 型はUNIXタイムスタンプで、 long 型のエイリアスなので、setDoubleForKey() が使えます。

次にフォアグラウンド移行時の処理です。
同じように AppDelegate.cpp の applicationWillEnterForeground() メソッドを利用します。

void AppDelegate::applicationWillEnterForeground()
{
  time_t btime = UserDefault::getInstance()->getDoubleForKey("btime", -1);
  time_t now = time(NULL);
  struct tm* nowSt = std::localtime(&now);
  double diff;
  // btime が無い、もしくは現時刻が5時よりも前なら 差分を -1 とする
  if (btime == -1 || nowSt->tm_hour < 5) {
    diff = -1;
  } else {
    struct tm fiveSt = {0, 0, 5, nowSt->tm_mday, nowSt->tm_mon, nowSt->tm_year};
    time_t fiveDate = std::mktime(&fiveSt);
    diff = difftime(fiveDate, btime);
  }
  if (diff >= 0) {
    this->runAction(CallFunc::create([]() {
      auto scene = Title::createScene();
      Director::getInstance()->replaceScene(scene);
    }));
  }
}

applicationDidEnterBackground() コール時にデータ保存した過去の時間(UNIXタイムスタンプ)を取得し、現時刻および本日の午前5時ジャストの時刻を生成して比較します。
getDoubleForKey() の2つ目の引数は、データが存在しなかった場合に返却される値です。
比較は difftime() で行います。午前5時時点の time_t 型変数を生成するため、struct で午前5時のオブジェクトを作り、そこから mktime() を利用してタイムスタンプを獲得します。
diff の値が0以上なら、replaceScene() を行います。