首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

坦克大战为什么药两个repaint解决思路

2012-03-16 
坦克大战为什么药两个repaint小弟我最近学到韩顺平视频线程这,有一个疑问请各位豪侠:MyPanel的事件处理Key

坦克大战为什么药两个repaint
小弟我最近学到韩顺平视频线程这,有一个疑问请各位豪侠:MyPanel的事件处理KeyListener中已有repaint函数,为什么还要把MyPanel做成线程,在run中再写一个repaint函数,才能把子弹重绘?
package game.tank;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

public class DrawTank extends JFrame
{
  Mypanel mypanel ;

  public DrawTank()
  {
  mypanel = new Mypanel();
  mypanel.setBackground(Color.black);
   
  Thread t = new Thread(mypanel);
  t.start();
   
  this.add(mypanel);
  this.addKeyListener(mypanel);
  this.setSize(500, 400);
  this.setLocation(500, 350);
  this.setVisible(true);
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

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

// 定义我的面板
class Mypanel extends JPanel implements KeyListener, Runnable
{
  Mytank mytank;
  // 定义敌人的tank数组
  Vector<Enemytank> enemytank = new Vector<Enemytank>();
  // 定义敌人tank出现的数量
  int etSize = 3;

  public Mypanel()
  {
  mytank = new Mytank(200, 340);
  mytank.setColor(0);
  for (int i = 0; i < etSize; i++)
  {
  Enemytank et = new Enemytank((i + 1) * 110, 0);
  et.setColor(1);
  et.setDirect(2);
  enemytank.add(et);
  }
  }

  public void paint(Graphics g)
  {
  super.paint(g);
  g.setColor(Color.cyan);
  this.draw(mytank.getX(), mytank.getY(), g, this.mytank.direct, 0);
  // 画出子弹
  if (mytank.b != null)
  {
  g.draw3DRect(mytank.b.x, mytank.b.y, 1, 1, false);
  }

  // 画出敌人的坦克
  for (int i = 0; i < enemytank.size(); i++)
  {

  this.draw(enemytank.get(i).getX(), enemytank.get(i).getY(), g,
  enemytank.get(i).getDirect(), 1);
  }

  }

  public void draw(int x, int y, Graphics g, int direct, int type)
  {
  switch (type)
  {
  case 0:
  g.setColor(Color.cyan);
  break;
  case 1:
  g.setColor(Color.yellow);
  break;
  }
  switch (direct)
  {
  // 向上
  case 0:
  g.fill3DRect(x, y, 5, 30, false);
  g.fill3DRect(x + 15, y, 5, 30, false);
  g.fill3DRect(x + 5, y + 5, 10, 20, false);
  g.fillOval(x + 5, y + 10, 10, 10);
  g.drawLine(x + 10, y + 15, x + 10, y);
  break;
  // 向右
  case 1:
  g.fill3DRect(x, y, 30, 5, false);
  g.fill3DRect(x, y + 15, 30, 5, false);
  g.fill3DRect(x + 5, y + 5, 20, 10, false);
  g.fillOval(x + 10, y + 4, 10, 10);
  g.drawLine(x + 15, y + 10, x + 30, y + 10);
  break;
  // 向下
  case 2:
  g.fill3DRect(x, y, 5, 30, false);
  g.fill3DRect(x + 15, y, 5, 30, false);
  g.fill3DRect(x + 5, y + 5, 10, 20, false);
  g.fillOval(x + 4, y + 10, 10, 10);


  g.drawLine(x + 9, y + 15, x + 9, y + 30);
  break;
  // 向左
  case 3:
  g.fill3DRect(x, y, 30, 5, false);
  g.fill3DRect(x, y + 15, 30, 5, false);
  g.fill3DRect(x + 5, y + 5, 20, 10, false);
  g.fillOval(x + 10, y + 4, 10, 10);
  g.drawLine(x + 15, y + 10, x, y + 10);
  break;

  }
  }

  @Override
  public void keyPressed(KeyEvent e)
  {
  if (e.getKeyCode() == KeyEvent.VK_UP)
  {
  this.mytank.setDirect(0);
  this.mytank.moveup();
  }
  else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
  {
  this.mytank.setDirect(1);
  this.mytank.moveright();
  }
  else if (e.getKeyCode() == KeyEvent.VK_DOWN)
  {
  this.mytank.setDirect(2);
  this.mytank.movedown();
  }
  else if (e.getKeyCode() == KeyEvent.VK_LEFT)
  {
  this.mytank.setDirect(3);
  this.mytank.moveleft();
  }
  if (e.getKeyCode() == KeyEvent.VK_J)
  {
  this.mytank.fire();
  }
  this.repaint();
  }

  @Override
  public void keyReleased(KeyEvent e)
  {
  // TODO Auto-generated method stub

  }

  @Override
  public void keyTyped(KeyEvent e)
  {
  // TODO Auto-generated method stub

  }

  @Override
  public void run()
  {
  while (true)
  {
  try
  {
  Thread.sleep(100);
  }
  catch (Exception e)
  {
  e.printStackTrace();
  }
  this.repaint();
  }

  }
}


[解决办法]

探讨
你好,请问第一个repaint就在按J事件处理下面,为什么不会重绘?

[解决办法]
第一个repaint的作用是让子弹立即显示出来,虽然说第二个repaint一直在执行,但是它有间隔时间,如果间隔时间长的话,第一个 repaint就很重要了,否则你点下射击键子弹不会立即出来,得等到第二个repaint再次执行。上面的程序间隔时间是100毫秒,即使没有第一个repaint子弹也会立即显示出来,如果你把时间改成5000毫秒,你就会知道第一个repaint的重要性了

热点排行
Bad Request.