首页 文章

applet中的双缓冲如何工作?

提问于
浏览
0

我正在使用youtube上的视频教程编写Java代码来制作Java游戏applet . 但是,教师并没有真正解释applet的更新方法如何在他调用时进行双缓冲 .

import java.awt.*;
    import java.applet.Applet;
    public class Game extends Applet implements Runnable {

    private Image i;
    private Graphics g2;
    private int x, y, dx = 1, dy = 1, radius = 10;

    ...
    public void update(Graphics g) {
                if ( i == null ) {
                    i = createImage(getHeight(), getHeight());
                }
                g2 = i.getGraphics();

                g2.setColor(getBackground());
                g2.fillRect(0, 0, getWidth(), getHeight());

                g2.setColor(getForeground());
                paint(g2);
                g.drawImage(i, 0, 0, null);
            }


    public void paint(Graphics g) 
            {
                x+= dx;
                y+= dy;
                g.setColor(Color.RED);
                g.fillOval(  x, getHeight() - y, radius * 4, radius * 4);
                g.setColor(Color.BLUE);
                g.fillOval( getWidth() - x - radius, y, radius * 4, radius * 4);
                g.setColor(Color.GREEN);
                g.fillOval( x, y, radius * 4, radius * 4);
                g.setColor(Color.YELLOW);
                g.fillOval( getWidth() - x , getHeight() - y , radius * 4, radius * 4);     
            }

如何消除闪烁?拥有Image对象有什么用?有另一个Graphics对象有什么用,为什么不使用参数Graphics?

1 回答

  • 4

    双缓冲的一般想法是绘图很慢,如果你有很多绘制,用户会以闪烁的形式注意到这一点 . 相反,您将所有绘图都设置为屏幕外图像(缓冲区) . 然后,当您准备好时,您将交换屏幕外缓冲区,以便它现在在屏幕上绘图 . 这种交换很快发生,因为它通常只是更新指针 .

    用户不再看到闪烁,因为所有绘图工作都在屏幕外完成 .

    您发布的代码是双缓冲的变体 . 所有绘图工作都在屏幕外完成Image对象 i . 绘图完成后,然后将图像对象复制到 update 方法的最后一行中的组件 .

    我说变种因为上面的代码没有交换缓冲区 . 而是将屏幕外缓冲区 i 复制到屏幕缓冲区 i . 它仍然消除了闪烁,因为所有渲染工作都在屏幕外完成 . 复制图像仍然非常快 .

    第二个 Graphics 对象存在,因为在绘制时应始终使用组件提供的对象 . 因此,上面的代码询问Image对象的Graphics对象 . 但是,没有真正的理由将 g2 存储为成员变量,您每次只能在 update 中请求它 .

相关问题