关于Java swing双缓存实现消除闪烁

  这几天一直纠结游戏界面的淡入淡出怎么实现。之前终于了解可以用AlphaComposite修改图片的alpha值,加以延时可以实现淡入淡出,但界面闪得很厉害。

  之前做图形编程的时候也知道,这是图片没有绘制完成然后显示到屏幕的原因。什么意思呢?就比方说一个运动的小球,实现的效果是先画小球,然后擦除,然后在新位置重绘小球。显然,擦除是不应该被显示到屏幕上的。小球到重绘的时候再显示到屏幕才是。曾经用过OpenGL写过一个2.5D的游戏,也要用到双缓冲,可那时候用的双缓存就一个API函数就搞定了。现在要在Java swing上实现双缓存消除闪烁应怎么做呢?

 

  在Java swing中,绘制的原理如下:

     update() -> paint(Graphics g) -> paintComponent(Graphics g)

  它们是逐渐调用的,Java swing内置有双缓冲,在paint(Graphics g)中。

  假如我们的图像绘制在JPanel上,我们可以继承JPanel,然后复写里面的paintComponent(Graphics g)和update方法。我们可以在paintComponent上绘制图像,然后调用paint方法就可以调用paintComponent方法绘制图像。

 

 双缓冲的实现:

  复写JPanel类中的update()方法,新建一个图像缓存空间,然后把它的画笔拿过来,用paint方法把要绘制的东西绘制上去。再一次性把图像显示在JPanel控件上。

public class MyPane extends JPanel {

     private Image image;   //你要绘制的图形
     private Image offScreenImage;  //图形缓存
     


     public MyPane(Image img) {
      this.image = img;
     }
    
     @Override
    public void paintComponent(Graphics g) {
         super.paintComponent(g);
         Graphics2D g2d = (Graphics2D)g;
         //................

         //.........你要绘制的东西

     }
     public void update(Graphics g) {
      if(offScreenImage == null)
       offScreenImage = this.createImage(800, 600);   //新建一个图像缓存空间,这里图像大小为800*600
         Graphics gImage = offScreenImage.getGraphics();  //把它的画笔拿过来,给gImage保存着
         paint(gImage);                                                      //将要画的东西画到图像缓存空间去
         g.drawImage(offScreenImage, 0, 0, null);            //然后一次性显示出来
     }

 

    public void animation() {

       try {                                                                        //延时,然后调用update(getGraphics),更新画面
         Thread.sleep(15);
       } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    update(getGraphics());

   }

}

 

 

 

 

你可能感兴趣的:(关于Java swing双缓存实现消除闪烁)