1

I'm making a snake game and I've encountered an error.
I have tried two different loops: thread.sleep and Timer.schedule.
I have gotten the same problem.
It will be working fine, but at random intervals, it will start to skip every other frame for 6-10 frames.
In case I wasn't clear, 1 frame is

@Override public void paintComponent(Graphics G){...}

being called. (I have also tried paint)
This has occurred in some other games I've created, but not all. What can I do to fix it?

Here's a full copy of the code: https://github.com/jnmcd/Snake/blob/master/Code.java

EDIT: I've done some debugging. It appears that the it's not a problem with the paint. The JPanel doesn't always update. What can I do to fix it?

James McDowell
  • 2,668
  • 1
  • 14
  • 27
  • `paintComponent()` is called only when it needs to be called. If nothing changed (e.g. layouts were not invalidated, components weren't resized, etc) then `paintComponent` is not called even if you call `repaint()`. See the anwers in post for more info: http://stackoverflow.com/questions/15544549/how-does-paintcomponent-work – Mike Laren Jun 29 '15 at 19:28
  • I've tried paint() instead of paintComponent(). No change. Plus, I trigger it with a repaint(). – James McDowell Jun 29 '15 at 19:29
  • *"I have tried two different loops: thread.sleep and Timer.schedule"* - There's a concern, Swing is not Thread safe, so be careful if you're updating the UI or UI state from them – MadProgrammer Jun 29 '15 at 21:13
  • There are at least two issues that I can see, the first is, you could be producing a race condition between the timer and Swings paint process, meaning that it's possible for Swing to pant your UI WHILE the task is updating the state, which would produce some weird results, – MadProgrammer Jun 29 '15 at 21:21
  • The second is you're understanding of the paint process. Swing uses passive rendering engine, meaning painting can occur at any time and is up to the discretion of the api, while you can make suggestions that the UI should be updated (repaint), the api can ignore or optimise the results (compressing repeated requests down to a single request for example) – MadProgrammer Jun 29 '15 at 21:22
  • You're reliance on will come back to haunt you – MadProgrammer Jun 29 '15 at 21:23

2 Answers2

1

I found what I needed to do. I had to add a revaidate() after the repaint().

James McDowell
  • 2,668
  • 1
  • 14
  • 27
  • Ts is more of an indication of a larger problem them a soliton, a you're not modifying the state of the components layout and normally, you revalidate the container before you paint it – MadProgrammer Jun 29 '15 at 21:16
0

Also In the checkKillCollisions you have to break the loop right after you found the losing condition.

Also if the game ends it keeps on showing the error message[Dialog] for which there i no end.So I have created a flag gameOver to check is game is over or not in Snake Class

 static Boolean gameOver = false;//Defined in Snake Class


 public void checkKillCollisions() {
    boolean lose = false;
    for (int i = 1; i < Snake.segments.size(); i++) {
        if (Snake.segments.get(i).x == x && Snake.segments.get(i).y == y) {
            lose = true;
            break;//Have to do this
        }
    }
    if (x >= 60 || x < 0 || y >= 60 || y < 0) {
        lose = true;
    }
    if (lose) {
        Snake.window.popUp("You Lose");
    }
    Snake.gameOver = lose;//Will set the gameOVer flag in Snake class
}

And I've modified the Loop class to stop running right after the gameOver flag is set to true

 class Loop extends TimerTask {

@Override
public void run() {
    if (!Snake.gameOver) {
        Snake.updates();
        Snake.window.render();
    } else {
        System.out.println("Game Over");
        cancel();
        Snake.window.dispose();
    }
}
}
Madhan
  • 5,750
  • 4
  • 28
  • 61
  • 1
    I know it doesn't close on game over. I don't intend it to. I just need to write the gameOver function. I had that in as a placeholder. I also modified it so if you go off the edge, it wraps over to the other side instead of game over. – James McDowell Jun 29 '15 at 20:13