How do I cap my framerate at 60 fps in Java?

2019-03-18 06:01发布

I am writting a simple game, and I want to cap my framerate at 60 fps without making the loop eat my cpu. How would I do this?

10条回答
\"骚年 ilove
2楼-- · 2019-03-18 06:28

I took the Game Loop Article that @cherouvim posted, and I took the "Best" strategy and attempted to rewrite it for a java Runnable, seems to be working for me

double interpolation = 0;
final int TICKS_PER_SECOND = 25;
final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
final int MAX_FRAMESKIP = 5;

@Override
public void run() {
    double next_game_tick = System.currentTimeMillis();
    int loops;

    while (true) {
        loops = 0;
        while (System.currentTimeMillis() > next_game_tick
                && loops < MAX_FRAMESKIP) {

            update_game();

            next_game_tick += SKIP_TICKS;
            loops++;
        }

        interpolation = (System.currentTimeMillis() + SKIP_TICKS - next_game_tick
                / (double) SKIP_TICKS);
        display_game(interpolation);
    }
}
查看更多
放我归山
3楼-- · 2019-03-18 06:35

In java you could do System.currentTimeMillis() to get the time in milliseconds instead of glfwGetTime().

Thread.sleep(time in milliseconds) makes the thread wait in case you don't know, and it must be within a try block.

查看更多
相关推荐>>
4楼-- · 2019-03-18 06:41

Timer is inaccurate for controlling FPS in java. I have found that out second hand. You will need to implement your own timer or do real time FPS with limitations. But do not use Timer as it's not 100% accurate, and therefore cannot execute tasks properly.

查看更多
霸刀☆藐视天下
5楼-- · 2019-03-18 06:41

If you are using Java Swing the simplest way to achieve a 60 fps is by setting up a javax.swing.Timer like this and is a common way to make games:

public static int DELAY = 1000/60;

Timer timer = new Timer(DELAY,new ActionListener() {
    public void actionPerformed(ActionEvent event) 
    {
      updateModel();
      repaintScreen();
    }
});

And somewhere in your code you must set this timer to repeat and start it:

timer.setRepeats(true);
timer.start();

Each second has 1000 ms and by dividing this with your fps (60) and setting up the timer with this delay (1000/60 = 16 ms rounded down) you will get a somewhat fixed framerate. I say "somewhat" because this depends heavily on what you do in the updateModel() and repaintScreen() calls above.

To get more predictable results, try to time the two calls in the timer and make sure they finish within 16 ms to uphold 60 fps. With smart preallocation of memory, object reuse and other things you can reduce the impact of the Garbage Collector also. But that is for another question.

查看更多
劫难
6楼-- · 2019-03-18 06:42

What I have done is to just continue to loop through, and keep track of when I last did an animation. If it has been at least 17 ms then go through the animation sequence.

This way I could check for any user inputs, and turn musical notes on/off as needed.

But, this was in a program to help teach music to children and my application was hogging up the computer in that it was fullscreen, so it didn't play well with others.

查看更多
老娘就宠你
7楼-- · 2019-03-18 06:43

The simple answer is to set a java.util.Timer to fire every 17 ms and do your work in the timer event.

查看更多
登录 后发表回答