java游戏循环的奇怪行为

java游戏循环的奇怪行为,java,swing,repaint,game-loop,Java,Swing,Repaint,Game Loop,我有一个简单的java游戏循环: public void run(){ while(running){ start = System.nanoTime(); gamePanel.update(); gamePanel.repaint(); elapsed = System.nanoTime() - start; wait = (TARGET_TIME - elapsed) / 1000000;

我有一个简单的java游戏循环:

public void run(){
    while(running){
        start = System.nanoTime();
        gamePanel.update();
        gamePanel.repaint();
        elapsed = System.nanoTime() - start;
        wait = (TARGET_TIME - elapsed) / 1000000;
        if(wait < 0){wait = TARGET_TIME;}
        try {Thread.sleep(wait);}catch(Exception e) {e.printStackTrace();}
    }
}
因此,当我重新绘制一次时,游戏会更新1000次以上。这正常吗?我觉得有点奇怪,不是吗?例如,可以对玩家执行1000步,直到游戏开始绘制。。。 这意味着update()方法不会等待重新绘制完成?为什么?

谢谢大家!

编辑:此处显示更新代码:

public void update(){
    if(moveUp){
        changeMapY(map, -map.getSpeed());
    }
    if(moveDown){
        changeMapY(map, map.getSpeed());
    }
    if(moveRight){
        changeMapX(map, map.getSpeed());
    }
    if(moveLeft){
        changeMapX(map, -map.getSpeed());
    }
}
编辑2:这就是changeMap所做的:(也许这就是问题所在?)

public void changeMapX(地图地图,整数金额){
对于(int i=0;i
以秒为单位计算等待时间。(纳秒/100万)

睡眠参数应以毫秒为单位。因此,改变这一行:

wait = (TARGET_TIME - elapsed) / 1000;

我测试了你的源代码,“更新”,“重新绘制”是一个接一个的。问题与您的
update()
方法有关。也许是递归,也许是循环

假设gamePanel是一个Swing组件,您可能观察到的是repaint()实际上并没有调用JComponent.paintComponent()。它所做的一切本质上就是使组件的图形无效,并告诉Swing在将来的某个时间点在Swing线程上重新绘制组件


对repaint()的多次调用不一定会导致对paintComponent()的多次调用-冗余的重新绘制请求会被折叠成一个。

也许您在
gamePanel.update()中有循环,显示更新次数
1000次?我们可以看到更新中的一些代码吗?(我假设update也不是递归正确的?)是从另一个线程调用的
update
方法吗?源代码递归的任何部分中都有吗?@T_01好的,
getSpeed()
是否以某种方式调用了
update()
,是吗?@Fildor如果他在循环前等待1000分之一的时间,就会导致循环执行1000次。我认为这是一个答案。嗯,没关系,因为他是对的,这确实有帮助。。。现在,它通过重绘1次更新1到3次。但是无论如何,更新方法不是等待…@LeeMeador是真的,但是如果这仅仅是他的
循环运行太频繁的问题,他不会得到
更新、重新绘制、更新、重新绘制等吗?@LeeMeador我不同意。我想他总是希望在更新之后立即重画。等待太久会导致他们两人都被执行得太频繁,或者我可能错过了什么?这是答案的一部分,你是对的。repaint当然调用paintComponent,paintComponent调用super.paintComponents();repaint()的默认实现不支持。如果你覆盖它,这将是一个有用的东西提到。
public void changeMapX(Map map, int amount){
    for(int i = 0; i < blocks.length; i++){
        for(int j = 0; j < blocks[0].length; j++){
            blocks[i][j].addX(amount);
        }
    }
    map.addOffsetx(amount);
}

public void changeMapY(Map map, int amount){
    for(int i = 0; i < blocks.length; i++){
        for(int j = 0; j < blocks[0].length; j++){
            blocks[i][j].addY(amount);
        }
    }
    map.addOffsety(amount);
}
wait = (TARGET_TIME - elapsed) / 1000;