0

I have a simple game loop in 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();}
    }
}

Now the problem: When i add a sysout in update() outing "updating" and one in paintComponent() outing "repainting", i get following result:

updating
updating
updating
updating
updating
(x1000 and more)
repainting

So when i repaint one time, the game is updating 1000 and more times. Is it normal? I think its abit strange, isnt it? For example can do 1000 steps with the player until the game is painting it... That means, the update() method doesnt wait for repaint finishing? Why?

Thank you!

Edit: Here the update code:

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());
    }
}

Edit 2: And this is what changeMap does: (maybe this is the problem?)

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);
}
T_01
  • 1,256
  • 3
  • 16
  • 35

3 Answers3

0

You calculate wait in seconds. (nano-seconds / 1 million)

The parameter to sleep should be in miliseconds. So change this line:

wait = (TARGET_TIME - elapsed) / 1000;
Lee Meador
  • 12,829
  • 2
  • 36
  • 42
  • That's true, but it does not answer the question, does it? – Fildor Sep 03 '13 at 17:49
  • @Fildor If he waits 1/1000th as long as he should before looping back, it will cause the loop to be executed 1000 times as often. I think that constitutes an answer. – Lee Meador Sep 03 '13 at 17:51
  • Hmmm its okay, because hes right and it does help... Now it updates 1 to 3 times by redrawing 1 time. But anyway, the update method isnt wating... – T_01 Sep 03 '13 at 17:52
  • @LeeMeador true, but if it was simply a problem of his `while` loop running too often, wouldn't he be getting `Updating, Repainting, Updating, Repainting` and so on? – Jordan Sep 03 '13 at 17:57
  • @LeeMeador I disagree. I think he'd expect always an update followed by a repaint immediately. Waiting for too long should cause them both to be executed too often, or am I missing something perhaps? It's part of the answer though, you're right. – Fildor Sep 03 '13 at 17:58
  • @Fildor We haven't seen the repaint code, perhaps it only paints if something changes or a certain time has elapsed or whatever. – Lee Meador Sep 03 '13 at 18:05
  • @LeeMeador See his comment to my question what the output without the loop is. I guess you are right that something probably keeps repaint from being executed, when using that loop. Could be that it has to do with it not being executed on the EDT or something like that? – Fildor Sep 03 '13 at 19:13
0

I tested your source code and "updating", "repainting" are one after each other. The problem is connected with your update() method. Maybe recursion, maybe loop.

Pawel
  • 1,457
  • 1
  • 11
  • 22
0

Assuming that gamePanel is a Swing component, what you're probably observing is that repaint() doesn't actually call JComponent.paintComponent(). All it does is essentially invalidates the component's graphics and tells Swing to repaint the component at a future point in time, on the Swing thread.

Multiple calls to repaint() don't necessarily result in multiple calls to paintComponent() - redundant repaint requests are collapsed into one.

TrogDor
  • 984
  • 6
  • 14
  • repaint calls paintComponent of course, and paintComponent is calling super.paintComponents(); – T_01 Sep 05 '13 at 07:51
  • The default implementation of repaint() does not. If you override it, it would be a useful thing to mention. – TrogDor Sep 06 '13 at 20:41