GamingLoop
描画のテストコードを書いて遊んでみました.
描画コード自体は難しくなかったんですけど、簡単なアニメーションをやってたくなってメインループを作る段階になって
ちょっとはまったので、(先に)足跡を残しておくことにしてみました.
描画については、明日以降書く予定
概要
自前で画面にアニメーションをつけたり、そもそもゲームコンテンツを作ろうと思ったら、メインループが作れなければ始まらない.
そんなわけで、メインループの作り方を試してみることにした.
タイマー基礎
NSTimer を利用すると、指定秒数後に指定関数の呼び出しが行える.
初期化時に、次のようなコードを記述することで、1/60秒毎に呼び出される関数、すなわちゲームループを作成することができる
m_timerLoop = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 60.0f) target:self selector:@selector(onTick) userInfo:nil repeats:YES];
呼び出す関数は、次のように作成すればよい.
/// フレーム処理 - (void)onTick { m_count++; if( m_count > 1000 ){ m_count = 0; } [self setNeedsDisplay]; }
"[self setNeedsDisplay]" を利用して、描画矩形の再発行要求を行っているので、次にシステムが描画発行を行う
タイミングで、 drawRect が呼ばれる.
入力がなかったときのスリープに関して
加速度だけを入力とするようなゲームコンテンツの場合、タッチによる入力が起こらないため、システムのサスペンドや
バックライトの輝度が落ちる、(設定していれば)システムのロックなどが発生してしまい、ゲームの進行を妨げる恐れがある.
これを回避するためには、初期化時に以下の設定を行えばよい.
[UIApplication sharedApplication].idleTimerDisabled = YES;
注意点(ってかよくわからないこと)
デベロッパドキュメントで、NSTimer を検索してみると、コールバック関数のプロトタイプが次のように書かれている
- (void)myTimerFireMethod:(NSTimer*)theTimer
当然、上記例の onTick もこのフォーマットにあわせてプログラムを打ってみたんだけれども、何らかの例外が
発生してしまってうまく動かない.
Apple から公開されているサンプルコード "CrashLanding" を参照してみると、引数なしの "renderScene" という
関数を指定していることが分かったので、このような形でフレーム処理を書いてみた.
また、最初は "frame" という名前の関数を用意していたが、これだと UIView の frame プロパティと名前が
かぶってしまうため、わけの分からない例外が出てしまう.
...変な地雷を踏んでしまった...(ってか、コンパイラが起こってくれてもいいと思う)