import java.awt.*;
import java.awt.event.*;public class TankGame extends Frame{
Hero hero = new Hero(280,550,0);

public static void main(String args[]) {
new TankGame();
}

public TankGame() {
this.setSize(600,600);
this.setBackground(Color.BLACK);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setVisible(true);
this.addKeyListener(new KeyMonitor());
}

public void paint(Graphics g) {
//画出主坦克
g.setColor(Color.YELLOW);
switch(hero.direct) {
case 0:
g.fill3DRect(hero.x, hero.y, 10, 40,false );
g.fill3DRect(hero.x+30, hero.y, 10, 40, false);
g.fill3DRect(hero.x+10, hero.y+10, 20, 20, false);
g.fillOval(hero.x+15, hero.y+10, 10, 10);
g.fillRect(hero.x+18, hero.y, 4, 10);
break;
case 1:
g.fill3DRect(hero.x, hero.y, 40, 10,false );
g.fill3DRect(hero.x, hero.y+30, 40, 10, false);
g.fill3DRect(hero.x+10, hero.y+10, 20, 20, false);
g.fillOval(hero.x+20, hero.y+15, 10, 10);
g.fillRect(hero.x+30, hero.y+18, 10, 4);
break;
case 2:
g.fill3DRect(hero.x, hero.y, 10, 40,false );
g.fill3DRect(hero.x+30, hero.y, 10, 40, false);
g.fill3DRect(hero.x+10, hero.y+10, 20, 20, false);
g.fillOval(hero.x+15, hero.y+20, 10, 10);
g.fillRect(hero.x+18, hero.y+30, 4, 10);
break;
case 3:
g.fill3DRect(hero.x, hero.y, 40, 10,false );
g.fill3DRect(hero.x, hero.y+30, 40, 10, false);
g.fill3DRect(hero.x+10, hero.y+10, 20, 20, false);
g.fillOval(hero.x+10, hero.y+15, 10, 10);
g.fillRect(hero.x, hero.y+18, 10, 4);
break;
}
repaint();
}

class KeyMonitor extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W) {
hero.setDirect(0);
hero.moveUp();
}
else if(e.getKeyCode() == KeyEvent.VK_D) {
hero.setDirect(1);
hero.moveRight();
}
else if(e.getKeyCode() == KeyEvent.VK_S) {
hero.setDirect(2);
hero.moveDown();
}
else if(e.getKeyCode() == KeyEvent.VK_A) {
hero.setDirect(3);
hero.moveLeft();
}
}
}
}坦克类:public class Tank {
int x,y;
int speed = 2;
int direct;

Tank(int x,int y) {
this.x = x;
this.y = y;
}

public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}

public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}

}class Hero extends Tank {
public Hero(int x,int y,int direct) {
super(x,y);
this.direct = direct;
}
public void moveUp() {
y -= speed;
}

public void moveRight() {
x += speed;
}

public void moveDown() {
y += speed;
}

public void moveLeft() {
x -= speed;
}
}

