2017-04-09 37 views
4

私は自分のゲームに何を使用するのが好きですか?タイマー:ゲームを実行するためのタイマーとアップデートの使用SpriteKit

let goodFPS = SKAction.wait(forDuration: 0.01666) 
let mainGameRunner = SKAction.run { 
//my code is here 
} 
let toRepeat = SKAction.repeatForever(SKAction.sequence([goodFPS,mainGameRunner])) 
inGameHighScore.run(toRepeat,withKey:"mainGame") 

または更新機能:

override func update(_ currentTime: TimeInterval){ 
//my code is here 
} 

より速く、より一貫性の更新プログラムを提供して?

注:私のフレームレートは、私はSKActionのタイミング施設はupdateを呼び出している同じゲームループに基づいていることをかなり確信している45

+0

私は 'update'関数が' SKScene'にあると思いますか?それを使用してください。 – EmilioPelaez

+0

@EmilioPelaez速いスピードか同じスピードがありますが、一定のペースで走っています – joshLor

+0

私は適切な答えを追加しました。 – EmilioPelaez

答えて

1

私は答えを完全に書き直して明確にすることに決めました。

まず、FPSの問題を間違った方向に向けると思います。あなたがデバイスが与えることができるよりも速いフレームレートを "強制"することはできません。すべてのフレームが一貫していると仮定してゲームの動きを基準にしている場合は、間違っています。 CPUが非常に遅く、ある世代から新しい世代への違いが最初はあまりにも悪くなかったので、それは実際に彼らがどのように初期の段階で行ったかです。若いハードウェアで古いDOSゲームを走らせるのは、フレームレートが非常に高く、ゲームメカニック全体が不安定になったり、プレイするには速すぎたりするので、難しいでしょう。

ここでのコンセプトは、「時間をかけて」考えることと、2つのフレーム間に経過した時間に関連して任意の動作を縮小することです。

update()メソッドは、すべてのフレームで現在のシステムクロック状態を提供することで、この機会を提供します。最後のフレームの時間を記録することで、現在のフレームとの時間差を計算し、その差を使って現在のフレームを縮小することができます。

タイマーを使用して一貫したフレームレートでアップデートを取得することはお勧めしません。一定の時間間隔で更新クロージャを呼び出すかもしれませんが、クロージャ内のコードは単独で実行する時間がかかっており、ゲームロジックによっては実行時間が異なることさえあります。したがって、一時停止のタイミングは一貫しているかもしれませんが、一時停止前後のコードは一貫していない可能性があります。それでは、低速のCPUでゲームを動かすとどうなりますか?コードの速度がさらに変わり、タイミングが不正確になります。

あなたのゲームループにSKActionを使用しないことに対するもう1つの点は、単純にそれらが何であるかです。アクションはメモリ内のオブジェクトであり、複数のオブジェクトによって再利用されます。例えば「ジャンプ」アクションを行っている場合は、そのアクションをどこかに保存し、ノードが何であっても「ジャンプする」必要があるたびに同じオブジェクトを再利用することをお勧めします。ゲームループはフレームごとに実行されますが、異なるオブジェクトでは実行されません。アクションも使い捨てです。それが実行中であってもアクションを殺すことができるという意味です。あなたのゲームループをアクションに入れたら、おそらくSKSceneによって実行されます。あなたのシーンで別のアクションを使用する場合は、直ちにパズルになります。これは、アクションを削除するだけでなく、すべてのアクションを削除するか、識別子キーを使用してアクションを作成し、そのキーを使用してアクションを削除するその鍵ですでに表示されていない場合は、シーンによって実行されるすべてのアクションに識別子を付け、それらを1つずつ削除するように強制します。そして再び彼らはあなたのゲームループを取り除くミスのためにドアを開いたままにしておきます。その後、あなたのアクションが最初に1フレームごとに実行される保証はありません。

なぜupdate()メソッドを使用しますか?あなたのシーンに組み込まれているからです。何であれ、毎フレーム、update()が最初に呼び出されます。その後、アクションが実行されます。できるだけアクションのようにupdate()メソッドを誤ってフラッシュすることはできません。アクションのようにクロージャー内のオブジェクトを参照しているため、メモリリークを引き起こす強い/弱い関係には注意する必要はありません。推奨

を読み取ります

  1. SKAction API reference:あなたは明らかにこれらのポイントを逃しました。
  2. SKScene API reference:spritekitのフレーム処理について読んでください。それは、どのようにすべてのフレームにすべてをまとめているかを理解するのに役立ちます。

私はそれが物事をより明確にすることを望む。

1

〜58の範囲です。

SKActionの利点は、それが火災であり、あなたを忘れることです。updateを使用すると、タイマー変数を設定してチェックするのが難しくなります。

+0

私はアウトをテストしているし、どちらも素晴らしいとは思わない – joshLor

1

私はSpriteKitで多大な経験はありませんが、iOSでゲームやアニメーションを作った経験があります。

というクラスがあり、スクリーンが更新されるたびにデリゲートへの呼び出しが発生します。これはゲームやアニメーションのいずれかで画面を更新するのに最適ですすべてのフレームと呼ばれ、それ以上はありません。

SpriteKitがそのクラスを使用してupdateメソッドを起動するかどうかはわかりませんが、似たようなものが使用されていると思います。これは通常、実行ループと呼ばれます。

SKActionsこの実行ループの最上部で実行されます。

waitアクションを使用して独自の実行ループを作成すると、利点が得られないだけでなく、ロジックの実行方法に不一致が生じることがあります。

あなたの待機動作を0.01秒に設定したとします(わかりやすくするために丸めました)。画面が期待どおりに速くリフレッシュされ、アクションが0.009秒ごとに更新された場合は、最初にチェックされ、waitコマンドに残りの0.001秒があるため起動しないので、もう1回0.009秒が経過しますコードはの代わりに0.018秒後に実行されます。それだけでなく、2つのフレームが実行の間に渡されます。

update関数を使用すると、ロジックが画面のリフレッシュごとに1回実行され、それ以上は実行されないことがわかります。

+0

こんにちはEmilio - これは私が知りたいことです! CADisplayLinkはSpriteKitのUpdateとちょうど同じですか? – Fattie

+0

@Fattieそれは言うのが難しいですが、私はそれがおそらく同じメカニズムだと言います。私は 'update()'の上にカスタム 'CADisplayLink'を使用しません。 – EmilioPelaez

関連する問題