SFML极慢/不规则帧率

时间:2015-11-24 22:22:18

标签: c++ sfml

我最近一直在寻找C ++游戏开发框架,并决定尝试SFML。我已经从本书的SFML游戏开发实现了一个早期的例子'看事情是否正常。可悲的是他们没有。

当按下其中一个'时,代码应该使圆形物体快速移动。键。实际上,圆圈开始缓慢移动大约十个像素的距离,然后停止,如果我进一步按下相应的键,圆圈会在感觉到的时候跳过另外几个像素。

//the header game.h
class Game
{
public:
    Game();
    void run();

private:
    void processEvents();
    void handlePlayerInput(sf::Keyboard::Key, bool);
    void update();
    void render();

    sf::RenderWindow mWindow;
    sf::CircleShape mPlayer;

    bool mIsMovingUp;
    bool mIsMovingDown;
    bool mIsMovingLeft;
    bool mIsMovingRight;
};

//the implementation
#include<SFML/Graphics.hpp>
#include "game.h"

Game::Game()
: mWindow(sf::VideoMode(640, 480), "SFML Application")
, mIsMovingUp(false), mIsMovingDown(false), mIsMovingLeft(false), mIsMovingRight(false)
, mPlayer()
{
    mPlayer.setRadius(40.f);
    mPlayer.setPosition(100.f, 100.f);
    mPlayer.setFillColor(sf::Color::Cyan);
}

void Game::run()
{
    while (mWindow.isOpen())
    {
        processEvents();
        update();
        render();
    }
}

void Game::render() 
{
    mWindow.clear();
    mWindow.draw(mPlayer);
    mWindow.display();
}

void Game::processEvents()
{
    sf::Event event;
    while (mWindow.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:
                mWindow.close();
                break;
        }
    }
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
    if (key == sf::Keyboard::W)
            mIsMovingUp = isPressed;

    else if (key == sf::Keyboard::S)
            mIsMovingDown = isPressed;

    else if (key == sf::Keyboard::A)
            mIsMovingLeft = isPressed;

    else if (key == sf::Keyboard::D)
            mIsMovingRight = isPressed;
}

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

    if (mIsMovingUp)
        movement.y -= 1.0f;    
    if (mIsMovingDown)
        movement.y += 1.0f;
    if (mIsMovingLeft)
        movement.x -= 1.0f;
    if (mIsMovingRight)
        movement.x += 1.0f;

    mPlayer.move(movement);
}

//main file
#include <SFML/Graphics.hpp>
#include "game.h"

int main()
{

    Game game;
    game.run();

    return 0;
}

老实说,我甚至不知道从哪里开始寻找解决方案。 我想这可能与驱动程序有关,我明天将在另一台计算机上测试它。 对此有任何建议将不胜感激。

编辑以响应Ike: 我从Debian存储库运行了

的SFML库
`dpkg -l | grep sfml`

返回:

ii  libsfml-audio2:amd64                 2.1+dfsg2-1+b2                  
ii  libsfml-dev:amd64                    2.1+dfsg2-1+b2                       
ii  libsfml-graphics2:amd64              2.1+dfsg2-1+b2                       
ii  libsfml-network2:amd64               2.1+dfsg2-1+b2                       
ii  libsfml-system2:amd64                2.1+dfsg2-1+b2                       
ii  libsfml-window2:amd64                2.1+dfsg2-1+b2    

我使用-O2标志用g ++编译了上面的代码。 我无法想象这是一个优化问题,因为游戏循环似乎每秒可能经历二十次迭代(最多)。我不能肯定地说这个,但我相信这个数字应该是成千上万。

另一个编辑:好的,所以我使用repo-library再次在Ubuntu-VM中编译了相同的代码。圈子现在移动得相当快,这比我想的更好(并且还提出了debian的一些问题,可能与驱动程序有关?)。在另一台计算机上(无疑比我的笔记本电脑快)运行拱形并使用sfml 2.3.2,程序运行速度快十倍

2 个答案:

答案 0 :(得分:1)

要尝试的几件事情:

A)设置mWindow.setKeyRepeatEnabled(false)。这将禁用自动重复。

B)尝试更改Game::processEvents以使用if代替while,如下所示:

void Game::processEvents()
{
    sf::Event event;
    if (mWindow.pollEvent(event))
    {
        ...
    }
}

我怀疑你看到的是事件队列被自动重复键事件发送垃圾邮件的结果。然后,这将切入调用updaterender等函数的频率,并破坏平滑的帧速率。

第一个建议试图消除干扰队列的这种可能性。第二个会使它更新/刷新在事件处理之间交错,而不仅仅在事件队列变空时执行。

答案 1 :(得分:0)

从我的相关问题https://gamedev.stackexchange.com/questions/185873/sfml-test-app-feels-slow-clunky/185880#185880来看,问题可能是您正在使用键盘事件而不是实时键盘输入。 即sed 's/[^0-9]*\([0-9]\+\).*/\1/' file

请参见https://www.sfml-dev.org/tutorials/2.5/window-inputs.php