reapaint()调用update()再调用paint();
所以在update中使用双缓冲
private Image offScreenImage = null; public void update(Graphics g) { if(offScreenImage == null) offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT); Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0, 0, null); }
//子类调用父类的launchFrame->PaintThread().strat()->repaint()->update(Graphics g)->paint(Graphic iB)===>g:原画布,iB:新画布
//update中有paint()方法,因为在子类中对该函数进行了覆盖,所以不调用父类中的paint(),而是子类中的paint(),而此时传给paint的参数是新的画布,
//而不是在原画布上直接操作,然后再把这个画布放到原来的画布上。这就形成了双缓冲绘图。
完整程序:
public class MyFrame extends Frame { /** * 加载窗口 */ public void launchFrame(){ setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT); setLocation(100, 100); setVisible(true); new PaintThread().start(); //启动重画线程 addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } private Image offScreenImage = null; public void update(Graphics g) { if(offScreenImage == null) offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT); Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0, 0, null); } /** * 定义一个重画窗口的线程类,是一个内部类 * @author dell * */ class PaintThread extends Thread { public void run(){ while(true){ repaint(); try { Thread.sleep(40); //1s = 1000ms } catch (InterruptedException e) { e.printStackTrace(); } } } } }