How to adjust a game loop frame rate?

2019-07-17 21:21发布

问题:

I'm at the moment trying to Programm my first Game in SFML (and my first overall) but i ran into the Problem that i get a stutter about once a second. During such a stutter the Frametime is 3 to 4 times higher than normal which is really noticeable as long i don't run really high FPS (300+).

No Problem (at least atm) as performance is not an Issue, but:

When doing that my movement Method really freaks out and moves way way slower that it's supposed to do.

my Movement method:

void Player::Update(float frametime){
    mMovementSpeedTimefactor = frametime * 60 / 1000.0f;

    setMovementVector(sf::Vector2f( mMovementVector.x * mMovementSpeedTimefactor, mMovementVector.y *mMovementSpeedTimefactor));
    validateMovement();
    //std::cout << mTestClock->restart().asMilliseconds() << std::endl;

    moveObject();
    this->updateAnimation();
}

frametime is the frametime in Milliseconds, and i Multiply by 60, as my movementspeed is set as a value for pixel/second and not per frame.

movementspeed is 5, so the character should move 5 px per second, whatever FPS( and therefore Frametime) i have.

But: that gives me really jumpy movement, as those "stutterframes" result in a jump, and on nto stuttering frames the palyer moves a lot slower than it should.

my mainloop is really simple, just

while(mMainWindow->isOpen()){

        HandleEvents();
        Update();
        Render();
    }

while using the inbuild framelimiter (tried writing my own, but i get the very same result, as long as i use sf:sleep to regulate FPS for not having the cpu core running at 100% load) to 300 FPS.

So yeah, i could just set my standard speed to 1 instead of 5, but setframeratelimit is not very accurate, so i get some variation in movementspeed, that i really not like.

anyone has an idea, what i could best do? Maybe i'm not seeing the forest for all the trees ( i actually have no idea if you say that in english :P) but as this is my first game i have no experience to look back upon.

回答1:

When frametime is really high or really low your calculations may not work correctly because of float precision issues. I suggest setting standard speed to, maybe, 500 and mMovementSpeedTimeFactor to frametime * 60 / 10.0f and check if the issue still happens.



回答2:

Similar question: Movement Without Framerate Limit C++ SFML.

What you really need is fixed time step. Take a look at the SFML Game development book source code. Here's the interesting snippet from Application.cpp:

    const sf::Time Game::TimePerFrame = sf::seconds(1.f/60.f);

    [...]

    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    while (mWindow.isOpen())
    {
        sf::Time elapsedTime = clock.restart();
        timeSinceLastUpdate += elapsedTime;
        while (timeSinceLastUpdate > TimePerFrame)
        {
            timeSinceLastUpdate -= TimePerFrame;

            processEvents();
            update(TimePerFrame);

        }

        updateStatistics(elapsedTime);
        render();
    }

EDIT: If this is not really what you want, see "Fix your timestep!" which Laurent Gomila himself linked in the SFML forum.