0

game loop:

private int FPS = 25;
private int targetTime = 1000 / FPS;

public void run(){

    init();

    long start;
    long elapsed;
    long wait;

    while (running){

        start = System.nanoTime();
        init();
        repaint();
        elapsed = System.nanoTime()  - start;

        wait = targetTime - elapsed / 1000000;

        try {

            Thread.sleep(wait);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

the paint method:

/**draws the game graphics*/
public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2 = (Graphics2D)g;

    gameStateHandler.draw(g2);

}

the method the that the paint method refers too:

private static  Image image = resourceLoader.getImage("/background/menu_background.png");
/**draws the menu state*/
public static void draw(Graphics2D g){

    g.drawImage(image, 0, 0, null);
}

i call the image from this method which is in the same folder of the image

static resourceLoader rl = new resourceLoader();

public static Image getImage(String image){

    return Toolkit.getDefaultToolkit().getImage(rl.getClass().getResource(image));
}

i have a game loop that it will call repaint(); 60 times per second and in the paint method it refers to a method where this method draws an image. everything seems nice and smooth and when i run the program the image appears and disappears at a fast time and sometimes the image appears and nothing bad happens but after a random amount of time the thing happens i changed the fps from low to high and from high to low still the same im using jpanel in this project

  • 1
    How/where is your `image` created/manipulated? – JimmyB Dec 14 '15 at 12:27
  • Sounds like a lack of double buffering http://content.gpwiki.org/index.php/Java%3aTutorials%3aDouble_Buffering – weston Dec 14 '15 at 12:28
  • @weston Thought so too, but blitting an image to the canvas should be as fast as it gets for updating the display. – JimmyB Dec 14 '15 at 12:30
  • For double buffering, you may also look here: http://stackoverflow.com/questions/10508042/how-do-you-double-buffer-in-java-for-a-game – JimmyB Dec 14 '15 at 12:30
  • @HannoBinder I found that too, but there are no really great answers on that question. – weston Dec 14 '15 at 12:31
  • @HannoBinder yes I guess it's not a problem for this case, they effectively are double buffering. – weston Dec 14 '15 at 12:32
  • I think we need to see more code, like Hanno said - where is the `image`, where is it being instantiated, why are we calling a method `draw()` (is it overloaded), and so on. If the OP is using a `Canvas`, too, I'd recommend dropping it for a `JPanel` and overriding `paintComponent()` instead of `paint()`. – Gorbles Dec 14 '15 at 12:35
  • my image is an png type in the project root (aka res folder) i created from a program and i putted in the project root @HannoBinder – Heroxlegend Dec 14 '15 at 13:08
  • i edited and added the code in the question @Gorbles – Heroxlegend Dec 14 '15 at 13:19
  • Are you using a `Canvas`? What are you drawing onto? – Gorbles Dec 14 '15 at 14:58
  • no i'm using jpanel @Gorbles – Heroxlegend Dec 14 '15 at 15:12

3 Answers3

0

Don't use Thread.sleep(). It can cause stutters if invoked on the EDT.

For swing you should use javax.swing.Timer:
1. Initialize the Timer with the required delay (your targetTime).
2. On timer actionPerformed() call repaint().

Leet-Falcon
  • 2,107
  • 2
  • 15
  • 23
  • `Thread.sleep()` *can* cause stutters but will not presuming your target framerate is acceptable. Certainly, drawing one image to your screen will not cause unnecessary delay on vaguely-modern hardware, especially at the target rate of 25FPS. I'm not sure your advice will help here, unfortunately. – Gorbles Dec 14 '15 at 12:33
0

In your game loop, after

 wait = targetTime - elapsed / 1000000;

add the line

 wait = Math.max(5L, wait);

to keep your wait time from getting too small or going negative.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

Okay, so there's a recommendation here, which could well be the fix you need:

Use paintComponent() instead of paint()

// draws the game graphics

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;    
    gameStateHandler.draw(g2);    
}

paintComponent is the recommended way to use JPanels to paint in Java - see also a more detailed explanation of custom painting in Swing. It could well be that your use of paint() is what's causing your visual inconsistencies.

Failing that, I recommend looking at how you're loading your resource, but that should work, so I don't think it's the issue.

Gorbles
  • 1,169
  • 12
  • 27