2

I can see from Google searches that this question gets asked a lot, but none of the solutions I find are doing it for me. I'm making a game in Java with images, you know, since games generally have that stuff. But the entire form is constantly flickering and I can't get it to stop. Yes, I have double buffered it and overridden the update() method, and while that definitely helped, the flickering still persists. I don't know if I'm doing something wrong with the double buffering, or if I need something completely different.

At first I thought maybe it had something to do with the clearRect() line, but upon removing it, the game still flickered but of course wasn't cleared each time. So that didn't help at all. Upon slowing down the timer the flickering does go away almost entirely, but I need to slow it down to 100ms and even then I still get some flicker. Besides, that is simply too slow for the game. I tried having one timer doing everything on a 10ms timer, with a separate one at 100ms for painting, but it just looks jumpy then. I can slow the painting timer down to about 30ms and have it still be smooth, though the flickering is still an issue.

There must be a way of doing this every 10-30ms without flickering. Is there some other method similar to double buffering but better in this case, or something I can use? Thanks in advance for any help.

public class main extends JApplet implements ActionListener {
    //This Declares The Variables
    Graphics2D buffer;
    Image offscreen;
    Timer timGame = new Timer(10, this);
    //other variables

    public void init(){
        //This Creates The Offscreen Buffer Zone
        offscreen = createImage(getSize().width, getSize().height);
        buffer = (Graphics2D)offscreen.getGraphics();
        //other initialization stuff irrelevant to drawing
    }

    public void actionPerformed(ActionEvent evt){
        if (evt.getSource() == timGame)
            runGame();
    }

    private void runGame(){
        //Do stuff, move objects
        repaint();
    }

    public void paint(Graphics g){
        super.paint(g);

        buffer.clearRect(0, 0, getSize().width, getSize().height);
        //draw stuff to buffer
        g.drawImage(offscreen, 0, 0, this);
    }

    public void update(Graphics gr){
        paint(gr);
    }
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Doug
  • 387
  • 2
  • 10
  • 20
  • 1
    possible duplicate of [JApplet - super.paint(); causes flicker](http://stackoverflow.com/questions/7004866/japplet-super-paint-causes-flicker) – Hovercraft Full Of Eels May 04 '12 at 03:13
  • Are you seeing [vsync tearing](http://en.wikipedia.org/wiki/Screen_tearing) from trying to update the screen _too quickly_? 60 Hz refresh rate works out to around 17 ms per frame... – sarnold May 04 '12 at 03:16
  • Clearing the super.paint() line fixed the issue. I knew it was something stupid like that. I guess that's what I get for painting it normally, then coming back later to double buffer it. I'll look into the PaintComponent as well, though I'm a bit busy to look at it at the moment. Hopefully it can help too, though for at least right now the flickering has stopped entirely. I can even bump up the timer back to 10ms :) Thanks a lot. – Doug May 04 '12 at 03:45

1 Answers1

9

Don't paint directly into the paint(...) method of a top-level window such as a JApplet or a JFrame as you lose all double buffering and all Swing goodies. Instead draw in the paintComponent(...) method of a JPanel or other JComponent-derived component (including JComponent itself) that you add to the JApplet.

If you search on this subject here or in Google, you will see that it has been asked and answered many many times on this and other sites, and the answer is the same.

e.g.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373