applet 中的双缓冲是如何工作的?

Posted

技术标签:

【中文标题】applet 中的双缓冲是如何工作的?【英文标题】:How does double buffering in applets work? 【发布时间】:2015-03-17 00:25:14 【问题描述】:

我正在从 youtube 上有关制作 Java 游戏小程序的视频教程中编写此 Java 代码。但是,讲师并没有真正解释小程序的更新方法是如何实现他所称的双缓冲的。

导入 java.awt.*; 导入 java.applet.Applet; 公共类 Game 扩展 Applet 实现 Runnable 私人图像 i; 私有图形 g2; 私有 int x, y, dx = 1, dy = 1, 半径 = 10; ... 公共无效更新(图形g) 如果(我==空) i = createImage(getHeight(), getHeight()); g2 = i.getGraphics(); g2.setColor(getBackground()); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setColor(getForeground()); 油漆(g2); g.drawImage(i, 0, 0, null); 公共无效油漆(图形g) x+=dx; y+=dy; g.setColor(Color.RED); g.fillOval(x, getHeight() - y, 半径 * 4, 半径 * 4); g.setColor(Color.BLUE); g.fillOval(getWidth() - x - 半径, y, 半径 * 4, 半径 * 4); g.setColor(Color.GREEN); g.fillOval(x, y, 半径 * 4, 半径 * 4); g.setColor(Color.YELLOW); g.fillOval( getWidth() - x , getHeight() - y , 半径 * 4, 半径 * 4);

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

【问题讨论】:

【参考方案1】:

双缓冲的一般概念是绘制很慢,如果你要绘制很多,用户会以闪烁的形式注意到这一点。取而代之的是,您将所有绘图都绘制到屏幕外图像(缓冲区)上。然后,当您准备好时,您交换 屏幕外缓冲区,因此它现在正在屏幕上绘制。这种交换发生得非常快,因为它通常只是更新一个指针。

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

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

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

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

【讨论】:

以上是关于applet 中的双缓冲是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

带有文本覆盖的双缓冲 AlphaBlend rect

消费者生产者模型中的双缓冲 OpenGL 对象

C 和 Windows GDI 中的双缓冲 *framework*

winform的双缓冲

最佳实践生产者和消费者模式中的双缓冲技术

基于c#的双缓冲技术画图