当前位置:编程学习 > JAVA >>

我的坦克为什么一闪一闪的?哪位给看一下。。Thank yoy

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;
}
}

--------------------编程问答-------------------- 你这个函数:
  public void paint(Graphics g) {

基本上就是一直在不停的重画坦克,闪是正常的吧。。。 --------------------编程问答-------------------- 线程同步问题 --------------------编程问答-------------------- 马士兵的坦克大战?这个解决方法是有的,我忘了 --------------------编程问答-------------------- 闪烁是因为刷新重画频率太快,paint方法还未完成,
你可以先将所有的东西画在虚拟图片上,然后一次性显示出来;
在调用paint方法时 调用update方法。 --------------------编程问答-------------------- 把这个代码加上,
还是会闪,不过没那么明显
你可以查查,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);
}
--------------------编程问答-------------------- Graphics2D gg = (Graphics2D) img.getGraphics();
-=>
Graphics2D gg = img.createGraphics(); --------------------编程问答--------------------


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();
  }
}
--------------------编程问答-------------------- 用双缓冲吧,先画一张缓冲图片,把你需要画的图片都画到缓冲图片上,再将整张缓冲图片画到你的控件上 --------------------编程问答--------------------

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太快了影响性能。 --------------------编程问答-------------------- 其实只是你在在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();
        }
    }


这样,在每次产生键盘事件时才去重画。 --------------------编程问答-------------------- 顺便,别忘删除掉paint方法中对于repaint方法的调用。 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 使用双缓冲可以很好的解决闪烁的问题
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,