2

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.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Daepilin
  • 49
  • 3
  • 9

2 Answers2

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.

Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • sorry for not seeing this earlier ( as i don't have time for my game atm i did not check) but wouldn't that result in 100% core load? – Daepilin Dec 04 '13 at 12:38
  • Why wouldn't you want to take all the juice left for the currently running game application? Or you're making a passive game? (hot-seat, turn-based) Or is it a mobile game on which the battery life is really important? But as I can see, you're already using 100% CPU in the example you provided. And whether or not to use 100% of the CPU is a whole other question in itself. – Emile Bergeron Dec 06 '13 at 07:43
  • I added a link to the [Fix your Timestep](http://gafferongames.com/game-physics/fix-your-timestep/) article in my answer. – Emile Bergeron Dec 06 '13 at 07:49
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.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • hm, did not work. I guess i would have to have a max value for 'frametime', or i will always get those jumps. + It still was a lot slower than simply setting the speed to 1.0, even though it should have resulted in the same value... Well, for now i guess i keep using the internal framelimiter and set my speed to the "should be" framerate. I guess i can always change that but i get really frustrated. But thanks for the suggestion either way :) – Daepilin Aug 08 '13 at 12:45
  • Try occasionally writing `mMovementSpeedTimeFactor` to console and check if it's near 0 to confirm/unconfirm my original idea – Vittorio Romeo Aug 08 '13 at 15:18
  • Well, i just had the idea to create a litle log and that is really strange: [link](http://pastebin.com/Fs3GVuKY) i guess you were right about FP precision or some kind... as i see no way to get those values when simply calculating: `setMovementVector(sf::Vector2f( mMovementVector.x * mMovementSpeedTimefactor, mMovementVector.y * mMovementSpeedTimefactor));` "normal" value at those fps should be 0.6 to 1.2 for the given frametimes... – Daepilin Aug 08 '13 at 16:03
  • @Daepilin: you're on the right track. I suggest messing with the formula that prints "Resulting Speed:" in the log and figure out what part of it is giving the precision issue. – Vittorio Romeo Aug 08 '13 at 16:31
  • oh wow -.- i think i got it... somehow my movementvector stays teh same value, as long as the key is beeing pressed down... `else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){ setMovementVector(sf::Vector2f(-getMovementSpeed(), 0.0f)); setNextAnimation(3); }` tough this should set it back to 500 everytime. i guess i have to do that differently then. – Daepilin Aug 08 '13 at 16:47
  • 1
    I LOVE YOU!!!!!! Works, thanks, i guess if you would have not asked for values i would have never logged everything i need. – Daepilin Aug 08 '13 at 16:58