Как вы двойной буфер в Java для игры?

Так что в игре, над которой я работаю, у меня есть мрамор, следящий за мышью, но когда это происходит, экран мерцает.

Фон включает в себя два JPEG и 9 прямоугольников. Как бы я пошел о двойной буферизации этого? Вот код для главного окна.

/**
 * 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)
    {

    }
}

4 ответа

Двойная буферизация концептуально довольно проста, вместо того, чтобы рисовать ваши объекты один за другим, вы рисуете их на изображении, а затем просите рендерер нарисовать все это изображение. Это устраняет мерцание.

Вот пример того, как вы могли бы сделать это ( источник)

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

В настоящее время вам не нужно реализовывать это самостоятельно, вы можете использовать BufferStrategy и выпущенные классы. Посмотрите ответ lakam99 для примера этого.

Swing автоматически поддерживает двойную буферизацию, поэтому вам не нужно ничего кодировать.

Просто позвони setDoubleBuffered(true) на вашем компоненте верхнего уровня (обычно JPanel), и все должно работать.

Увидеть: setDoubleBuffered

Другое решение - использовать библиотеку, которая удвоит для вас буфер. Поскольку вы используете Java2D, я предполагаю, что вы хотите сохранить все довольно легким и более низким уровнем. Я думаю, что Slick2D отлично справляется с предоставлением простых, двумерных функций рисования и ввода, не мешая вам. Это похоже на более элегантную версию Java2D, но написано на OpenGL. Как только вы создадите несколько приложений на чистой Java, я думаю, что переход на Slick2D - это БОЛЬШАЯ идея. Это не прямое решение вашей проблемы, но, поскольку оно уже решено, я подумал, что дам несколько советов, которые облегчат вашу жизнь в разработке Java-игр. Проверьте это, если у вас есть шанс http://slick.cokeandcode.com/

Я думаю, что ваша проблема не в двойной буферизации. Вы должны добавить super.paint(page); в первой строке вашего метода рисования.

Другие вопросы по тегам