How should I change my GameLoop?

I’ve got a serious issue with my GameLoop. This loop varies in time with the platform and with the same hardware. This is a list of FPS achieved.

  • Windows ======= 140 to 150
  • Linux ======= 120 to 125
  • Windows(WINE) ======= 125 to 135

And since my game loop is fixed timestep, the speed of the game is not stable. Here’s my GameLoop.

GameLoop

public final void run(){
    // Initialize the resources
    Map.initMap();
    initResources();
    // Start the timer
    GTimer.startTimer();
    GTimer.refresh();
    long elapsedTime = 0;
    // The game loop
    while (running) {
        // Update the game
        update(elapsedTime);
        if (state == GameState.GAME_PLAYING) {
            Map.updateObjects(elapsedTime);
        }
        // Show or hide the cursor
        if (Global.HIDE_CURSOR) {
            setCursor(GInput.INVISIBLE_CURSOR);
        } else {
            setCursor(Cursor.getDefaultCursor());
        }
        // Repaint the game and sync
        repaint();
        elapsedTime = GTimer.sync();
        Toolkit.getDefaultToolkit().sync();
    }
}

Here are the two classes of the timer package.

https://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/timer/GTimer.java
https://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/timer/GFrameRateCalculator.java

How could I improve it?

It’s really common to have different FPS results on many OSes.

But the game speed is not consistant. On windows it’s much faster…

How about cap/limit the FPS to certain value, like 30 or 60? I always do this for quick solution (when you’re on jam/compo) and only have time to test on windows. I never hear problem from linux users by this.

I agree just cap at 60, human eye can’t see any more frames then 30-40 so 60 will always appear to be smooth.

Could anybody show an example?

Your GTimer.sync() should already do it, but I can’t find place where you set the desired number.

See this class https://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/core/Global.java

I never use those classes before, but it looks like you just need to specify the time. For 60fps I think it’ll be 1000/FPS = 1000/60 = 16.67 ~ 16ms.

inb4 my game is stuttering because it’s running at 62 FPS on a 60 hertz monitor.

The human eye can see many more frames than 60 per second…it’s the timings of the screens that cap it at 60, 75 or 120Hz to ensure a smooth experience. It’s more like 2500fps for the human eye, although we don’t process all of them.

The eye processes pretty much continuously, and its ability to distinguish discrete events ranges, depending on light conditions, the type of stimulus, and physical and mental state. It’s just that 60fps just happens to be good enough most of the time for the sort of motion commonly rendered on a computer screen. It’s not really based on any advanced study of perception, it’s just good enough. Do a fast pan with high contrast on a 50" screen without any motion blur and you’ll still ruin the illusion with a big trail of distinct after-images.

Now the job of the brain is to smooth out all the data from the eye, and it really does some amazing things. Google “stopped clock illusion” sometime for one really mind-bendy example – your perception of time itself is largely a trick your brain is pulling on you.

You got me wrong. People were using an old flawed version of Display.sync() to sync to 60 FPS, but since it rounded the wait time it synced to 62 FPS, and people saw that as “stuttering” when one frame was dropped two or three times a second. This in turn spawned a huge thread with people trying to fix all kinds of stuttering using Java magic and rituals in a futile attempt to make the graphics pipeline that is OpenGL not behave like a graphics pipeline.

The OPer might want to read up on stuff here,

http://www.koonsolo.com/news/dewitters-gameloop/

It explains things well IMO.