2016-12-29 8 views
1

私はsfmlでゲームループを書いています。私がスリープ状態にならない場合、各ループ反復の経過時間は〜1msです。しかし、私は睡眠を追加する(sleepTime)突然dtが高いです。ループの始めにdtを再起動しますが、最後のスリープ時間が追加されているようです。何が原因ですか?睡眠なしゲームループでsleep()を使うと、デルタ時間が不安定になる

sf::Clock clock; 
float dt; 
sf::Time sleepTime = sf::milliseconds(0); 

while(m_Window.isOpen()) 
{ 
    sf::Time elapsed = clock.restart(); 
    dt = elapsed.asMilliseconds(); 

    cout << "Elapsed: " << dt; 

    sf::Event event; 

    while(m_Window.pollEvent(event)) 
    { 
     switch(event.type) 
     { 
      case sf::Event::Closed: 
       m_Window.close(); 
       break; 
     } 
    } 

    sleepTime = sf::milliseconds(16 - dt); 

    float time = sleepTime.asMilliseconds(); 
    cout << "\tSleep time: " << time << endl; 

    if(sleepTime >= sf::Time::Zero) 
    { 
     sf::sleep(sleepTime); 
    } 
    else 
    { 
     cout << "Shit." << endl; 
    } 

https://aww.moe/sn1z0a.png

睡眠とは:あなたが何をしようとしてhttps://aww.moe/7seof1.png

+5

睡眠が原因です。なぜあなたは寝ているのですか? –

+0

私は一定のゲーム速度を確立したいので。私はこれを使用しています:http://www.koonsolo.com/news/dewitters-gameloop/ – Glamhoth

+0

そして私はsleep()が超正確ではないことを知っています。しかし、ループの開始時にdtを再起動します。なぜ、スリープ時間がdtに追加されるのですか? – Glamhoth

答えて

3

- 特定のフレームレートにゲームを制限する - すでにSFMLに組み込まれています。 sf::Window::setFrameRateLimit()にパラメータとして指定したフレームレートを指定するだけで設定されます。また、ターゲットマシンが目的のフレームレートでレンダリングできない場合、ゲームが遅くなるため、垂直同期(sf::Window::setVerticalSyncEnabled()を使用)を使用してフレーム/更新の数を制限することもできます。 120または140Hzで動作するハイエンド画面のスピードアップ)。

しかし、通常、現在のマシンが画面をすばやく更新できない場合でも、ゲームの速度が低下しないように、ゲームの更新をフレームレートから切り離したい場合があります。

SFMLを使用して、基本的なアプローチは、一般的に(これはメモリからなので、バグや誤植が含まれる可能性がある)のようになります。

sf::Clock updateTimer; // Clock to monitor the time passed 
sf::Time passedTime; // Accumulated game time 
const sf::Time frameTime(sf::milliseconds(10)); // intended time per frame; here: 10ms 

while (window.isOpen()) { 
    sf::Event event; 
    while (window.pollEvent(event)) { 
     // Event handling 
    } 

    // First add the time passed 
    passedTime += updateClock.restart(); 

    unsigned int numUpdates = 0; // Count the updates done 

    // As long as enough time passed, do an update 
    // Up to a specific maximum to avoid problems, e.g. 
    // the main thread was blocked or can't catch up 
    while (passedTime >= frameTime) { 

     if (numUpdates++ < 10) { 
      // Do your game update here 
     } 

     // Subtract the time we've "handled" 
     passedTime -= frameTime; 
    } 

    window.clear(); 
    // Draw your game here 
    window.display(); 
} 

numUpdatesの使用が最初に明確であるが、ちょうど想像しない場合がありますマシンが1秒間に100回の更新をほとんど実行できない状況。あなたが20回更新している場合(何らかのヒックアップなど)、マシンは決して適切に追いつくことができず、ひどい吃音やゲームが反応しなくなります。

+0

http://pastebin.com/VvWLewmAこれを少し変更しました。仕事をしているようだ。 – Glamhoth

+0

@Glamhothもう一度タイマーを再起動しないでください(最後に)。さもなければ、あなたはすべてを描くのにかかった時間を失ってしまいます。 – Mario

+0

まだ動作しているようですね、ありがとう! – Glamhoth

関連する問題