2014-09-20 89 views
2

這是我的第一篇文章,所以我希望我得到這個權利。SFML遊戲開發書籍 - 瞭解FPS計算

我目前正在通過SFML遊戲開發書。我想了解介紹示例中FPS的計算方式。

我的遊戲類看起來是這樣的:

#include "Game.h" 

const sf::Time Game::TIME_PER_FRAME = sf::seconds(1.f/60.f); 
const float Game::PLAYER_SPEED = 100.f; 

Game::Game() : Window(sf::VideoMode(640,480), "ORGELLA") {   

    isMovingUp = false; 
    isMovingDown = false; 
    isMovingLeft = false; 
    isMovingRight = false; 

    Player.setRadius(40.f); 
    Player.setPosition(100.f, 100.f); 
    Player.setFillColor(sf::Color::Cyan); 

    font.loadFromFile(resourcePath() + "sansation.ttf"); 
    statsText.setFont(font); 
    statsText.setPosition(5.f, 5.f); 
    statsText.setCharacterSize(10); 
} 

void Game::run() { 
    sf::Clock clock; 
    sf::Time timeSinceLastUpdate = sf::Time::Zero; 


    while (Window.isOpen()) { 
     sf::Time dt = clock.restart(); 
     timeSinceLastUpdate += dt; 

     while (timeSinceLastUpdate > TIME_PER_FRAME) { 
      timeSinceLastUpdate -= TIME_PER_FRAME; 

      handleEvents(); 
      update(TIME_PER_FRAME); 
     } 

     updateGameStats(dt); 
     render(); 
    } 
} 

void Game::handleEvents() { 
    sf::Event event; 
    while (Window.pollEvent(event)) { 
     switch (event.type) { 
      case sf::Event::KeyPressed: 
       handlePlayerInput(event.key.code, true); 
       break; 
      case sf::Event::KeyReleased: 
       handlePlayerInput(event.key.code, false); 
       break; 
      case sf::Event::Closed: 
       Window.close(); 
       break; 
     } 
    } 
} 

void Game::update(sf::Time dt) { 
    sf::Vector2f movement(0.f, 0.f); 

    if (isMovingUp) 
     movement.y -= PLAYER_SPEED; 
    if (isMovingDown) 
     movement.y += PLAYER_SPEED; 
    if(isMovingLeft) 
     movement.x -= PLAYER_SPEED; 
    if (isMovingRight) 
     movement.x += PLAYER_SPEED; 

    Player.move(movement * dt.asSeconds()); 
} 

void Game::render() { 
    Window.clear(); 
    Window.draw(Player); 
    Window.draw(statsText); 
    Window.display(); 
} 

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed) { 
    switch (key) { 
     case sf::Keyboard::W: 
      isMovingUp = isPressed; 
      break; 
     case sf::Keyboard::S: 
      isMovingDown = isPressed; 
      break; 
     case sf::Keyboard::A: 
      isMovingLeft = isPressed; 
      break; 
     case sf::Keyboard::D: 
      isMovingRight = isPressed; 
      break; 
    } 
} 

void Game::updateGameStats(sf::Time dt) { 
    statsTotalTimeElapsed += dt ; 
    statsNumberOfFrames += 1; 

    if (statsTotalTimeElapsed >= sf::seconds(1.0f)) { 
     statsText.setString(
      "FPS = " + to_string(statsNumberOfFrames) + "\n" + 
      "Time/Update = " + to_string(statsTotalTimeElapsed.asMicroseconds()/statsNumberOfFrames) + "us"); 

     statsTotalTimeElapsed -= sf::seconds(1.0f); 
     statsNumberOfFrames = 0; 
    } 
} 

現在,我的問題是這樣的。計算出的FPS是如何計算的,並顯示在我的屏幕上。從我所能理解的FPS上限爲60fps,但是當我運行該應用程序時,顯示的FPS約爲500 - 1200 FPS。

我在計算這個錯誤還是隻是沒有正確理解這個?

我希望這篇文章是好的,我似乎無法找到類似的問題。

任何意見或幫助將不勝感激。

回答

1

給定一個framerate(例如60 FPS):

auto framerate = 60; // FPS 
auto elapsedMillisecondsExpected = 1000/framerate; // in milliseconds 

在SFML您使用sf::Clock並在每一幀你更糟的是:

sf::Clock clock; 

// frame logic 

auto elapsedMilliseconds = clock.getElapsedTime().asMilliseconds(); 
if (elapsedMilliseconds < elapsedMillisecondsExpected) { 
    auto sleepMilliseconds = elapsedMillisecondsExpected - elapsedMilliseconds; 
    // sleep for sleepMilliseconds 
} 
+0

嗨,感謝您的答覆。這是有道理的,但不是在當前的遊戲循環中發生了什麼? Where TIME_PER_FRAME = framerate,第二個循環應該跟蹤將其限制爲60FPS?再次感謝。 – 2014-09-21 06:17:33

0

想通了這一個了!我正在查看每秒運行的總幀數,而不是每秒更新的幀數。當我記錄更新方法每秒運行多少次時,我得到穩定的60FPS。

欣賞幫助。

尼克