我的坦克为什么一闪一闪的?哪位给看一下。。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是有问题的,应该是每次移动之后调一次就行了
--------------------编程问答-------------------- Graphics2D gg = (Graphics2D) img.getGraphics();
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 = 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