Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you double buffer in java for a game?

So in the game I'm working on, I have a marble follow the mouse, but when it does this the screen flickers.

The background includes two jpegs and 9 rectangles. How would I go about double buffering this? Here is the code for the main window.

/**
 * Write a description of class Window here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Window extends JApplet implements MouseMotionListener
{
    private BufferedImage image; 
    private BufferedImage side;
    private int mouseX;
    private int mouseY;

    public Window(){
        try {
            image = ImageIO.read(new File("Backgrounds/violet.jpg"));
            side = ImageIO.read(new File("Backgrounds/side margin.jpg"));
        } catch (IOException ex) { }    
    }   

    private void delay(int delay)
    {
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {}
    }

    public void init()
    {
        this.addMouseMotionListener(this);
    }

    public void paint (Graphics page)
    {
        page.drawImage(image, 0, 0, null);
        page.setColor(Color.blue);
        page.fillRect(0, 0, 160, 160);
        page.setColor(Color.black);
        page.fillRect(15, 15, 130, 130);
        page.setColor(Color.green);
        page.fillRect(340, 0, 160, 160);
        page.setColor(Color.black);
        page.fillRect(355, 15, 130, 130);
        page.setColor(Color.yellow);
        page.fillRect(0, 340, 160, 160);
        page.setColor(Color.black);
        page.fillRect(15, 355, 130, 130);
        page.setColor(Color.red);
        page.fillRect(340, 340, 160, 160);
        page.setColor(Color.black);
        page.fillRect(355, 355, 130, 130);
        page.drawImage(side, 500, 0, null);
        page.drawString(Score.getScore(), 560, 110);
        //conveyors
        page.setColor(Color.gray);
        page.fillRect(235, 0, 30, 160);

        //marble
        delay(100);

        page.fillOval(mouseX, mouseY , 40, 40);          
    }

    public void mouseMoved(MouseEvent e)
    {
        mouseX = e.getX();
        mouseY = e.getY();
        repaint();
    }

    public void mouseDragged(MouseEvent e)
    {

    }
}
like image 655
Ryley Matos Avatar asked May 08 '12 23:05

Ryley Matos


People also ask

What is double buffering in Java?

Double-buffering is the process of drawing graphics into an off-screen image buffer and then copying the contents of the buffer to the screen all at once. For the complex graphics, using double-buffering can reduce flickering issues. Java Swing automatically supports double-buffering for all of its components.

What is double buffering in games?

In computer graphics, double buffering is a technique for drawing graphics that shows no (or less) stutter, tearing, and other artifacts. It is difficult for a program to draw a display so that pixels do not change more than once.

How does double buffering work?

Double buffering is a term used to describe a device with two buffers. The usage of multiple buffers increases the overall throughput of a device and helps prevents bottlenecks. For example, with graphics, double buffering can show one image or frame while a separate frame is being buffered to be shown next.


2 Answers

Double buffering is conceptually pretty simple, instead of drawing your objects one by one, you draw them on an image and then tell the renderer to draw that entire image. This eliminates the flickering.

Here's an example of how you might do this (source)

class DoubleBufferedCanvas extends Canvas {

    public void update(Graphics g) {
    Graphics offgc;
    Image offscreen = null;
    Dimension d = size();

    // create the offscreen buffer and associated Graphics
    offscreen = createImage(d.width, d.height);
    offgc = offscreen.getGraphics();
    // clear the exposed area
    offgc.setColor(getBackground());
    offgc.fillRect(0, 0, d.width, d.height);
    offgc.setColor(getForeground());
    // do normal redraw
    paint(offgc);
    // transfer offscreen to window
    g.drawImage(offscreen, 0, 0, this);
    }
}

Nowdays, you don't have to implement this yourself, you can use the BufferStrategy and releated classes. See lakam99's answer for an example of that .

like image 108
dfb Avatar answered Oct 16 '22 05:10

dfb


Swing supports double buffering automatically, so you don't need to code anything.

Just call setDoubleBuffered(true) on your top-level component (typically a JPanel) and it should all work.

See: setDoubleBuffered

like image 36
mikera Avatar answered Oct 16 '22 04:10

mikera