SFML游戏开发手册 - 了解FPS计算

时间:2014-09-20 12:45:40

标签: c++ sfml frame-rate

这是我的第一篇文章,所以我希望我能做到这一点。

我目前正在研究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。

我是在计算这个错误还是只是没有正确理解这个?

我希望这篇文章没问题,我似乎无法找到类似的问题。

非常感谢任何建议或帮助。

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

想出这一个!我看的是每秒运行的总帧数而不是每秒更新的帧数。当我记录每秒运行更新方法的次数时,我得到一个稳定的60FPS。

感谢帮助。

尼克