Regulating the number of executions per second usi

2020-05-01 10:32发布

问题:

So as of right now I'm implementing Conway's Game of Life using JavaFX. In a nutshell, in my class extending AnimationTimer, within the handle() method, it traverses through every cell in a 2D array and updates each position, then draws to the canvas using the information in the 2D array.

This works completely fine but the problem is it runs far too fast. You can't really see what's going on on the canvas. On the window I have the canvas as well as a few buttons. I added a Thread.sleep(1000) to try to regulate a generation/frame per second, but doing this causes the window to not detect the button presses immediately. The button presses are completely responsive when not telling the thread to sleep.

Does anyone have any suggestions on how to solve this?

回答1:

You can use Timeline which is probably more suitable for this. Set cycle count to Animation.INDEFINITE, and add a KeyFrame with the delay you want between updates, and your current handle implementation as the frame's onFinished.

final Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.getKeyFrames().add(
        new KeyFrame(
                Duration.seconds(1), 
                event -> handle()
        )
);
timeline.play();

Alternatively, you may try to have the delay of the KeyFrame as zero, and use the Timeline's targetFrameRate, but I personally never tried it.

Edit: Another option is to keep a frameSkip variable in your AnimationTimer:

private int frameSkip = 0;
private final int SKIP = 10;

@Override
public void handle(long now) {
    frameSkip++;
    if (frameSkip <= SKIP) {
        // Do nothing, wait for next frame;
        return;
    }
    // Every SKIP frames, reset frameSkip and do animation
    frameSkip = 0;

    // Do animation...
}