0

私は、すべての敵が設定された間隔で移動するゲーム&ウオッチスタイルのゲーム(ドンキーコングを覚えていますか?)を作成しています。

例えば。ドンキーコングの樽は、正確に1秒ごとに1ステップ移動する可能性があります。プレーヤーは動きを予測し、ジャンプを計画する必要があるため、正確さは非常に重要です。

私はNSTimerを使用して、基本的にすべての敵を1ステップ前進させることを処理する関数を実行しています。これはうまく機能していましたが、時々、敵が一時的にフリーズし、ゲームが台無しになることに気づきました。NSTimerのドキュメントを読むと、これはNSTimerを操作するときとまったく同じように見えます。

私が試したこと:

私はもともとscheduledTimerWithTimeIntervalを使用していましたが、timerWithTimeIntervalを一緒に使用することを提案した別のスレッドを読みました

[[NSRunLoop currentRunLoop] addTimer:autoMoveTimer forMode:NSRunLoopCommonModes];

しかし、私はまだ凍結に気づきました。

タイマーを毎秒実行する代わりに、タイマーをもっと頻繁に実行してから、関数内で経過時間を確認します。

NSTimeInterval elapsedTimeInterval;
elapsedTimeInterval = [gameTickerLastRan timeIntervalSinceNow];

if(elapsedTimeInterval<-gameSpeed){

        NSLog(@"%f since ticker last ran",elapsedTimeInterval);

        gameTickerLastRan=[NSDate date];

//do stuff in function

}

しかし、出力されている経過時間は私にはかなり正確に見えたにもかかわらず、それでも私はフリーズに気づきました。

 -1.006408 since ticker last ran

 -1.006985 since ticker last ran

 -1.007313 since ticker last ran

 -1.007193 since ticker last ran

 -1.006768 since ticker last ran

 -1.007468 since ticker last ran

 -1.007429 since ticker last ran

 -1.006759 since ticker last ran

 -1.007435 since ticker last ran

その機能の終わりに、すべての敵がステップで動かされた後、私はグラフィックを強制的に更新しようとしました

[self performSelector:@selector(sweetNothings) withObject:nil afterDelay:0.0];

しかし、これは役に立ちませんでした。

タイマー専用のスレッドを簡単に作成してみましたが、試したものがうまくいかず、深みがありすぎて実験することができませんでした。

ストーリーボードには、フレームごとのアニメーションのようにレイアウトされた約100個のUIImageViewが含まれています。次に、hiddenプロパティを使用してこれらのオンとオフを切り替え、アニメーションを作成します。

この関数を正確な間隔で実行し、グラフィックのフリーズを回避するための堅実な方法を誰かが提案できますか?

編集:CADisplayLinkを試しましたが、まったく同じように見えます。つまり、約10秒ごとに1秒間フリーズします。これは私が持っているものです

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameTicker:)];

[displayLink setFrameInterval:1];

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

そしてゲームのティッカーで私は持っています

CFTimeInterval elapsedTime = displayLink.timestamp - lastDrawTime;
NSLog(@"elapsed %f", elapsedTime);
if(elapsedTime>=gameSpeed){
//do stuff
lastDrawTime = displayLink.timestamp;
}

編集2:まあ、私はそれがまったく遅れていないことに気付いたと言って恥ずかしいです。配列を前方にループしながら要素を削除していたため、ラグの錯覚が発生していました。とにかくCADisplayLinkを紹介していただきありがとうございます-とても便利に見えます。質問を削除する必要がありますか?

4

1 に答える 1

2

CADisplayLinkを見てください(これはCocos2dや他のゲームフレームワークが使用しているものです)。

于 2013-02-01T15:04:48.703 に答える