使用双缓冲技术解决动画播放闪烁问题

双缓冲技术主要就是使多张图像在后台绘制到一张图像上,然后把这一张图像绘制到显示屏幕上来解决多次绘制导致的屏幕闪烁

就比如如下的方法,传入系统屏幕的画笔g,然后在后台上创建一个和屏幕一样大的图像iBuffer,再获得iBuffer的画笔gBuffer,

通过画笔gBuffer把图像画到iBuffer上面,这就是在后台完成图像的绘制,最终调用系统的画笔g把后台绘制完成的图像画到屏幕上

/**
	 * 绘制方法
	 * 采用双缓冲技术
	 */
	public void onDrow(Graphics g) {
		//判断后台图像是否为空  
		if(iBuffer == null){  
			//如果为空,则创建一个和当前界面一样大小的缓冲图像,再取得这个图像的画布对象gBuffer  
			iBuffer = createImage((int)this.getSize().getWidth(),(int)this.getSize().getHeight());  
		}
		//获得该图像的画笔
		gBuffer = iBuffer.getGraphics();  
		//用背景色填充图像(清理画面) 
		//一般如果有背景图的话,本段就可以不用了
		gBuffer.setColor(getBackground());  
		gBuffer.fillRect(0, 0, (int)this.getSize().getWidth(), (int)this.getSize().getHeight()); 
		
		gBuffer.drawImage(image.getSubimage(ax, ay, w, h), 1000, 300, 50, 75, null);
		
		//在界面上直接画出缓冲图像  
		g.drawImage(iBuffer,0,0,this); 
	}

最终贴上完整代码,其中的图片可以酌情换成其他4*4的人物行走素材图片

package com.ljxt.SwingTest;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class SwingTest extends JFrame{	
	
	public static int count = 0;
	
	public static int screenWidth;
	public static int screenHeight;
	
	public static BufferedImage image;
	
	boolean isRun = true;

	Image iBuffer;
	Graphics gBuffer;
	static int ax = 0;
	int ay = 0;
	int w;
	int h;
	
	public static void main(String[] args) {
		//初始化设置
		SwingTest swingTest = new SwingTest(true);
		//显示窗体
		swingTest.setVisible(true);
		//开始循环绘制
		swingTest.action();
		
	}
	
	/**
	 * 开启线程
	 */
	public void action() {
		new Thread(run).start();
	}
	
	/**
	 * 绘制图像
	 */
	public void paint(Graphics g) {
		//调用绘制方法
		onDrow(g);
	}
	
	/**
	 * 绘制方法
	 * 采用双缓冲技术
	 */
	public void onDrow(Graphics g) {
		//判断后台图像是否为空  
		if(iBuffer == null){  
			//如果为空,则创建一个和当前界面一样大小的缓冲图像,再取得这个图像的画布对象gBuffer  
			iBuffer = createImage((int)this.getSize().getWidth(),(int)this.getSize().getHeight());  
		}
		//获得该图像的画笔
		gBuffer = iBuffer.getGraphics();  
		//用背景色填充图像(清理画面) 
		//一般如果有背景图的话,本段就可以不用了
		gBuffer.setColor(getBackground());  
		gBuffer.fillRect(0, 0, (int)this.getSize().getWidth(), (int)this.getSize().getHeight()); 
		
		gBuffer.drawImage(image.getSubimage(ax, ay, w, h), 1000, 300, 50, 75, null);
		
		//在界面上直接画出缓冲图像  
		g.drawImage(iBuffer,0,0,this); 
	}
	
	/**
	 * 读取图片
	 */
	public void getImage() {
		if(image == null) {
			try {
				image = (BufferedImage)(ImageIO.read(new FileInputStream("image/人物行走.jpg")));
				//获得图片截取的大小
				w = image.getWidth() / 4;
				h = image.getHeight() / 4;
			} catch (FileNotFoundException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
	
	/**
	 * 更新画面
	 */
	public void update(Graphics g){  
		paint(g);  			
	}
	
	/**
	 * 获得屏幕大小
	 */
	public void getScreen() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Dimension dimension = toolkit.getScreenSize();
		screenWidth = (int) dimension.getWidth();
		screenHeight = (int) dimension.getHeight();
		
	}
	
	/**
	 * 初始化窗体设置
	 */
	public SwingTest(boolean actMoving) {
		getImage();
		getScreen();
		setTitle("无限恐怖v0.1");
		setSize(screenWidth, screenWidth);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//设定背景为黑色
		setBackground(Color.BLACK);
	}
	
	/**
	 * 由线程来控制绘制频率
	 */
	Runnable run = new Runnable() {
		
		@Override
		public void run() {
			while (true) {
				if(SwingTest.count % 4 == 0) {
					ay = SwingTest.count / 4 * 75;
					ax = 0;
				}
				repaint();
				try {
					Thread.sleep(1000 / 10);
				} catch (Exception e) {
					
				}
				ax += w;
				SwingTest.count++;
				if(SwingTest.count == 4) {
					SwingTest.count = 0;
				}
				
			}
		}
	};
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值