ゲーム開発に時間の処理が欠かせぬものとしてiPhoneアプリ内で 時間は如何様に扱われるのかの検証記事として本ブログに2017年2月19日に配信したのが -(void)update:(CFTimeInterval)currentTimeメソッドに於けるシステム時間の参考出力と考察 でしたが此のメソッドは任意の単位時間毎にコールバックメソッドを呼び出すにも応用が効きます。 其の様な応用を用いればこそ此のメソッド及び呼び出されるコールバックメソッドにて キャラクターのリアルタイム移動、 アイテムの一定時間毎の出現、 イベント起動、 等のゲームならではの機能を実現せしめ得ます。
関してはiPhone及びiOSゲームアプリ開発のチュートリアルサイト RAYWENDERLICH TUTORIALS FOR DEVELOPERS & GAMERS では以前日本語で有益な情報を提供してくれていましたが今は当該記事は残念ながら削除されている様です。 但し英語版が当時のObjective-Cでのコード記述から装いも新たにSwiftのコード記述に変えて 現在でも用意されていますので下にリンクを貼り置きます。
SpriteKit Swift 3 Tutorial for BeginnersまたObjective-Cでの記述もアーカイブされているので其方も下にリンクを貼り置きましょう。 本記事に記載されるコードは単位時間毎の処理を実装した当時 2014年4月12日の試行錯誤に習い最後のコードを除き基本的には以下のページから引用するものです。
開発機:MacBook Air(11-inch, Mid 2013)
MacOSバージョン:OS X 10.9.2
Xcodeバージョン:5.1
言語:Objective-C
主関連アプリ:うさ犬が行く
さて当時同サイトでは日本語でアップル社謹製のゲーム用フレームワーク Sprite Kit には此のフレームワーク登場以前の2Dゲーム用フレームワークの標準たる Cocos2D に用意される任意の単位時間毎のアップデートをコールバックする機能が用意されていないが 少々コードに細工すれば同じ効果を齎らし得ると記述されていました。 応用すれば最後のアップデート処理からの差異時間をも取得出来る旨も紹介されていました。 現在の英語版アーカイブでも同様ですがゲーム開発の為のコードの参考例として好適な モンスターのスポーンを用いていますのでゲーム開発を志す向きには分かり易いものでしょう。
先ずは前回のモンスターのスポーン時間プロパティを lastSpawnTimeInterval と決め、前回のアップデート処理からの時間プロパティを lastUpdateTimeInterval と決めSpriteKitのView足るSceneのヘッダに以下引用の如く追加します。
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
然る後前回のアップデートからの任意時間毎にコールバックするメソッドを追加する様記述されます。 其れが以下に引用するコードです。 任意の単位時間は1秒に設定されています。
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 1) {
self.lastSpawnTimeInterval = 0;
[self addMonster];
}
}
モンスターを追加するメソッドは addMonster と命名されていますので 前回のアップデートからの時間をリセットし 1秒毎にモンスターを追加するメソッドとなるものであるのが分かり易くあります。 勿論当該メソッドはSpriteKit内で標準でコールされるものではありませんので 此れをコールする為にSpriteKit内で自動的にコールされる update メソッド内に然るべく記述する様に記述されます。 コードを以下に引用します
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
コード内のコメントには アプリの負荷が上がって処理能力が標準の60fpsより落ちても同じ単位時間で処理する旨が記されます。 具体的には前回のアップデート処理からの時間が1秒を超えていれば指定したメソッドがコールバックされる様仕組まれています。 此のコードはアップル社のAdventureアプリのサンプルコードから引用したコードであるとされています。 基本的な内容としては現在の時間足る currentTime と前回のアップデート処理からの時間の差異で目論みの機能を齎らしているものです。 此の時予期せぬ事態を回避する為に60分の1秒でリセットするインターバルをチェックしてもいる旨も説明されています。 而して任意の単位時間毎の処理は実現されるのでした。
現在では英語版でしか情報は見られない様ですが インディー系ゲーム開発者に取っては実に有用な内容ですので RAYWENDERLICH TUTORIALS FOR DEVELOPERS & GAMERS の内容は参照に値するものと思います。
併せて 水島企画 の2013年11月11日の記事の様な実装も有りますので 以下にリンクを貼り置き紹介して置きましょう。
おせんべ焼けた?焼く時間に仍ってお煎餅の仕上がりが異なって来るので 程良い焼き上がり時間で美味しいお煎餅を焼き上げましょう、 と言うゲームです。 以下にコードの骨格と思しき記述を手前勝手に解釈し記し置きます。
@property NSTimeInterval startTime;
@property NSUInteger state;
@end
---
typedef enum {
GameStateReady = 1,
GameStateStart = 2,
GameStateWaiting = 3,
GameStateStop = 4,
GameStateFinish = 5
} GameState;
---
- (void)update:(NSTimeInterval)currentTime {
if (self.state == GameStateStart) {
self.state = GameStateWaiting;
self.startTime = currentTime;
}
float duration = currentTime - self.startTime;
if (self.state == GameStateStop) {
if (duration < 2.0) {
// NONE
} else if (duration > 3.0) {
// Bad
} else {
//
}
}
}
バージョン: 3.21
リリース: 2015年9月14日
更新: 2022年3月7日
サイズ : 19.7 MB
互換性: iOS 14.4 以降のiPhone、iPod touch に対応。および、macOS 11.0以降とApple M1 チップを搭載したMac に対応。
1件のコメント
コメントは受け付けていません。