JavaFXAnimationTimer没有正确停止

所以,我正在使用 JavaFX 创建蛇游戏,我似乎无法让游戏正确暂停,即它偶尔会暂停,而其他时候,游戏只是忽略了暂停。所以,基本上我有一个Main类,我在其中初始化所有 GUI 组件,它还充当 javafx 应用程序的控制器。

我有一个启动/暂停游戏的Button命名gameControl,一个Boolean pause跟踪游戏状态(新/暂停/运行)的变量,以及方法startGame, pauseGame

gameControl按钮的EventHandler情况如下:

gameControl.setOnClicked(event->{
    if(paused == null) startGame(); //new game
    else if(paused) continueGame(); //for paused game
    else pauseGame();               //for running game
});

startGame函数看起来像这样:

void startGame(){
    paused = false;
    Snake snake = new Snake(); //the snake sprite
    //following gameLoop controls the animation of the snake
    gameLoop = new AnimationTimer(){
        @Override
        public void handle(long now){
            drawSnake(); //draws the snake on the game
            snake.move(); //move snake ahead

            //following code is for slowing down the gameLoop renders to make it easier to play
            Task<Void> sleeper = new Task<>(){
                @Override
                protected Void call() throws Exception {
                    gameLoop.stop();
                    Thread.sleep(30);
                    gameLoop.start();
                    return null;
                }
            };
            new Thread(sleeper).start();
            //force garbage collection or else throws a bunch of exceptions after a while of running.
            //not sure of the cause...
            System.gc();
        }
    };
    gameLoop.start();
}

AnimationTimer gameLoop 是允许从其他函数调用的类的变量。

pauseGame功能:

void pauseGame() {
    paused = true;
    gameLoop.stop();
}

因此,正如我以前说过的游戏不会暂停,每次我打的gameControl按钮,我怀疑这是由于Thread.sleep(30);内部线路TaskgameLoop。话虽如此,我仍然不完全确定,也不知道如何解决这个问题。任何帮助,将不胜感激。

回答

什么类型是“暂停”?你检查它是否为空,然后把它当作一个布尔值......我不明白为什么它会是一个大的 'B' 布尔对象包装器而不是原始布尔类型。

这个:

        //following code is for slowing down the gameLoop renders to make it easier to play
        Task<Void> sleeper = new Task<>(){
            @Override
            protected Void call() throws Exception {
                gameLoop.stop();
                Thread.sleep(30);
                gameLoop.start();
                return null;
            }
        };

是一种绝对可怕的方式来限制速度。让您的游戏循环运行,检查每个循环的时间,看看是否已经过去了足够的时间来更新内容。您的动画计时器将推动游戏。您不想暂停主平台线程,也不想暂停任何正在处理任务的工作线程。如果您正在安排任务,请安排它们以您想要的时间间隔运行 - 不要在 call() 方法中限制线程。

你真正想要的是这样的:

//following gameLoop controls the animation of the snake
gameLoop = new AnimationTimer(){
    @Override
    public void handle(long now){
        if ((now - lastTime) > updateIterval) {
            drawSnake(); //draws the snake on the game
            snake.move(); //move snake ahead
            lastTime = now;
        }

您甚至可以将其设为循环以“赶上”,以防动画计时器因某种原因落后:

        while ((now - lastTime) > updateIterval) {
            drawSnake(); //draws the snake on the game
            snake.move(); //move snake ahead
            lastTime += updateIterval;
        }


以上是JavaFXAnimationTimer没有正确停止的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>