A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴新 中级黑马   /  2012-11-25 20:31  /  1152 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

求大牛给讲讲双缓冲机制!有图最好的说

4 个回复

倒序浏览
双缓冲,消除闪烁
   带着很严重的闪烁。这种现象在写游戏程序中是普遍存在的现象。这是由于我们的 repaint()函数导致的结果,由于它在调用paint()函数前会自动清除屏幕,所以在一个毫秒内我们会看到一个空白的屏幕,在快速的变换操作中就出现了闪烁现象。

  解决这种闪烁现象有几种方法,下面是两种方法的列举说明,其他的方式大家可以自己尝试。

  第一种:我们始终不清除屏幕显示,但是这个方法会带来个附作用,我们下降的圆不在是一个圆了,而是一条直线,因为它的下降过程中没有了断点,保留了所有的圆球的影象。我们只要在Ball.java内加上如下代码update(Graphics g) {paint(g)},你就会看到一条很长的线拉出来。有兴趣的朋友可以试试。

  第二种:使用双缓冲机制(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图形  

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
罗忠文 发表于 2012-11-25 20:47
双缓冲,消除闪烁
   带着很严重的闪烁。这种现象在写游戏程序中是普遍存在的现象。这是由于我们的 repa ...

那么 update paint 和 repaint 是按什么顺序执行的呢
回复 使用道具 举报
吴新 发表于 2012-11-25 21:03
那么 update paint 和 repaint 是按什么顺序执行的呢

update————>paint----------->repaint
回复 使用道具 举报
罗忠文 发表于 2012-11-25 21:21
update————>paint----------->repaint

真是谢谢了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马