Java中的repaint()方法,实际上调用两个方法:update(),paint()。
解决重绘闪烁:
1.始终不清屏。
2.使用双缓冲机制(Double buffering)
1.
//以下是一小球下落的动画,加上update后,虽然屏幕不闪烁,但屏幕也不更新。
import java.awt.*;
import java.applet.*;
public class Ball extends Applet implements Runnable
{
}
2.使用双缓冲机制(Double buffering)
而我们的程序中简单的说就是在显示我们想要的图画之前,把所有的图画先在后台绘制好并存放到相应的图像变量中去。当需要显示时直接复制到前台屏幕就可以了。
具体实现:
1.首先我们用createImage方法新建一后台图像类变量
2.然后使用getGraphics()方法得到当前图像的图形关联
3.在后台处理所有相关的处理,如清除屏幕,后台绘画等等
当完成所有的后台工作后,复制已经绘制好的图像到前台,并覆盖前台的存在图像。这样我们的所有操作都是在后台前行,在屏幕显示新的图像前,这些内容都已经存在于后台了。所以你也将在任何时刻都看不到空屏幕的存在。也即代表闪烁消除了。
下面我们来看看相关的代码说明:
在开始之前我们得先在程序的开始部分声明两个实例变量用来存储后台图画。如下:
private Image bgImage; private Graphics bg; |
然后我们利用update()方法来实现双缓冲机制。
Update()方法要实现下面三个步骤:
1.清除屏幕上的组件
2.设置相关联组件的前景色
3.调用paint方法重画屏幕
public void update (Graphics g) // 初始化buffer bgImage = createImage (this.getSize().width, this.getSize().height); } // 后台清屏,即设置圆球组件和后台一样的颜色,大小 // 绘制相应的元素组件 // 在屏幕上重画已经绘制好的圆 } |
此处g 为屏幕图形,bg为g的后台关联。而bgimage包含了bg图形。请于此处来看看我们的源代码例子及演示效果。
附:缓冲机制
. 缓冲区缓冲区用来储存着色的像素(影像)在视频内存中的区域。缓冲区的大小由解析度和色深决定,例如800x600,16bit色的缓冲区就占用800x600x2(16bit=2bytes)的内存区域。
(1) 前置Buffer是当前显示在萤幕上的缓冲区,后置Buffer是尚未显示在萤幕上的缓冲区。
(2) Single Buffering使用一个前置缓冲区,在着色的同时影像立即显示在萤幕上。因此当萤幕更新影像时会出现闪烁的现象。Single Buffering在目前的程序中已很少使用。
(3) Double Buffering则使用两个缓冲区,一个前置Buffer,一个后置Buffer。所谓前置和后置是相对而言的。前置缓存的像素在屏幕上显示的同时,显卡正在紧张地着色后置缓存中的像素。
后置缓存的像素上色完毕后是以Vsync信号的形式等待。在前置缓存和后置缓存交换后,新一轮的着色工作又重新开始。这正如舞台话剧中前台和后台的演员一般。在前台演员表演时,后台的演员仍在进行最后的排练。前台的演员下场时正是后台演员登场的时间。唯一不同的是前置和后置缓存是循环轮番上阵,而演员表演完毕一般都不再出场。目前大多数游戏内定都使用Double Buffering。
(4) Triple Buffering使用一个前置缓存和两个后置缓存。在着色完第一个后置缓冲区的数据后,立即开始处理第二个后置缓冲区。今天,不少新游戏都采用的是Triple Buffering,Trible Buffering正逐渐成为发展的趋势,因为它没有Vsync(萤幕的垂直刷新频率)等待的时间,游戏也将更加流畅。Triple Buffering也是3Dmark2000测试的内定值设定。