a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 158|回复: 0

[专业语言] JAVA认证:双缓冲原理在实现如何消除闪烁(3)

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
那么怎么通过其他的方法消除swing中的闪烁问题呢,我们此时再回到出发点,双缓冲的核心就是改变paint(g)中的画布,那么好了,我直接在paint(g)函数里实现不就得了,下面再来看这一段代码:
1 ^; A  K, Z" g  r    Java代码
6 z# N5 t4 R( ]0 a$ C    public void paint(Graphics g)6 I! Z% ^4 |5 |1 {  {# d
    {
# H0 z% @7 Y# a( f& ?% z" s    // 在重绘函数中实现双缓冲机制
2 k; Q- j) J3 N; q3 E5 P+ K    offScreenImage = this.createImage(WIDTH, HEIGHT);
# t$ t  z) O# S( b    // 获得截取图片的画布
9 q* E9 y, D" ?: g# j  t    gImage = offScreenImage.getGraphics();2 f; r8 h* s1 A  E# r" e: r: `$ Z
    // 获取画布的底色并且使用这种颜色填充画布,如果没有填充效果的画,则会出现拖动的效果
- [; f4 T1 h# J1 d    gImage.setColor(gImage.getColor());' g; p- ^4 b; d. H' G* l4 R4 B
    gImage.fillRect(0, 0, WIDTH, HEIGHT); // 有清楚上一步图像的功能,相当于gImage.clearRect(0, 0, WIDTH, HEIGHT)* K, b( Y# k! ~( z) `
    // 调用父类的重绘方法,传入的是截取图片上的画布,防止再从最底层来重绘
; ~2 N" o. t6 s) ]9 M) b: `    super.paint(gImage);1 g3 k# [: P& V; d- n
    // 当游戏没有结束的时候绘出对战双方
3 s# W5 G  _% |8 R3 u# a    if (!getGameOver()) {
$ n" T! w0 B! K# c. P    // 画出自己的坦克
7 j2 ], S, e) `) J2 T    paintMyTank(gImage);5 Q- V  ]" ^0 K+ b. b
    // 画出自己坦克发射的子弹! y6 S, k0 \& u/ y; r7 Q
    paintMyBullet(gImage);2 z  i! T7 I. K1 y, \
    // 画出敌方坦克$ n6 y7 x5 j$ @( X0 a% @
    paintEnemyTank(gImage);1 j: [# u1 k' }1 k( j8 b/ P
    // 画出敌方坦克发射的子弹
: V1 Q4 j! V- O& e! q' [, H* _$ V    paintEnemyBullet(gImage);& o6 l# M9 r; o# T- F. r4 ^1 Z
    }
; Z6 ^) ^' P/ C: U, y    // 画出草地, T2 Z& W' \5 a5 f9 w) |; n
    paintGrass(gImage);
. D  E+ V. i+ ]! _1 _4 z' L3 j    // 画出小河/ Y; l: t: g/ K: H* Q
    paintRiver(gImage);
3 A0 t/ M" T) j. ~    // 画出石头# \* j7 \0 D! V2 |
    paintStone(gImage);$ B, ~/ T. ^3 G7 J1 S; Q
    // 画出各种道具
1 F2 V" m5 s/ i    paintTool(gImage);" U  X8 F& _* ?
    // 将接下来的图片加载到窗体画布上去,才能考到每次画的效果
4 k& X8 b' E# z& S7 F  {    g.drawImage(offScreenImage, 0, 0, null);6 L: c9 h- n8 u2 S
    }& }+ g/ O+ f: g& g
    有一些相似的部分吧,其中最重要的是super.paint(gImage)这句,改变画布在这里,消除闪烁也是在这里!!!
; J& R4 M0 p3 R    下面我们再探讨最后一个问题,即如何理解swing中内置双缓冲,我们首先从继承体系来看,JFrame->Frame->Window->Container->Component,在Frame中的update()方法是从Container中继承而来的,而JFrame中却重写了update()方法如下6 _; q6 ?; m- m9 u3 S" O
    Java代码- {9 w1 i9 V% s% n
    /**, R$ p2 u3 }( K; k
    * Just calls paint(g).  This method was overridden to
, G; R' Y9 Y, W) n9 D    * prevent an unnecessary call to clear the background.
  ~6 }0 d% H2 ?& B! X    *: H5 H7 `" Y7 h. q' u: h
    * @param g the Graphics context in which to paint, @+ h% T" E7 d0 v/ i+ K! I/ ^3 j
    */
! F7 s  f* E5 y$ s9 R/ c$ e    public void update(Graphics g) {" Z, J' Q1 @0 M- H2 o. V
    paint(g);$ ~) a5 O6 m2 F+ }6 _2 h
    }
/ e4 Z  f  e0 Q' C; _) G# X% u    与之前的同名方法相比,这里直接调用了paint()函数而没有clearRect(),也就是清屏的方法,这里他试图不通过清屏来阻止闪烁的发生。这也就是JFrame本身的一种处理方法。6 b0 |0 k$ H$ e* w  ?' p
    以上是通过自己对双缓冲的一些理解,其中还有很多问题,希望牛人们能够积极指出来,并且一起讨论这个问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-6 19:07 , Processed in 0.368040 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表