Java中的repaint()方法,实际上调用两个方法:update(),paint()。
解决重绘闪烁:
1.始终不清屏。
2.使用双缓冲机制(Double buffering)
1.
//以下是一小球下落的动画,加上update后,虽然屏幕不闪烁,但屏幕也不更新。
import java.awt.*;
import java.applet.*;
public class Ball extends Applet implements Runnable
{
int x = 100;
int y = 20;
int r = 10;
public void init() { }
public void start()
{
Thread thd=new Thread(this);
thd.start();
}
public void stop() { }
public void destroy() { }
public void run ()
{
while(true)
{
y+=1;
repaint();
try
{
Thread.sleep (20);
}
catch (InterruptedException ex)
{
}
}
}
public void paint (Graphics g)
{
//设置球的颜色
g.setColor (Color.blue);
// 从x,y位置处画一个实心的圆
g.fillOval (x , y, 2 * r, 2 * r);
}
}
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
if (bgImage == null)
{
bgImage = createImage (this.getSize().width, this.getSize().height);
bg = bgImage.getGraphics ();
}
// 后台清屏,即设置圆球组件和后台一样的颜色,大小
bg.setColor (getBackground ());
bg.fillRect (0, 0, this.getSize().width, this.getSize().height);
// 绘制相应的元素组件
bg.setColor (getForeground());
paint (bg);
// 在屏幕上重画已经绘制好的圆
g.drawImage (bgImage, 0, 0, this);
}
此处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测试的内定值设定。
本文介绍Java中repaint()方法调用update()和paint()方法的情况,探讨解决重绘闪烁问题的方法。一是始终不清屏,二是使用双缓冲机制。详细说明了双缓冲机制的原理、实现步骤及代码示例,还介绍了不同缓冲机制(单缓冲、双缓冲、三缓冲)的特点。
242

被折叠的 条评论
为什么被折叠?



