当前位置: 首页 > 知识库问答 >
问题:

小程序中的双缓冲是如何工作的?

和嘉澍
2023-03-14

我是从youtube关于制作Java游戏小程序的视频教程中编写这段Java代码的。然而,导师并没有真正解释一个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);     
            }

这里的闪烁是如何去除的?拥有图像对象有什么用?拥有另一个Graphics对象有什么用,为什么不使用参数Graphics呢?

共有1个答案

苍和裕
2023-03-14

双缓冲的一般思想是绘制速度很慢,如果你有很多东西要画,用户会注意到这一点,以闪烁的形式。取而代之的是,您对屏幕外的图像(一个缓冲区)进行所有的绘制。然后,当你准备好了,你交换了屏幕外的缓冲区,使它现在在屏幕上绘图。这种交换发生得非常快,因为它通常只是更新一个指针。

用户不再看到闪烁,因为所有的绘制工作都是在屏幕外完成的。

您发布的代码是双缓冲的一个变体。所有绘制工作都是在屏幕外对图像对象i完成的。绘制完成后,image对象就被复制到组件中,位于update方法的最后一行。

我之所以说variant是因为上面的代码没有交换缓冲区。相反,您将屏幕外缓冲区i复制到屏幕内缓冲区。它仍然可以消除闪烁,因为所有的渲染工作都是在屏幕外完成的。复制图像还是相当快的。

第二个graphics对象就在那里,因为在绘制时应该始终使用组件提供的对象。因此,上面的代码要求图像对象获取它的图形对象。但是,没有真正的理由将g2存储为成员变量,您可以每次在update中请求它。

 类似资料:
  • 问题内容: 我正在研究一个项目,并且在使用Java的双重缓冲方面已经读了尽可能多的内容。我想做的是向我的JFrame添加一个组件或面板或包含要绘制到其上的双缓冲表面的东西。如果可能,我想使用硬件加速,否则请使用常规软件渲染器。到目前为止,我的代码如下所示: 我创建了一个抽象的游戏类和一个调用Update和Draw的游戏循环。现在,如果您看到我的评论,那就是我主要关注的领域。有没有一种方法可以获取图

  • 问题内容: 到目前为止,我已经通过创建和图像完成了双重缓冲,使用其关联的Graphics对象向该图像绘制了我想要的图像,然后使用paint方法的Graphics对象将该图像绘制到了屏幕上。最近,我了解了BufferStrategy类及其用法。我想知道这两种方法的优缺点。 编辑:我认为我的问题不太清楚。我想知道DIY方法和BufferStrategy的优缺点,以及何时应该使用其中一种。 问题答案:

  • 问题内容: awt是否可以进行双缓冲(在Java中)?目前,我知道awt不应该与swing一起使用,所以我不能使用BufferStrategy之类的东西(我已经用awt编写了一些我不想在swing中重写的代码)。 如果使用awt可以进行双缓冲,我是否必须手动写入缓冲区?与swing不同,awt似乎没有相同的内置双缓冲功能。 如果必须手动编写代码,是否有一个不错的教程可以看?还是对于新手程序员来说,

  • 问题内容: 构造函数中的缓冲区大小是什么意思? 当我编写程序时: 输出: 然后,缓冲区大小是什么意思,正如我希望的那样,它只能读取两个字符。但事实并非如此。 问题答案: 顾名思义,缓冲输入。这意味着它会在将输入源传递给您之前从输入源读取到缓冲区。此处的缓冲区大小是指其缓冲的字节数。 从大多数来源读取输入非常慢。仅2个字节的缓冲区将损害性能,因为您的程序很可能大部分时间都在等待输入。缓冲区大小为2时

  • 上周我阅读了有关vertx的文档。我不明白的是vertx处理器是如何工作的?例如 和服务器是: (P.S.我知道我首先应该检查处理程序是否成功,然后采取一些措施,但为了简化代码,我删除了这种检查,如果在30秒内没有任何响应,则处理程序中会出现异常,也会从正式文档中删除。) 从上面的代码中,客户端每秒发送请求,并且不等待响应,但是它有一个处理程序,当响应到来时将执行该处理程序。 jdbcVertx监

  • 问题内容: 我想做的是在缓冲区上绘制图形,然后将其原样复制到画布上,这样我就可以制作动画并避免闪烁。但是我找不到这个选项。有人知道我该怎么做吗? 问题答案: 下面的有用链接除了显示使用双缓冲的示例和优点之外,还显示了使用html5 canvas元素的其他一些性能提示。它包含指向jsPerf测试的链接,这些链接将跨浏览器的测试结果汇总到Browserscope数据库中。这样可以确保性能提示得到验证。