-(void)update:(CFTimeInterval)currentTimeメソッドに於けるシステム時間の参考出力と考察

iPhoneゲームアプリのアニメーション表示

iPhoneアプリを開発するにあたって開発環境である Xcode は勿論、 アップル社からは様々な純正のフレームワークが無料で提供されています。 中にも SpriteKit なるフレームワークは2Dゲーム開発用に提供されているもので iPhone専用にネイティブでゲームを開発するにはとても便利で有用です。

処でゲーム開発には時間の処理が欠かせません。 キャラクターの移動をリアルタイム処理したり 一定時間毎にアイテムを出現させたりイベントを起動させたり様々な要請が考えられるでしょう。 手元の開発ゲーム うさ犬が行く などでも其の開発初期にはアニメーションの表示タイミングを測るのに覚束ない面がありました。 SpriteKitではルートのViewとして用意されるクラス SKScene には initWithSize メソッドが用意され通例此処にゲームの初期設定などを記述しますが 此処にアニメーション表示タイミングを記述すると基本的に一定時間の繰り返し処理となり柔軟性に欠けます。 ゲーム内で要求されるフレキシブルな時間処理を把握するための取っ掛かりとして システム時間をログに出力させてみようと考えました。

なおゲームアプリ うさ犬が行く はリリース時には開発言語に Swift を採用していますが本記事に記述する内容の実行時期、開発当初に於いては Objective-C で記述していたものです。

スポンサーリンク
日付:2014年4月11日
開発機:MacBook Air(11-inch, Mid 2013)
MacOSバージョン:OS X 10.9.2
Xcodeバージョン:5.1
言語:Objective-C
主関連アプリ:うさ犬が行く

SKScene の持つメソッドには update(_:) もありクラスのインスタンスが存在すれば随時実行される仕様となっていますので ゲームではリアルタイムの実行処理に用いたり タイムインターバルを取得して何某かの処理を実行させるのに用いたりします。 今回はupdateメソッドに於けるシステム時間の参考出力と考察を試みました。 SpriteKitフレームワークを用いたテンプレートを利用したプロジェクトを作成すれば GameSceneクラスには以下の如き記述が用意されているでしょう。

-(void)update:(CFTimeInterval)currentTime

updateメソッド内でのシステム時間についての調査、研究のために %2、%3、%5など剰余を用いた以下コードでcurrentTimeを出力してみます。

if ((int)currentTime % 3 == 0) {
  NSLog(@"TIME:%f", currentTime);
}

このコードを以て出力したログの一例から20行ほど表示させてみたものが以下になります。 2014年開発当時のプロジェクトネームは USAINU GOES でした。

2014-04-11 22:09:11.486 USAINU GOES[394:60b] TIME:144.014289
2014-04-11 22:09:11.518 USAINU GOES[394:60b] TIME:144.047261
2014-04-11 22:09:11.535 USAINU GOES[394:60b] TIME:144.063980
2014-04-11 22:09:11.552 USAINU GOES[394:60b] TIME:144.080398
2014-04-11 22:09:11.568 USAINU GOES[394:60b] TIME:144.096608
2014-04-11 22:09:11.585 USAINU GOES[394:60b] TIME:144.113605
2014-04-11 22:09:11.602 USAINU GOES[394:60b] TIME:144.130427
2014-04-11 22:09:11.618 USAINU GOES[394:60b] TIME:144.146931
2014-04-11 22:09:11.635 USAINU GOES[394:60b] TIME:144.164184
2014-04-11 22:09:11.652 USAINU GOES[394:60b] TIME:144.180886
2014-04-11 22:09:11.668 USAINU GOES[394:60b] TIME:144.196806
2014-04-11 22:09:11.685 USAINU GOES[394:60b] TIME:144.214285
2014-04-11 22:09:11.702 USAINU GOES[394:60b] TIME:144.230475
2014-04-11 22:09:11.718 USAINU GOES[394:60b] TIME:144.247201
2014-04-11 22:09:11.734 USAINU GOES[394:60b] TIME:144.263200
2014-04-11 22:09:11.752 USAINU GOES[394:60b] TIME:144.280628
2014-04-11 22:09:11.768 USAINU GOES[394:60b] TIME:144.296745
2014-04-11 22:09:11.785 USAINU GOES[394:60b] TIME:144.314245
2014-04-11 22:09:11.801 USAINU GOES[394:60b] TIME:144.330210
2014-04-11 22:09:11.819 USAINU GOES[394:60b] TIME:144.347425

此のログを見るとどうやらシステム時間とはMacBook AirでXcodeを用いた際は 通常の生活時間に合わせ最も右側に iOSシミュレータを起動してからのシステム時間を示している様です。 iOSシミュレータの文字通り端末のシミュレートをするにあたり時間も含まれているのだと思います。 単位は 10-6 のfloat値で出力されています。

このログに於いて最も右の TIME の項を追っていくと当該メソッドが0.1秒間に6回、 即ち1秒間に60回呼び出されているのが分かります。 恐らくはSpritekitはデフォルトで60fpsで画面が書き換えられる仕様となっていますから 其の度に此のメソッドが呼ばれるため1秒間に60回呼ばれているログが出力されるのだと思われます。 従って((int)currentTime % 3 == 0)で分岐させ 3秒に1回呼んでる積もりでいても実は的外れなコードであって実際には60回も呼んでいるので 例えば此のコードの考え方のタイミングでアニメを呼び出そうものなら 呼び出されたアニメが大量に連続して描画されるといった結果が招枯れてしまうでしょう。

iPhoneゲームアプリのアニメーション表示のタイミング

しかしまたログの左側の時刻の通常表示の項の表示を見てみると TIMEと比較して時間あたりの呼び出し回数が少ないように見受けられます。 1秒間に60回は呼ばれずに40回程度となっているようです。 此れは特にiOSシミュレータは負荷の掛かる処理ですので 実行機器に因っては処理能力等に起因するコマ落ちがあるのではないかとも考えられます。 本記事のログ出力にはMacBook Air 2013というモバイル用に特化された比較的非力なマシンで此れを実行しており 招かれた事態であると考えられます。

処理落ちが処理落ちとして判然とする場合には問題ありませんが 状況によっては招かれた遅延が体感と整合性が取れてしまうので問題です。 実際iOSシミュレータで問題なく実行されているように見えても iPhone実機で走らせると無限増殖アニメであるかのような事態が発生するでしょうので注意が必要でしょう。

以上updateを用いた場合端末毎に単位時間が異なり異なる可能性があるかも知れません。 従って時間を競うなどのゲームに重要な事項の判定にupdateメソッドを使用するのは問題が有る可能性があります。 またupdateメソッドを精確なリアルの生活での時間の基準に使うには問題が有り ゲームに限らず其のような生活に密着したアプリで精確な時間の必要な際には デバイス本体の時間と時々同期を取るなどの処理を導入するようにしようと考えています。 ただiPhoneの性能が向上し60fps程度のフレーム書き換えでは 一般的なゲームに於いて問題はないと思われますので開発ゲームアプリ うさ犬が行く ではゲーム進行の中心にはupdateメソッドを用いてはいます。

Going USAINU(邦題: うさ犬が行く)
無料:カテゴリ: ゲーム: 4+ 評価
バージョン: 3.21
リリース: 2015年9月14日
更新: 2022年3月7日
サイズ : 19.7 MB
互換性: iOS 14.4 以降のiPhone、iPod touch に対応。および、macOS 11.0以降とApple M1 チップを搭載したMac に対応。