Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Game loop becomes unstable after ~5 seconds  (Read 2014 times)

0 Members and 1 Guest are viewing this topic.

buymespam

  • Newbie
  • *
  • Posts: 6
    • View Profile
Game loop becomes unstable after ~5 seconds
« on: August 12, 2014, 10:06:33 am »
Hey, I've been playing around with trying to make a game in my spare time. I've unfortunately just realized that my game loop is just terrible after five seconds of execution, and I'm not sure what to do to fix it. I've been following gaffer's game loop tutorial, for what it's worth. If you compile the below code, you'll see that initially everything is fine, but eventually the time becomes "jerky," and then everything just stops.

I know that this is (likely) due to a poor game loop, specifically the use of floats to store the time. But I don't know exactly what I'm doing wrong. I provided an attempted minimal example of my problem.

On a slightly related note, if there's something fundamentally wrong with my game loop structure, or I'm using poor coding practices somewhere, please let me know! Thanks!  :)

#include <SFML/Graphics.hpp>
void update(sf::CircleShape & s , float t ,float dt){
        s.setPosition(250+(float)(50*std::sin(t/10000.0)),250+(float)(50*std::cos(t/10000.0)));
}

int main(){
        sf::RenderWindow window(sf::VideoMode(500,500),"Testing!");

        sf::Clock clock;
        clock.restart();

        sf::CircleShape s;
        s.setRadius(50);
        s.setFillColor(sf::Color::Red);

        float t = 0.0f;
        const float dt = 0.01f;
        float currentTime = clock.getElapsedTime().asSeconds();
        float accumulatedTime = 0.0f;

        //Window Loop
        while(window.isOpen()){

                //Event processing.
                sf::Event event;
                while (window.pollEvent(event)){
                        if (event.type == sf::Event::Closed)
                                window.close();
                }

                //Timestep Updating.
                float  newTime = clock.getElapsedTime().asSeconds();
                float  frameTime = newTime - currentTime;
                if(frameTime > 0.25)
                        frameTime = 0.25;
                currentTime = newTime;
                accumulatedTime+=newTime;
               
                //Update loop.
                while(accumulatedTime > dt){
                        update(s,t,dt);
                        accumulatedTime-=dt;
                        t+=dt;
                }

                //Draw items, Linear interpolation.
                const float  alpha = accumulatedTime / dt;
                window.clear(sf::Color::Black);
        window.draw(s);
                window.display();
        }
}
 

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Game loop becomes unstable after ~5 seconds
« Reply #1 on: August 12, 2014, 11:46:04 am »
So you already know its wrong to use float for making time calculations, but still ask whats wrong? Never ever use float for times. If you cant help it use 64 bit ints or doubles, but the right way with SFML is to just only use sf::Time for all calculations and retrieve a number only at the last moment before you need one.
Reading the tutorial may be helpful: http://sfml-dev.org/tutorials/2.1/system-time.php

Hapax

  • Hero Member
  • *****
  • Posts: 3367
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Game loop becomes unstable after ~5 seconds
« Reply #2 on: August 12, 2014, 04:52:48 pm »
As time increases, the floats are becoming less and less accurate.
You could restart the clock instead to keep the time in always low, thus:
frameTime = clock.restart().asSeconds();

Also, in the tutorial that you followed, you mis-typed a line:
Quote
accumulator += frameTime;
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

buymespam

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Game loop becomes unstable after ~5 seconds
« Reply #3 on: August 12, 2014, 05:55:40 pm »
So you already know its wrong to use float for making time calculations, but still ask whats wrong? Never ever use float for times. If you cant help it use 64 bit ints or doubles, but the right way with SFML is to just only use sf::Time for all calculations and retrieve a number only at the last moment before you need one.
Reading the tutorial may be helpful: http://sfml-dev.org/tutorials/2.1/system-time.php

I replaced all  float with  long double a while ago, but this didn't help, as I still get a little jerkyness / speedups after some time.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Game loop becomes unstable after ~5 seconds
« Reply #4 on: August 12, 2014, 09:57:30 pm »
Why on earth don't you just use sf::Time (or 'auto' which gives you just that)?
Why do you insist on conversions that reduce accuracy?

And another thing: don't ever depend on frame rates being stable. They are not (ever). Deal with it.
« Last Edit: August 12, 2014, 10:00:04 pm by Jesper Juhl »

Hapax

  • Hero Member
  • *****
  • Posts: 3367
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Game loop becomes unstable after ~5 seconds
« Reply #5 on: August 12, 2014, 10:26:52 pm »
It's because you adding on the entire elapsed time each frame. The longer it runs, the more time needs to be processed. You need to be only adding on the frame time (see the correction that I showed you in my previous post, which is directly from the original tutorial).
Remember, frameTime, not newTime.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*