解决方案 »

  1.   

    你这个函数:
      public void paint(Graphics g) {基本上就是一直在不停的重画坦克,闪是正常的吧
      

  2.   

    闪烁是因为刷新重画频率太快,paint方法还未完成,
    你可以先将所有的东西画在虚拟图片上,然后一次性显示出来;
    在调用paint方法时 调用update方法。
      

  3.   

    把这个代码加上,
    还是会闪,不过没那么明显
    你可以查查,java 双缓冲
    在我看一直调repaint是有问题的,应该是每次移动之后调一次就行了public void update(Graphics g) {
    super.update(g);
    BufferedImage img = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB);
    Graphics2D gg = (Graphics2D) img.getGraphics();
    paint(gg);
    g.drawImage(img, 0, 0, null);
    }
      

  4.   

    Graphics2D gg = (Graphics2D) img.getGraphics();
    -=>
    Graphics2D gg = img.createGraphics();
      

  5.   

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;public class TankGame extends JFrame {  private static final int APPROX_FPS = 60;  public static void main(String args[]) {    SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {        new TankGame().start();
          }
        });
      }
      
      private Hero hero = new Hero(280, 550, 0);
      private JPanel gamePanel;
      private Timer approxFPSTimer;  public TankGame() {
        
        setTitle("坦克");
        
        gamePanel = new GamePanel();
        gamePanel.setBackground(Color.BLACK);
        gamePanel.setPreferredSize(new Dimension(600, 600));
        
        setContentPane(gamePanel);
        addKeyListener(new KeyMonitor());
        
        this.approxFPSTimer = new Timer(1000/APPROX_FPS, new Repainter(gamePanel));
      }  public void start() {
        
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        
        setVisible(true);
        approxFPSTimer.start();
      }  private class GamePanel extends JPanel {    @Override
        public void paintComponent(Graphics g) {      super.paintComponent(g);      g.setColor(Color.YELLOW);
          switch( hero.direct ) {
            case 0:
              g.fill3DRect(hero.x, hero.y, 10, 40, false);
              g.fill3DRect(hero.x + 30, hero.y, 10, 40, false);
              g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
              g.fillOval(hero.x + 15, hero.y + 10, 10, 10);
              g.fillRect(hero.x + 18, hero.y, 4, 10);
              break;
            case 1:
              g.fill3DRect(hero.x, hero.y, 40, 10, false);
              g.fill3DRect(hero.x, hero.y + 30, 40, 10, false);
              g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
              g.fillOval(hero.x + 20, hero.y + 15, 10, 10);
              g.fillRect(hero.x + 30, hero.y + 18, 10, 4);
              break;
            case 2:
              g.fill3DRect(hero.x, hero.y, 10, 40, false);
              g.fill3DRect(hero.x + 30, hero.y, 10, 40, false);
              g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
              g.fillOval(hero.x + 15, hero.y + 20, 10, 10);
              g.fillRect(hero.x + 18, hero.y + 30, 4, 10);
              break;
            case 3:
              g.fill3DRect(hero.x, hero.y, 40, 10, false);
              g.fill3DRect(hero.x, hero.y + 30, 40, 10, false);
              g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
              g.fillOval(hero.x + 10, hero.y + 15, 10, 10);
              g.fillRect(hero.x, hero.y + 18, 10, 4);
              break;
          }
        }
      }
      
      class KeyMonitor extends KeyAdapter {    @Override
        public void keyPressed(KeyEvent e) {      if( e.getKeyCode() == KeyEvent.VK_W ) {        hero.setDirect(0);
            hero.moveUp();
          }
          else if( e.getKeyCode() == KeyEvent.VK_D ) {        hero.setDirect(1);
            hero.moveRight();
          }
          else if( e.getKeyCode() == KeyEvent.VK_S ) {        hero.setDirect(2);
            hero.moveDown();
          }
          else if( e.getKeyCode() == KeyEvent.VK_A ) {        hero.setDirect(3);
            hero.moveLeft();
          }
        }
      }
    }class Tank {  int x, y;
      int speed = 2;
      int direct;  Tank(int x, int y) {    this.x = x;
        this.y = y;
      }  public int getDirect() {    return direct;
      }  public void setDirect(int direct) {    this.direct = direct;
      }  public int getX() {    return x;
      }  public void setX(int x) {    this.x = x;
      }  public int getY() {    return y;
      }  public void setY(int y) {    this.y = y;
      }
    }class Hero extends Tank {  public Hero(int x, int y, int direct) {    super(x, y);
        this.direct = direct;
      }  public void moveUp() {    y -= speed;
      }  public void moveRight() {    x += speed;
      }  public void moveDown() {    y += speed;
      }  public void moveLeft() {    x -= speed;
      }
    }class Repainter implements ActionListener {  private JComponent c;  Repainter(JComponent c) {    assert c != null;
        this.c = c;
      }  @Override
      public void actionPerformed(ActionEvent e) {    c.repaint();
      }
    }
      

  6.   


    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.image.BufferedImage;import javax.swing.JFrame;public class TankGame extends JFrame {
    Hero hero = new Hero(280, 550, 0); public static void main(String args[]) {
    new TankGame();
    } public TankGame() {
    this.setSize(600, 600);
    this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    this.setVisible(true);
    this.addKeyListener(new KeyMonitor());
    this.repaintThread();
    } public void repaintThread() { new Thread() { public void run() {
    try {
    while (true) {
    thisRepaint();
    Thread.sleep(50);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    } }.start(); } public void thisRepaint() {
    this.repaint();
    } public void paint(Graphics grap) {
    BufferedImage image = new BufferedImage(600, 600,
    BufferedImage.TYPE_3BYTE_BGR);
    Graphics g = image.getGraphics();
    // 画出主坦克
    g.setColor(Color.YELLOW);
    switch (hero.direct) {
    case 0 :
    g.fill3DRect(hero.x, hero.y, 10, 40, false);
    g.fill3DRect(hero.x + 30, hero.y, 10, 40, false);
    g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
    g.fillOval(hero.x + 15, hero.y + 10, 10, 10);
    g.fillRect(hero.x + 18, hero.y, 4, 10);
    break;
    case 1 :
    g.fill3DRect(hero.x, hero.y, 40, 10, false);
    g.fill3DRect(hero.x, hero.y + 30, 40, 10, false);
    g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
    g.fillOval(hero.x + 20, hero.y + 15, 10, 10);
    g.fillRect(hero.x + 30, hero.y + 18, 10, 4);
    break;
    case 2 :
    g.fill3DRect(hero.x, hero.y, 10, 40, false);
    g.fill3DRect(hero.x + 30, hero.y, 10, 40, false);
    g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
    g.fillOval(hero.x + 15, hero.y + 20, 10, 10);
    g.fillRect(hero.x + 18, hero.y + 30, 4, 10);
    break;
    case 3 :
    g.fill3DRect(hero.x, hero.y, 40, 10, false);
    g.fill3DRect(hero.x, hero.y + 30, 40, 10, false);
    g.fill3DRect(hero.x + 10, hero.y + 10, 20, 20, false);
    g.fillOval(hero.x + 10, hero.y + 15, 10, 10);
    g.fillRect(hero.x, hero.y + 18, 10, 4);
    break;
    }
    grap.drawImage(image, 0, 0, this);
    } class KeyMonitor extends KeyAdapter {
    public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_W) {
    hero.setDirect(0);
    hero.moveUp();
    } else if (e.getKeyCode() == KeyEvent.VK_D) {
    hero.setDirect(1);
    hero.moveRight();
    } else if (e.getKeyCode() == KeyEvent.VK_S) {
    hero.setDirect(2);
    hero.moveDown();
    } else if (e.getKeyCode() == KeyEvent.VK_A) {
    hero.setDirect(3);
    hero.moveLeft();
    }
    }
    }
    }这个不闪了。
    用JFrame,建议用线程repaint,repaint太快了影响性能。
      

  7.   

    其实只是你在在paint方法里repaint方法的关系,造成无条件的循环。其实你这里需要重写的地方也只有产生键盘事件的时候,所以我建议你改一下键盘监听类。class KeyMonitor extends KeyAdapter {        private TankGame game = null;        public KeyMonitor(TankGame game) {
                this.game = game;
            }
            
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_UP) {
                    hero.setDirect(0);
                    hero.moveUp();
                } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                    hero.setDirect(1);
                    hero.moveRight();
                } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                    hero.setDirect(2);
                    hero.moveDown();
                } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                    hero.setDirect(3);
                    hero.moveLeft();
                }
                game.repaint();
            }
        }这样,在每次产生键盘事件时才去重画。
      

  8.   

    顺便,别忘删除掉paint方法中对于repaint方法的调用。