java Applet绘图(涉及双缓冲)

准备学习java2游戏编程。(其实这是一本书啦)

然后作为基础的基础的基础,必须学习如何让键盘与界面进行交互。下面就是对一个基础得不能再基础的applet程序。

虽然这是个小程序,但其中关于双缓冲概念的介绍是很重要的,要深入理解。(高级噢)

首先先看代码:

package bear.game.keyevent;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Game extends Applet implements KeyListener{

	private Image bufImage = null;
	Graphics bufG = null;
	@Override
	public void paint(Graphics g) {
		setBackground(backColor);
		g.fillRect(r.x, r.y, r.width, r.height);
	}

	@Override
	public void update(Graphics g) {
		bufImage = createImage(getSize().width, getSize().height);
		bufG = bufImage.getGraphics();
		paint(bufG);
		g.drawImage(bufImage, 0, 0, null);
	}
	
	private static final long serialVersionUID = 1L;
	private Rectangle r;
	private Color backColor;
	public void init()
	{
		r = new Rectangle(0, 0, 20, 10);
		backColor = Color.WHITE;
		addKeyListener(this);
	}
	@Override
	public void keyPressed(KeyEvent e) {
		int kc = e.getKeyCode();
		if(kc == KeyEvent.VK_LEFT)
		{
			r.x -= 5;
			if(r.x < 0)
				r.x = 0;
			repaint();
		}
		else if(kc == KeyEvent.VK_RIGHT)
		{
			r.x += 5;
			if(r.x > getSize().width - r.width)
				r.x = getSize().width - r.width;
			repaint();
		}
		else if(kc == KeyEvent.VK_UP)
		{
			r.y -= 5;
			if(r.y < 0)
				r.y = 0;
			repaint();
		}
		else if(kc == KeyEvent.VK_DOWN)
		{
			r.y += 5;
			if(r.y > getSize().height - r.height)
				r.y = getSize().height - r.height;
			repaint();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
	}
	
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		char kc = e.getKeyChar();
		switch(kc)
		{
			case 'r':
			{
				backColor = Color.RED;
				repaint();
				break;
			}
			case 'g':
			{
				backColor = Color.GREEN;
				repaint();
				break;
			}
			case 'b':
			{
				backColor = Color.BLUE;
				repaint();
				break;
			}
			case 'w':
			{
				backColor = Color.WHITE;
				repaint();
				break;
			}
		}
	}

}


程序比较简单明了,该类继承于Applet并且实现了KeyListener接口。

其成员变量主要包括:一个由我们控制的Rectangle,一个Image和一个Graphics用来实现双缓冲。

我们在init()中将Rectangle初始化,在keyPressed中处理键盘移动事件,在keyTyped中处理键盘修改颜色的事件。

下面重点看的是双缓冲的实现(位于update重载函数中),代码如下:

@Override
	public void update(Graphics g) {
		bufImage = createImage(getSize().width, getSize().height);
		bufG = bufImage.getGraphics();
		paint(bufG);
		g.drawImage(bufImage, 0, 0, null);
	}

比方说看动漫的时候,一般一个星期才出一次。所以感觉不是很给力。所以我们可以等它出了很多集之后再一次看完。(好拙的比方)

所以说,双缓冲就是在内存空间中先画好图像,再一次性显示到屏幕上,这与之前先用背景色覆盖,然后再重绘是不同的。

那么为什么之前不重载update会闪烁呢?回答这个问题之前要对awt的重绘的过程有一定的了解。

在awt中对于窗体画布的重绘其条用顺序是repaint()  -->  update()  -->  paint()。

所以我们在调用repaint()的时候要进行update,然后呢,我们来看一看update()的源码。(这里指的是super.update)

/**
* Updates the container. This forwards the update to any lightweight
* components that are children of this container. If this method is
* reimplemented, super.update(g) should be called so that lightweight
* components are properly rendered. If a child component is entirely
* clipped by the current clipping setting in g, update() will not be
* forwarded to that child.
*
* @param g the specified Graphics window
* @see
Component#update(Graphics)
*/

public void update(Graphics g){
	if(isShowing()) {
		if(!(peer instanceof LightweightPeer)){
			g.clearRect(0, 0, width, height);
		}
	paint(g);
	}
}

可以看出super.update()有一个清屏的作用:g.clearRect方法。之后重绘,然后就会出现闪烁。

所以我们利用双缓冲技术可以减缓闪烁的效果。

参考资料:

JAVA双缓冲机制 http://stchou.iteye.com/blog/810701

双缓冲原理在实现消除闪烁的方法  http://edu.21cn.com/java/g_189_642790-1.htm

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值