Почему мой апплет мигает при каждом перекрашивании? - PullRequest
1 голос
/ 21 июля 2011

Я нашел в сети код Java-игры и пытаюсь его изменить.Я преобразовал его из JFrame в Applet, но моя игра начинала мигать каждый раз, когда я перекрашивал экран.Я пробовал двойную буферизацию, но без разницы.

Источник:

    private void paintDisks(Graphics g) {
        try {
            for (Disk d : disk)
                paintDisk(g, d);
        } catch (Exception ex) {
            //System.out.println(ex.getMessage());
            paintDisks(g); // retry so the disks never not get painted
        }
    }
    private void paintDisk(Graphics g, Disk d) {
        if (d == null)
            return;
        if (diskimg[d.player] == null) {
            g.setColor(colour[d.player]);
            g.fillOval((int)d.x - 1, (int)d.y - 1, 32, 32);
        } else {
            g.drawImage(diskimg[d.player],
                       (int)d.x - 1, (int)d.y - 1,
                        32, 32, this);
        }
    }

    @Override
    public void paint(Graphics g) {
        // paint real panel stuff
        super.paint(g);

        Graphics gr; 
        if (offScreenBuffer==null ||
              (! (offScreenBuffer.getWidth(this) == this.size().width
              && offScreenBuffer.getHeight(this) == this.size().height)))
        {
            offScreenBuffer = this.createImage(size().width, size().height);
        }

        gr = offScreenBuffer.getGraphics();

        gr.clearRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this));

        // paint the disks
        paintDisks(gr);

        // paint the curser ontop of the disks
        paintCurser(gr);

        g.drawImage(offScreenBuffer, 0, 0, this);   
    }

    @Override
    public void run() {

        while (true) {
            repaint();

            try {
                Thread.sleep(9, 1);
            } catch (InterruptedException ex) {
                System.out.println(ex.getMessage());
            }
        }
    }

}

Ответы [ 2 ]

3 голосов
/ 21 июля 2011

Краткий ответ: не вызывайте super.paint() в вашем методе Board.paint().

Длинный ответ: Апплет также является контейнером с собственными свойствами отображениявключая цвет фона, который вы устанавливаете с помощью setBackground(Color.WHITE); как часть вашего конструктора.Вызывая super.paint(g), вы заставляете апплет закрашивать свой белый фон отображаемой графикой, а также вызываете рисование любого содержащегося компонента.Это является причиной мерцания - каждый цикл рисования, это рисование на экране белым цветом, а затем копирование вашего offscreenBuffer изображения на экранном дисплее.

Вероятно, это лучше, чтобы быть явным, забудьтео фоне апплета удалите super.paint(g), и просто сделайте все шаги рисования самостоятельно.Вам нужно будет заменить clearRect() на setColor() и fillRect().

Также вам следует реализовать update().

@Override
public void update(Graphics g) { paint(g); }

@Override
public void paint(Graphics g) {
    // no super.paint(g)

    if (offScreenBuffer==null ||
          (! (offScreenBuffer.getWidth(this) == this.size().width
          && offScreenBuffer.getHeight(this) == this.size().height)))
    {
        offScreenBuffer = this.createImage(size().width, size().height);
    }

    Graphics gr = offScreenBuffer.getGraphics();

    // blank the canvas
    gr.setColor(Color.WHITE);
    gr.fillRect(0,0,offScreenBuffer.getWidth(this),offScreenBuffer.getHeight(this));

    // paint the disks
    paintDisks(gr);

    // paint the curser ontop of the disks
    paintCurser(gr);

    g.drawImage(offScreenBuffer, 0, 0, this);   
}
1 голос
/ 21 июля 2011

Взгляните на игровой движок Бонсай от Иво Ветцель .Мне это очень нравится.

Используется BufferStrategy, что, я думаю, лучший способ удвоить буфер.

...