为什么我的applet会为每次重绘而闪烁?

时间:2011-07-21 11:29:46

标签: java applet awt

我在线发现了一些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 个答案:

答案 0 :(得分:3)

简答:请勿在{{1​​}}方法中致电super.paint()

长答案: Applet也是一个具有自己的显示属性的容器,包括您通过Board.paint()设置的背景颜色作为构造函数的一部分。通过调用setBackground(Color.WHITE);,您可以使applet将其白色背景绘制到显示图形,以及调用任何包含的组件绘制。这是闪烁的原因 - 每个绘画周期,它将屏幕显示画为白色,然后将super.paint(g)图像复制到屏幕显示。

可能最好是明确的,忘记Applet背景,删除offscreenBuffer,然后自己完成所有绘制步骤。您需要将super.paint(g)替换为clearRect()setColor()

此外,您还应该实施fillRect()

update()

答案 1 :(得分:1)

Bonsai查看游戏引擎Ivo Wetzel。我很喜欢它。

它使用BufferStrategy,我认为这是双缓冲的最佳方法。