System.out.println在while循环的每次迭代中打印两次

时间:2014-03-24 06:27:25

标签: java game-loop

我试图弄清楚为什么在运行此代码时,我会在while循环的每次迭代中打印两行:

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1) {
            System.out.println(delta);
            currentTime = System.nanoTime();
        }
    }
}

我尝试调整代码只调用System.out.println()一次进行调试,但是它仍然打印两次。我似乎无法弄清楚为什么会发生这种情况,因为在此修改版本中调用了System.out.println(delta),然后将print设置为true,因此不应再调用System.out.println(delta)

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
            boolean printed = false;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1 & !printed) {
            System.out.println(delta);
            currentTime = System.nanoTime();
                            printed = true;
        }
    }
}

上下文代码:

public class Game extends Canvas implements Runnable, KeyListener {

    private Thread gameThread;

public synchronized void start() {
    if(GameConstants.running) return;
    GameConstants.running = true;
    gameThread = new Thread(this);
    gameThread.start();
}

public synchronized void stop() {
    if(!GameConstants.running) return;
    GameConstants.running = false;
    try {
        gameThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void run() {
    long currentTime = System.nanoTime();
    long targetFPS = 1000;
    long delta;
            boolean printed = false;
    while(GameConstants.running) {
        delta = System.nanoTime() - currentTime;
        if(delta/1000000000 >= 1 && !printed) {
            System.out.println(delta);
            currentTime = System.nanoTime();
                            printed = true;
        }
    }
}

public void update() {
    if(GameConstants.gameState == 1 && !GameConstants.trialTypeDetermined ) {
        Random r = new Random();
        double prob = r.nextDouble();
        if(prob < GameConstants.goProb) {
            GameConstants.skipBad = true;
        }
        GameConstants.trialTypeDetermined = true;
        System.out.println(GameConstants.skipBad);
    }
      taskTimer(GameConstants.goTaskTimes.get(getGameState(GameConstants.gameState)));
    System.out.println(GameConstants.gameState);
    try {
        Thread.sleep(1);
    } catch(InterruptedException e) {
    }
}

public void render() {

}

//
public String getGameState(int gameState){
    return GameConstants.gameStates[GameConstants.gameState];
}

private void skipBad() {
    Random r = new Random();
    double prob = r.nextDouble();
    if(prob < GameConstants.goProb) {
        GameConstants.skipBad = true;
    }
    GameConstants.trialTypeDetermined = true;
}

public void taskTimer(long taskTime) {
    if(System.currentTimeMillis() - GameConstants.startTime >= taskTime) {
        GameConstants.taskComplete = true;
        GameConstants.startTime = System.currentTimeMillis();
        nextGameState();
        GameConstants.keyPressed = false;
    }
}

private void nextGameState() {
    if(GameConstants.gameState == 2 & GameConstants.skipBad) {
        GameConstants.gameState = GameConstants.gameState + 2;
    } else if(GameConstants.gameState != 5) {
        GameConstants.gameState++;
    } else {
        GameConstants.gameState = 1;
    }
    GameConstants.gameStateRegistered = false;
}

private void resetParameters() {

}

private void checkHit() {

}

public void keyPressed(KeyEvent e){
    int keyCode = e.getKeyCode();

    if(keyCode == KeyEvent.VK_SPACE && !GameConstants.keyPressed){
       GameConstants.keyPressed = true;
       if(!GameConstants.reached){
           GameConstants.reached = true;
           GameConstants.RT = System.currentTimeMillis();
       }
    }
}

public void keyReleased(KeyEvent e){

}

public void keyTyped(KeyEvent e){

}

public static void main(String[] args) {
    Game game = new Game();
    game.setPreferredSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));
    game.setMaximumSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));
    game.setMinimumSize(new Dimension(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE));

    JFrame frame = new JFrame("Game");
    frame.setSize(GameConstants.WIDTH * GameConstants.SCALE, GameConstants.HEIGHT * GameConstants.SCALE);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(game);
    frame.setVisible(true);
    game.start();
    game.run();
}
}

2 个答案:

答案 0 :(得分:4)

您的引导代码存在缺陷,您正在调用startrun两次有效运行代码。移除对run的电话。

答案 1 :(得分:1)

你已经在同一个对象上启动了多个线程,你应该使用synchronized块来运行线程安全的代码,

synchronized(this){

long currentTime = System.nanoTime();
long targetFPS = 1000;
long delta;
while(GameConstants.running) {
    delta = System.nanoTime() - currentTime;
    if(delta/1000000000 >= 1) {
        System.out.println(delta);
        currentTime = System.nanoTime();
    }
}
}

更新源代码后

呀!在这里,您正在调用run()方法并启动它们......

game.start();
game.run();

显式删除调用run方法,您将获得所需的结果:)