我正在使用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 回答
双缓冲的一般想法是绘图很慢,如果你有很多绘制,用户会以闪烁的形式注意到这一点 . 相反,您将所有绘图都设置为屏幕外图像(缓冲区) . 然后,当您准备好时,您将交换屏幕外缓冲区,以便它现在在屏幕上绘图 . 这种交换很快发生,因为它通常只是更新指针 .
用户不再看到闪烁,因为所有绘图工作都在屏幕外完成 .
您发布的代码是双缓冲的变体 . 所有绘图工作都在屏幕外完成Image对象
i
. 绘图完成后,然后将图像对象复制到update
方法的最后一行中的组件 .我说变种因为上面的代码没有交换缓冲区 . 而是将屏幕外缓冲区
i
复制到屏幕缓冲区i
. 它仍然消除了闪烁,因为所有渲染工作都在屏幕外完成 . 复制图像仍然非常快 .第二个
Graphics
对象存在,因为在绘制时应始终使用组件提供的对象 . 因此,上面的代码询问Image对象的Graphics对象 . 但是,没有真正的理由将g2
存储为成员变量,您每次只能在update
中请求它 .