2017-01-02 9 views
0

私はMonoGameで始める初心者プログラマーです。私はアニメーションを実行するためのコードを実装していましたが、解決方法がわからない問題が発生しました。この私がAnimationManagerクラスで使用されるコードです:アニメーションフレームレートvsゲームfps

public void Update(GameTime gameTime) 
{ 
    timeElapsed += (float)gameTime.ElapsedGameTime.TotalSeconds; 

    if (timeElapsed > timeToUpdate) 
    { 
     timeElapsed -= timeToUpdate; 
     //Tried to just reset timeElapsed to zero, still doesn't work 
     //timeElapsed = 0; 
     if (frameIndex < rectangles.Count -1) 
     { 
      frameIndex++; 
     } 
     else if (isLooping) 
     { 
      frameIndex = 0; 
     } 
    } 
} 

問題は、私は、毎秒24のフレームでアニメーションとゲームが60または30 fpsで、それぞれの更新コードをチェック上で実行されるときであることは、描画する時間ですアニメーションの新しいフレームでは、毎秒24枚の画像を均等に描画しようとしたため、フレームの残りの部分が得られます。 6フレームの残りの部分があります。この結果、約6フレームのアニメーションが2回描かれ、一部はスキップされ、アニメーション全体が約25%長くなります。これを修正する方法はありますか?このコードをDrawコールに移動し、60 fpsゲームで48 fpsで描画コールをキャップすることで、各アニメーションフレームが2回目の描画コールごとに描画されるようにすることはできますか?それが合理的な解決策であれば、私はこれをどうやって進めるのか分かりません。

VSyncはこのすべてにどのように影響しますか?この問題が解決されたとしても、アニメーションフレームが乱れますか?

編集:それは2dゲーム、手描きのアニメーションと言うことを忘れました。

+0

おそらく、アニメーションフレーム(線形補間が十分であるかもしれない)の間にいくつかの補間を行うことになっているはずです。そうすれば、異なるフレームレートは問題にならないはずです(まだいくつかの問題が存在します) – UnholySheep

+0

私は今、それについて読んでいます。それは2dにappliableですか? – david0009

+0

私は毎秒24フレーム対30のあなたの説明を理解しているか分からない。アニメーションは、おそらくあなたの更新コードがやっているように見えるいくつかの経過時間の後にスプライトを交換するという観点から描画されるべきです。あなたは説明が深すぎるので、問題が何ではないかと考えていますが、問題は何ではありません。おそらく、あなたはその質問を言い換えて、より一般的に実際の行動と望ましい行動が何であるかを説明することができますか? –

答えて

0

これはよくわかっている問題です。彼らが互いに独立していないので、30ゲームのfpsで24のアニメーションfpsを詰まらせることは不可能です。この問題を解決するには補間法が唯一の方法です。これは、60Hzモニタで24fpsの映画を見るときに実行されるのと同じことです。

https://en.wikipedia.org/wiki/Three-two_pull_down

1

一般的に、このようなことをしているときは、VSyncやゲームが60または30 fpsで動作することを心配する必要はありません。それはまったく無関係です。

重要なことは、アニメーションの1秒あたりのフレーム数と、1つのゲームフレームにかかる時間を知っていることです。

これから、のアニメーションフレームで時間の長さを計算できます。たとえば、次のような結果に終わるとします。

var animationFrameTime = 1f/24f; // 24 frames per second 

これまでのところとても良いです。

次は、どこかで時間を累積することです。これについて考える方法はいくつかあります。私はの点で次のフレームまでどれくらいの時間が残っているか考えてみたい。

var gameFrameTime = (float)gameTime.ElapsedGameTime.TotalSeconds; 
timeUntilNextFrame -= gameFrameTime; 

フレームタイムを使い果たしたときには、frameIndexを増やす必要があります。

if(timeUntilNextFrame <= 0) 
{ 
    frameIndex++; 
    timeUntilNextFrame += animationFrameTime; 
} 

重要なビットがここにあります。私はを追加しました。animationFrameTimetimeUntilNextFrameに追加しました。この方法で、前のフレームからの時間が残っている場合は、次のフレームに追加され、アニメーションが滑らかに保たれます。

それ以上のことはありません。私はrectangles.CountビットとisLoopingビットを除外しましたが、それらを追加するだけで十分です。また、最初のフレームについてtimeUntilNextFrameanimationFrameTimeを初期化することもできます。

何らかの理由でゲームがゆっくり実行されている(または多分一時停止している)場合、gameFrameTimeは非常に大きな値になり、奇妙な動作を引き起こす可能性があります。 MonoGame/XNAでこれが起こるかどうかは完全にはわかりませんが、少なくとも検討する価値はあります。

+0

shouldn ' t animationFrameTimeは、animationFrameTime = 1f/24fとする。 ? –

+0

@MikeJohnson素敵に見つかった。一定。 – craftworkgames

関連する問題