老师布置的作业代码写好了,三个球碰撞变色,可是出现闪烁了,模仿网上的双缓冲消除闪烁也没用,请大侠们看看错在哪里,怎么改
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;public class lsn_4 extends Frame implements Runnable{
int x1=0,y1=100,x2=300,y2=100,x3=400,y3=400;
int d1,d2,d3;
int dx1=5,dy1=5,dx2=5,dy2=5,dy3=5,dx3=5;
Color color1,color2,color3;
int width,height;
Image ImageBuffer=null,img1,img2,img3;
Graphics GraImage=null;
int rgb1=(int)(Math.random()*0xFFFFFF),rgb2=(int)(Math.random()*0xFFFFFF),rgb3=(int)(Math.random()*0xFFFFFF);
public static void main(String args[]){
lsn_4 lsn=new lsn_4();
}
public lsn_4(){
GraphicsDevice gd=GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
DisplayMode dm=gd.getDisplayMode();
width=dm.getWidth();
height=dm.getHeight();
setUndecorated(true);
setSize(width,height);
setVisible(true);
setBackground(Color.BLACK);

new Thread(this).start();
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
 System.exit(0);
}
});
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
if(e.getClickCount()==2)
System.exit(0);
}
});
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_ESCAPE||e.getKeyCode()==KeyEvent.VK_SPACE)
System.exit(0);
}
});
}
public void run(){
while(true){
 d1=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
 d2=(x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
 d3=(x3-x2)*(x3-x2)+(y3-y2)*(y3-y2);
 
 if(x1<=0) {dx1=5;doColor1();}  
 else if((x1+100)>=getWidth()) {dx1=-5; doColor1();}
 if(y1<=0) {dy1=5;doColor1();}
 else if((y1+100)>=getHeight()) {dy1=-5; doColor1();}
 if(x2<=0) {dx2=5;doColor2();}  
 else if((x2+100)>=getWidth()) {dx2=-5; doColor2();}
 if(y2<=0) {dy2=5;doColor2();}
 else if((y2+100)>=getHeight()) {dy2=-5; doColor2();}
 if(x3<=0) {dx3=5;doColor3();}  
 else if((x3+100)>=getWidth()) {dx3=-5; doColor3();}
 if(y3<=0) {dy3=5;doColor3();}
 else if((y3+100)>=getHeight()) {dy3=-5; doColor3();}
 if(d1<=10000){
dx1=-dx1;dy1=-dy1;
dx2=-dx2;dy2=-dy2;
 doColor1();doColor2();
 }
 if(d2<=10000){
 dx1=-dx1;dy1=-dy1;
 dx3=-dx3;dy3=-dy3;
 doColor1();doColor3();
 }
 if(d3<=10000){
dx2=-dx2;dy2=-dy2;
dx3=-dx3;dy3=-dy3;
 doColor2();doColor3();
 } 
 x1=x1+dx1;
 y1=y1+dy1;
 x2=x2+dx2;
 y2=y2+dy2;
 x3=x3+dx3;
 y3=y3+dy3;
 repaint();
 try{Thread.sleep(50);}
 catch(InterruptedException e){;}
}
}
public void update(Graphics g){
paint(g);
}


public void paint(Graphics g){
if(ImageBuffer==null)
ImageBuffer = createImage(getWidth(), this.getHeight());   //Image ImageBuffer=null;
GraImage=ImageBuffer.getGraphics(); // Graphics GraImage=null;
GraImage.drawImage(img1,x1,y1,this);
GraImage.drawImage(img2,x2,y2,this);
GraImage.drawImage(img3,x3,y3,this);
GraImage.dispose();
g.drawImage(ImageBuffer,0,0,this);
g.setColor(color1);
g.fillOval(x1, y1, 100, 100);
g.setColor(color2);
g.fillOval(x2, y2, 100, 100);
g.setColor(color3);
g.fillOval(x3, y3, 100, 100);
}
public void doColor1(){
rgb1=(int)(Math.random()*0xFFFFFF);
color1=new Color(rgb1);
}
public void doColor2(){
rgb2=(int)(Math.random()*0xFFFFFF);
color2=new Color(rgb2);
}
public void doColor3(){
rgb3=(int)(Math.random()*0xFFFFFF);
color3=new Color(rgb3);
}
}

解决方案 »

  1.   

    重点改造这个函数:
      public void paint(Graphics g){改造目标就一点:
      只允许使用 g.drawImage() 函数一次,此外不准再使用 g 任何函数。希望你能理解为啥
      

  2.   

    正好最近也用到了这个,我是按这个格式来写的
    双缓冲的使用  它的执行过程是这样的:repaint() 到update()再到paint(),而我们的双缓冲代码就写在update()里。   1)定义一个Graphics对象gOff和一个Image对象offScreenImage。按屏幕大小建立一个缓冲对象给offScreenImage。然后取得offScreenImage的Graphics赋给gOff。此处可以把gOff理解为逻辑上的缓冲屏幕,而把offScreenImage理解为缓冲屏幕上的图象。   2) 在gOff(逻辑上的屏幕)上用paint(Graphics g)函数绘制图象。   3)将后台图象offScreenImage全部一次性的绘制到我们的动画窗口,然后把我们内存中分配的空间窗口关闭调用dispose()方法. 具体代码如下:  Image offScreenImage = null;  if (offScreenImage == null)
            offScreenImage = createImage(BLOCK_SIZE * COLS, BLOCK_SIZE * ROWS);
            Graphics gOff = offScreenImage.getGraphics();
            // 4.调用paint(),将缓冲图象的画笔传入
            paint(gOff);
            // 5.再将此缓冲图像一次性绘到代表屏幕的Graphics对象,即该方法传入的“g”上
            g.drawImage(offScreenImage, 0, 0, null);
      

  3.   


    Image ImageBuffer=null,img1,img2,img3;
     Graphics GraImage=null;
     
    public void paint(Graphics g){
    if(ImageBuffer==null)
    ImageBuffer = createImage(getWidth(), this.getHeight());   //Image ImageBuffer=null;
    GraImage=ImageBuffer.getGraphics(); Graphics GraImage=null;
    GraImage.drawImage(img1,x1,y1,this);
    GraImage.drawImage(img2,x2,y2,this);
    GraImage.drawImage(img3,x3,y3,this);
    paint(GraImage);
    g.drawImage(ImageBuffer,0,0,null);
    GraImage.dispose();
    g.setColor(color1);
    g.fillOval(x1, y1, 100, 100);
    g.setColor(color2);
    g.fillOval(x2, y2, 100, 100);
    g.setColor(color3);
    g.fillOval(x3, y3, 100, 100);
    }
    我改成这个样子了,可是干脆就出不来了
      

  4.   

    3楼这个复杂的过头了,而且完全领会错精神,其实2楼就已经比较好的实现效果了。public void paint(Graphics g){
      // 创建OffScreen画布
      Image off = createImage(getWidth(), this.getHeight());
      Graphics goff=off.getGraphics();  // 把所有东西在off上画好
      goff.drawImage(img1,x1,y1,this);
      goff.drawImage(img2,x2,y2,this);
      goff.drawImage(img3,x3,y3,this);
      goff.setColor(color1);
      goff.fillOval(x1, y1, 100, 100);
      goff.setColor(color2);
      goff.fillOval(x2, y2, 100, 100);
      goff.setColor(color3);
      goff.fillOval(x3, y3, 100, 100);
      goff.dispose();  // 最后一步才是画到FrontScreen
      g.drawImage(off, 0, 0, this);
    }