java 摆动计时器在调试时工作正常但在运行时不工作

java swing timer works fine in debug but not in runtime

我已经尝试这个几个小时了,我 lost.I 想要 运行 我的游戏以 30 fps 的速度运行。摆动定时器延迟设置为 1000/30。即使我将它减慢到 1000 或 2000,它也不会改变任何东西。在逐步调试中,一切都按预期工作。 "updateALL()" 方法在下次定时器刷新时被调用。但是在 运行time updateAll 从未被调用,甚至一次都没有(sysout 从不打印)。我精简了下面的代码以显示基本部分。它应该编译。

这是我的听众class:

public class Observer implements ActionListener {

    private int timerFrame;
    private int fps;
    private boolean frameComplete;

    public Observer() {
        this.frameComplete = true;
        this.timerFrame = 0;
    }

    @Override
    public void actionPerformed(ActionEvent aEvent) {
            nextTimerFrame();
    }

    public void frameCompleted() {
        frameComplete = true;
        System.out.println("Fcompleted");
    }

    public int getTimerFrame() {
        return timerFrame;
    }

    public void setFps(int fps) {
        this.fps = fps;
    }

    private void nextTimerFrame() {
        System.out.println(timerFrame);
        if(frameComplete) {
            if(timerFrame == fps) {
                timerFrame = 1;
            } else {
                ++timerFrame;
            }
            frameComplete = false;
        }
    } 
}

这是我的 GameClock 中的代码 Class:

public class GameClock {
    private Timer timer;
    private Observer observer;
    private GameEngine gameEngine;
    private View view;
    private boolean paused;
    private boolean quit;
    private int clockFrame;

    public GameClock() {}
    public GameClock(GameEngine gameEngine) {
        this.gameEngine = gameEngine;
        this.paused = false;
        this.quit = false;
        setupTimer();
        this.clockFrame = 0;
        run();
    }

    public void updateAll() {
            readInputs();
            updateGameEngine();
            updateCanvas2D();
            updateCanvas3D();
            clockFrame = clockFrame == 30? 1:clockFrame+1;  
            observer.frameCompleted(); // puts frameComplete at "true" in Observer
            System.out.println("update" + clockFrame);
    }

    public void run() {
        while(!quit) {
            int timerFrame = observer.getRefreshFrame();
            if(!paused && (clockFrame < timerFrame || (clockFrame == 30 && timerFrame == 1))) {
                updateAll();
                //System.out.println("update");
            }
        }
    }

    private void setupTimer() {
        int fps = Config.getFps();
        int delay = Math.round(1000/fps); 
        observer.setFps(fps);
        this.timer = new Timer(delay, observer);
        timer.start();
    }   
    private void readInputs() {

    }

    private void updateGameEngine() {
    }

    private void updateCanvas2D() {
    }

    private void updateCanvas3D() {
    }
}

更新:

一些奇怪的观察:

如果我将 2 sysout 放入我的 while 循环的 "if" 语句中,它们永远不会打印。这没有打印输出:

public void run() {
    while(!quit) {
        int clockFrame = observer.getRefreshFrame();
        //System.out.println("clock" + clockFrame);
        //System.out.println("frame" + refreshFrame);
        if(!paused && (refreshFrame < clockFrame || (refreshFrame == 30 && clockFrame == 1))) {
            System.out.println("clock" + clockFrame);
            System.out.println("frame" + refreshFrame);
            updateAll();
            //System.out.println("update");
        }
    }
}

如果我将之前的 sysout 放在注释中并从 "if" 语句之外的 2 中删除 //,如下所示:

public void run() {
    while(!quit) {
        int clockFrame = observer.getRefreshFrame();
        System.out.println("clock" + clockFrame);
        System.out.println("frame" + refreshFrame);
        if(!paused && (refreshFrame < clockFrame || (refreshFrame == 30 && clockFrame == 1))) {
            //System.out.println("clock" + clockFrame);
            //System.out.println("frame" + refreshFrame);
            updateAll();
            //System.out.println("update");
        }
    }
}

我看到 refreshFrame 总是随着 clockFrame 递增。这是没有意义的。如果从不调用 updateAll refreshFrame 则不会递增。

更新 2 - 一些解释:

以下是一个文件 mre(将整个代码复制粘贴到 GameClock.java)演示如何使用秋千 Timer 更新秋千 View在 30fps:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;

public class GameClock {

    private final Observer observer;
    private final View view;

    public GameClock() {
        view = new View();
        observer = new Observer(view);
        setupTimer();
    }

    private void setupTimer() {
        int fps = 30;
        int delay = Math.round(1000/fps);
        observer.setFps(fps);
        Timer timer = new Timer(delay, observer);
        timer.setInitialDelay(0);
        timer.start();
    }

    public static void main(String[] args) {
        new GameClock();
    }
}

class View {

    private JLabel counter;

    View(){
        createAndShowGui();
    }

    void createAndShowGui(){
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        counter = new JLabel("0", SwingConstants.CENTER);
        f.add(counter);
        f.pack();
        f.setVisible(true);
    }

    void setCounter(int i){
        counter.setText(String.valueOf(i));
    }
}

class Observer implements ActionListener {

    private int timerFrame;
    private int fps;
    private final boolean paused;
    private final View view;

    public Observer(View view) {
        this.view = view;
        paused = false;
        timerFrame = 0;
    }

    @Override
    public void actionPerformed(ActionEvent aEvent) {
        if (! paused) {
            updateAll();
        }
    }

    public int getTimerFrame() {
        return timerFrame;
    }

    public void setFps(int fps) {
        this.fps = fps;
    }

    private void nextTimerFrame() {
        timerFrame = timerFrame >= fps ?    0 : timerFrame + 1;
    }

    public void updateAll() {
        nextTimerFrame();
        view.setCounter(timerFrame);
    }
}