今天看啥
    热点:

      天发国际娱乐官网:  “软木布料100元一米,成本比较低廉,但摸起来又很温润。

      Java坦克大战(四),java坦克大战


      这是我的坦克游戏大战的最后一版,里面添加很多新的功能。这个坦克大战的有很多不足之处,但是对于初学者来说依然是一个很好的练习项目,从中我们可以学习Java基础知识,将知识与项目结合,学习面向对象编程思想,最主要的是编程的逻辑练习,代码往往不像是写文章从上到下一气呵成完成,中间很可能为增加一个功能来添加一个类一个方法等,中间有很多细节需要我们考虑。文章最后会附加该坦克大战涉及的相关素材。

      功能:

      1.防止坦克重叠

      2.可以分关(闪烁效果)

      3.记录成绩(小型游戏都是写在文件中)

      4.存盘退出,可以记录但是敌人坦克的坐标

      5.可以恢复上局,继续玩

      6.坦克的声音

      坦克大战最终版本(2.1)

      MyTanKGame类:

      /*
       * 功能:
       * 1.防止坦克重叠
       * 2.可以分关(闪烁效果)
       * 3.记录成绩(小型游戏都是写在文件中)
       * 4.存盘退出,可以记录但是敌人坦克的坐标
       * 5.可以恢复上局,继续玩
       * 6.坦克的声音
       */
      package com.fanghua6;
      
      import java.awt.*;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.KeyEvent;
      import java.util.Vector;
      import javax.swing.*;
      
      public class MyTankGame1_7 extends JFrame implements ActionListener {
      
          Mypanel1_2 mp = null;
      
          // 定义开始面板
          MyStartPanel msp = null;
          // 做出菜单
          JMenuBar jmb = null;
          // 开始游戏
          JMenu jm1 = null;
          JMenuItem jmi1 = null;
          // 退出游戏
          JMenuItem jmi2 = null;
          // 存盘退出
          JMenuItem jmi3 = null;
          JMenuItem jmi4 = null;
      
          public static void main(String[] args) {
              new MyTankGame1_7();
          }
      
          // 构造函数
          public MyTankGame1_7() {
              // mp = new Mypanel1_2();
      
              // 启动mp线程
              // Thread t = new Thread(mp);
              // t.start();
      
              // this.add(mp);
              // 注册监听
              // this.addKeyListener(mp);
              // 创建菜单及菜单选项
              jmb = new JMenuBar();
              jm1 = new JMenu("游戏(G)");
              jm1.setMnemonic('G');
              jmi1 = new JMenuItem("开始新游戏(N)");
              jmi1.setMnemonic('N');
      
              jmi2 = new JMenuItem("退出游戏(E)");
              jmi2.setMnemonic('E');
      
              jmi3 = new JMenuItem("存盘退出(C)");
              jmi3.setMnemonic('C');
      
              jmi4 = new JMenuItem("继续上局(S)");
              jmi4.setMnemonic('S');
      
              // jmi1相应
              jmi1.addActionListener(this);
              jmi1.setActionCommand("newgame");
              jmi2.addActionListener(this);
              jmi2.setActionCommand("exit");
              jmi3.addActionListener(this);
              jmi3.setActionCommand("saveExit");
              jmi4.addActionListener(this);
              jmi4.setActionCommand("conGame");
      
              jm1.add(jmi1);
              jm1.add(jmi2);
              jm1.add(jmi3);
              jm1.add(jmi4);
      
              jmb.add(jm1);
      
              // 加了开始面板(上面的全注释掉)
              msp = new MyStartPanel();
              this.add(msp);
              // 启动msp面板
              Thread t = new Thread(msp);
              t.start();
      
              this.setJMenuBar(jmb);
      
              this.setSize(600, 500);
              this.setTitle("我的坦克大战");
              ImageIcon icon = new ImageIcon("images\\tanke.png");
              this.setIconImage(icon.getImage());
              this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              this.setVisible(true);
      
          }
      
          @Override
          public void actionPerformed(ActionEvent e) {
              // TODO Auto-generated method stub
              // 对用户不同的点击做出不同的处理
              if (e.getActionCommand().equals("newgame")) {
      
                  // 创建战场面板
                  mp = new Mypanel1_2("newGame");
                  // 启动mp线程
                  Thread t = new Thread(mp);
                  t.start();
                  // 先把msp删掉,再加mp
                  this.remove(msp);
                  this.add(mp);
                  // 注册监听
                  this.addKeyListener(mp);
                  // 显示,刷新JFrame(这个很重要)
                  this.setVisible(true);
              } else if (e.getActionCommand().equals("exit")) {
      
                  // 用户退出系统的菜单(保存击毁敌人数量)
                  Recorder.keepRecording();
      
                  System.exit(0);
              }// 对存盘退出的处理
              else if (e.getActionCommand().equals("saveExit")) {
      
                  /*
                   * 当时这里这样处理的,大错特错。new两次 工作 new Recorder().setEts(mp.ets);new
                   * 保存击毁敌人的数量和敌人的坐标 Recorder().keepRecAndEnemyTank();
                   */
      
                  // 工作
                  Recorder rd = new Recorder();
                  rd.setEts(mp.ets);
                  // 保存击毁敌人的数量和敌人的坐标
                  rd.keepRecAndEnemyTank();
      
                  // 退出
                  System.exit(0);
              } else if (e.getActionCommand().equals("conGame")) {
                  // 继续游戏
                  // 创建战场面板
                  mp = new Mypanel1_2("con");
      
                  // 不在这:mp.nodes = new Recorder().getNodesAndEnNums();
                  // 启动mp线程
                  Thread t = new Thread(mp);
                  t.start();
                  // 先把msp删掉,再加mp
                  this.remove(msp);
                  this.add(mp);
                  // 注册监听
                  this.addKeyListener(mp);
                  // 显示,刷新JFrame(这个很重要)
                  this.setVisible(true);
      
              }
          }
      }
      
      // 提示面板(用线程来实现闪烁效果)
      class MyStartPanel extends JPanel implements Runnable {
          // 做一个开关
          int times = 0;
      
          public void paint(Graphics g) {
              super.paint(g);
              g.fillRect(0, 0, 400, 300);
              // 提示信息
              if (times % 2 == 0) {
                  g.setColor(Color.yellow);
                  // 开关信息的字体
                  Font myFont = new Font("华文新魏", Font.BOLD, 30);
                  g.setFont(myFont);// 别忘了
                  g.drawString("stage: 1", 140, 200);
              }
          }
      
          @Override
          public void run() {
              // TODO Auto-generated method stub
              while (true) {
                  // 休眠
                  try {
                      Thread.sleep(500);
                  } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  times++;
                  // 重画
                  this.repaint();
              }
          }
      
      }
      
      // 我的面板,拓宽思路:Panel本身就是一个刷新体
      class Mypanel1_2 extends JPanel implements java.awt.event.KeyListener, Runnable {
      
          // 定义我的坦克
          Hero1_2 hero = null;
      
          // 判断是续上局,还是新游戏
      
          // 定义敌人的坦克(不止一辆,线程安全,集合)
          Vector<EnemyTank> ets = new Vector<EnemyTank>();
          Vector<Node> nodes = new Vector<Node>();
      
          // 定义炸弹集合
          Vector<Bomb> bombs = new Vector<Bomb>();
      
          int enSize = 4;// 敌人坦克保持4个
      
          // 定义三张图片(三张图片才能组成一颗炸弹)
          Image image1 = null;
          Image image2 = null;
          Image image3 = null;
      
          // 构造函数(续局,变成含参的构造函数)
          public Mypanel1_2(String flag) {
      
              // 恢复记录(写在这里)
              Recorder.getRecoring();
      
              hero = new Hero1_2(70, 100);
      
              if (flag.equals("newGame")) {
                  // 初始化敌人的坦克
                  for (int i = 0; i < enSize; i++) {
                      // 创建一辆敌人的坦克
                      EnemyTank et = new EnemyTank((i + 1) * 50, 0);
                      et.setColor(0);
                      // 坦克默认反向是0(向上),这里改一下
                      et.setDirect(2);
      
                      // 将MyPanel的敌人坦克向量交给该敌人坦克
                      et.setEts(ets);
      
                      // 启动敌人的坦克
                      Thread t = new Thread(et);
                      t.start();
                      // 给敌人坦克添加一颗子弹
                      Shot s = new Shot(et.x + 10, et.y + 30, 2);
                      // 加入给敌人的坦克
                      et.ss.add(s);
      
                      Thread t2 = new Thread(s);
                      t2.start();
                      ets.add(et);
                  }
              } else {
      
                  nodes = new Recorder().getNodesAndEnNums();
      
                  for (int i = 0; i < nodes.size(); i++) {
      
                      Node node = nodes.get(i);
                      // 创建一辆敌人的坦克
                      EnemyTank et = new EnemyTank(node.x, node.y);
                      et.setColor(0);
                      et.setDirect(node.direct);
      
                      // 将MyPanel的敌人坦克向量交给该敌人坦克
                      et.setEts(ets);
      
                      // 启动敌人的坦克
                      Thread t = new Thread(et);
                      t.start();
                      // 给敌人坦克添加一颗子弹
                      Shot s = new Shot(et.x + 10, et.y + 30, 2);
                      // 加入给敌人的坦克
                      et.ss.add(s);
      
                      Thread t2 = new Thread(s);
                      t2.start();
                      ets.add(et);
                  }
              }
              // 初始话图片,这样做击中第一个坦克,爆炸的效果不明显。下面优化
              image1 = Toolkit.getDefaultToolkit().getImage(
                      Panel.class.getResource("/bomb_1.gif"));
              image2 = Toolkit.getDefaultToolkit().getImage(
                      Panel.class.getResource("/bomb_2.gif"));
              image3 = Toolkit.getDefaultToolkit().getImage(
                      Panel.class.getResource("/bomb_3.gif"));
      
              // 引包:import javax.imageio.ImagesssIO;
              // try {
              // image1=ImageIO.read(new File("/bomsb_1.gif"));
              // image2=ImageIO.read(new File("/bomb_2.gif"));
              // image3=ImageIO.read(new File("/bomb_3.gif"));
              // } catch (IOException e) {
              // // TODO Auto-generated catch block
              // e.printStackTrace();
              // }
      
              // 在Mypanel1_2初始化里,放置开战音效,加载即播放
              // 以后再添加爆炸效果的声音也是这样做的思路
              AePlayWave apw = new AePlayWave("E:\\111.wav");
              apw.start();
      
          }
      
          // 提示信息(只需要画笔即可)
          public void showInfo(Graphics g) {
              // 画出提示信息坦克
              this.drawTank(70, 310, g, 0, 0);
              g.setColor(Color.black);
              g.drawString(Recorder.getEnNum() + "", 100, 330);
      
              this.drawTank(70, 360, g, 0, 1);
              g.setColor(Color.black);
              g.drawString(Recorder.getMyLife() + "", 100, 380);
      
              // 画出玩家的总成绩
              g.setColor(Color.black);
              Font f = new Font("宋体", Font.BOLD, 20);
              g.setFont(f);
              g.drawString("你的总成绩", 410, 30);
              this.drawTank(410, 60, g, 0, 0);
      
              g.setColor(Color.black);
              g.drawString(Recorder.getAllEnNum() + "", 440, 80);
          }
      
          // 重写paint函数
          public void paint(Graphics g) {
              // 一定要调用
              super.paint(g);
              g.fillRect(0, 0, 400, 300);
              // 画出提示信息
              this.showInfo(g);
      
              // 画出自己的坦克(将方向填进去)
              if (hero.isLive == true) {
                  this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1);
              }
              // 从ss中取出每一颗子弹,并画出
              for (int i = 0; i < hero.ss.size(); i++) {
      
                  Shot myShot = hero.ss.get(i);
                  if (myShot != null && myShot.isLive == true) {
                      g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
      
                      /*
                       * 画出一颗子弹(后添加 hero.s.isLive==true,节省资源) if (hero.s != null
                       * &&hero.s.isLive == true) { g.draw3DRect(hero.s.x, hero.s.y,
                       * 1, 1,false); }
                       */
                  }
                  if (myShot.isLive == false) {
                      // 从ss(向量)中删除该子弹
                      // hero.ss.remove(i);会报异常。
                      hero.ss.remove(myShot);
                  }
              }
      
              // 画出炸弹
              for (int i = 0; i < bombs.size(); i++) {
                  // 取出炸弹
                  Bomb b = bombs.get(i);
                  if (b.life > 6) {
                      g.drawImage(image1, b.x, b.y, 30, 30, this);
                  } else if (b.life > 4) {
                      g.drawImage(image2, b.x, b.y, 30, 30, this);
                  } else {
                      g.drawImage(image3, b.x, b.y, 30, 30, this);
                  }
                  // 让b的生命值减小
                  b.lifeDown();
                  // 如果炸弹生命值为零,就把该炸弹从bombs向量中去掉
                  if (b.life == 0) {
                      bombs.remove(b);
                  }
      
              }
      
              // 画出敌人的坦克
              for (int i = 0; i < ets.size(); i++) {
                  EnemyTank et = ets.get(i);
                  if (et.isLive) {
                      this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0);
      
                      // 画出敌人的子弹
                      for (int j = 0; j < et.ss.size(); j++) {
                          // 取出子弹
                          Shot enemyShot = et.ss.get(j);
                          if (enemyShot != null && enemyShot.isLive == true) {
                              g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
                          }
                          if (enemyShot.isLive == false) {
                              // 如果敌人的坦克死亡了,就从Vector中删除
                              et.ss.remove(enemyShot);
                          }
                      }
                  }
              }
          }
      
          // 敌人的坦克是否击中我
          public void hitMe() {
              // 取出每一个敌人的坦克
              for (int i = 0; i < this.ets.size(); i++) {
                  // 取出坦克
                  EnemyTank et = ets.get(i);
      
                  // 取出每一颗子弹
                  for (int j = 0; j < et.ss.size(); j++) {
                      // 取出子弹
                      Shot enemyShot = et.ss.get(j);
                      if (hero.isLive) {
                          if (this.hitTank(enemyShot, hero)) {
      
                          }
                      }
                  }
              }
          }
      
          // 判断我的子弹是否击中敌人的坦克
          public void hitEnemyTank() {
              // 判断是否击中敌人的坦克
              for (int i = 0; i < hero.ss.size(); i++) {
                  // 取出子弹
                  Shot myShot = hero.ss.get(i);
                  // 判断子弹是否有效
                  if (myShot.isLive) {
                      // 取出每个坦克,与它判断
                      for (int j = 0; j < ets.size(); j++) {
                          // 取出坦克
                          EnemyTank et = ets.get(j);
      
                          if (et.isLive) {
                              if (this.hitTank(myShot, et)) {
      
                                  // 减少敌人数量
                                  Recorder.reduceEnNum();
                                  // 增加我的记录
                                  Recorder.addEnNumRec();
                              }
                          }
      
                      }
                  }
              }
          }
      
          // 写一个函数 专门判断是否击中敌人坦克(原来第二参数: EnemyTank et)
          // void改成boolean 判断击中的目标是谁
      
          public boolean hitTank(Shot s, Tank1_2 et) {
              boolean b2 = false;
      
              // 判断该坦克的方向
              switch (et.direct) {
              // 如果敌人坦克的方向是上或者是下
              case 0:
              case 2:
                  if (s.x > et.x && s.x < et.x + 20 && s.y > et.y && s.y < et.y + 30) {
                      // 击中
                      // 子弹死亡
                      s.isLive = false;
                      // 敌人坦克死亡
                      et.isLive = false;
                      b2 = true;
                      // 创建一颗炸弹,放入Vector
                      Bomb b = new Bomb(et.x, et.y);
                      // 放入Vector
                      bombs.add(b);
      
                  }
      
                  break;
              case 1:
              case 3:
                  if (s.x > et.x && s.x < et.x + 30 && s.y > et.y && s.y < et.y + 20) {
                      // 击中
                      // 子弹死亡
                      s.isLive = false;
                      // 敌人坦克死亡
                      et.isLive = false;
                      b2 = true;
                      // 创建一颗炸弹,放入Vector
                      Bomb b = new Bomb(et.x, et.y);
                      // 放入Vector
                      bombs.add(b);
      
                  }
                  break;
              }
      
              return b2;
      
          }
      
          // 画出坦克的函数
          public void drawTank(int x, int y, Graphics g, int direct, int type) {
              // 坦克类型
              switch (type) {
              case 0:
                  g.setColor(Color.green);
                  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 + 5, 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 + 5, y + 10, 10, 10);
                  g.drawLine(x + 10, y + 15, x + 10, 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 + 5, 10, 10);
                  g.drawLine(x + 15, y + 10, x, y + 10);
                  break;
              }
      
          }
      
          @Override
          public void keyPressed(KeyEvent e) {
              // TODO Auto-generated method stub
              // 已更正为顺时针
              if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
                  this.hero.moveUp();
                  this.hero.setDirect(0);
              } else if (e.getKeyCode() == KeyEvent.VK_RIGHT
                      || e.getKeyCode() == KeyEvent.VK_D) {
                  this.hero.setDirect(1);
                  this.hero.moveRight();
              } else if (e.getKeyCode() == KeyEvent.VK_DOWN
                      || e.getKeyCode() == KeyEvent.VK_S) {
                  this.hero.moveDown();
                  this.hero.setDirect(2);
              } else if (e.getKeyCode() == KeyEvent.VK_LEFT
                      || e.getKeyCode() == KeyEvent.VK_A) {
                  this.hero.moveLeft();
                  this.hero.setDirect(3);
              } else if (e.getKeyCode() == KeyEvent.VK_J) {
                  // 将J键设置为发出子弹
                  // 子弹连发,J被按几下,发几颗:this.hero.shotEnemy();
                  // this.repaint();在run函数里,不应该设计在这里
                  if (this.hero.ss.size() <= 4) {
                      this.hero.shotEnemy();
                  }
              }
              // 必须重新绘制Panel
              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() {
              // TODO Auto-generated method stub
              // 每隔100毫秒去重绘
              while (true) {
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
      
                  // 谨记这里:由于这里多写了这些,线程每次都被重新调用
                  // showInfo的信息不会动态改变 调了好久好久。苦笑脸
                  // 判断是否击中(写在这里,虽然在每次重绘的时候都要调用,但是没办法)
                  // 每一颗子弹都要和每个坦克进行匹配
                  // for (int i = 0; i < hero.ss.size(); i++) {
                  // // 取出子弹
                  // Shot myShot = hero.ss.get(i);
                  // // 判断子弹是否有效
                  // if (myShot.isLive) {
                  // // 取出每个坦克,与它判断
                  // for (int j = 0; j < ets.size(); j++) {
                  // // 取出坦克
                  // EnemyTank et = ets.get(j);
                  //
                  // if (et.isLive) {
                  // this.hitTank(myShot, et);
                  // }
                  // }
                  // }
                  // }
                  this.hitEnemyTank();
      
                  this.hitMe();
      
                  // 重绘
                  this.repaint();
              }
          }
      }

      Menbers类:

      package com.fanghua6;
      
      import java.io.BufferedReader;
      import java.io.BufferedWriter;
      import java.io.File;
      import java.io.FileReader;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.util.Vector;
      import javax.sound.sampled.AudioFormat;
      import javax.sound.sampled.AudioInputStream;
      import javax.sound.sampled.AudioSystem;
      import javax.sound.sampled.DataLine;
      import javax.sound.sampled.SourceDataLine;
      
      //播放声音的类
      class AePlayWave extends Thread {
      
          private String filename;
      
          public AePlayWave(String wavfile) {
              filename = wavfile;
      
          }
      
          public void run() {
      
              File soundFile = new File(filename);
      
              AudioInputStream audioInputStream = null;
              try {
                  audioInputStream = AudioSystem.getAudioInputStream(soundFile);
              } catch (Exception e1) {
                  e1.printStackTrace();
                  return;
              }
      
              AudioFormat format = audioInputStream.getFormat();
              SourceDataLine auline = null;
              DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
      
              try {
                  auline = (SourceDataLine) AudioSystem.getLine(info);
                  auline.open(format);
              } catch (Exception e) {
                  e.printStackTrace();
                  return;
              }
      
              auline.start();
              int nBytesRead = 0;
              // 这是缓冲
              byte[] abData = new byte[512];
      
              try {
                  while (nBytesRead != -1) {
                      nBytesRead = audioInputStream.read(abData, 0, abData.length);
                      if (nBytesRead >= 0)
                          auline.write(abData, 0, nBytesRead);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
                  return;
              } finally {
                  auline.drain();
                  auline.close();
              }
          }
      }
      
      // 继续上一局的记记录点的类
      class Node {
          int x;
          int y;
          int direct;
      
          public Node(int x, int y, int direct) {
              this.x = x;
              this.y = y;
              this.direct = direct;
          }
      }
      
      // 记录类,同时也可以保存玩家的设置(一般都是事先写在缓存里面的)
      class Recorder {
          // 记录每关有多少敌人
          private static int enNum = 20;
          // 设置我有多少可以用的坦克
          private static int myLife = 3;
          // 记录一共消灭多少敌人
          private static int allEnNum = 0;
      
          // 从文件中恢复记录点
          static Vector<Node> nodes = new Vector<Node>();
      
          private static FileWriter fw = null;
          private static BufferedWriter bw = null;
          private static FileReader fr = null;
          private static BufferedReader br = null;
      
          private Vector<EnemyTank> ets = new Vector<EnemyTank>();
      
          // 完成读取的函数(记录点和敌人的数量)
          public Vector<Node> getNodesAndEnNums() {
              try {
                  fr = new FileReader("E:/Tanke.txt");
                  br = new BufferedReader(fr);
                  String n = "";
                  n = br.readLine();// 设置先读第一行
                  allEnNum = Integer.parseInt(n);
                  // 接着读
                  while ((n = br.readLine()) != null) {
                      String[] xyz = n.split(" ");
                      // 在知道只有三条数据的情况下,用了这个方法。否则要用for循环
                      Node node = new Node(Integer.parseInt(xyz[0]),
                              Integer.parseInt(xyz[1]), Integer.parseInt(xyz[2]));
                      nodes.add(node);
                  }
      
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } finally {
                  try {
                      br.close();
                      fr.close();
                  } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
              return nodes;
          }
      
          public Vector<EnemyTank> getEts() {
              return ets;
          }
      
          public void setEts(Vector<EnemyTank> ets) {
              this.ets = ets;
          }
      
          // 保存击毁敌人的数量和击毁敌人坦克的坐标、方向
          public void keepRecAndEnemyTank() {
              try {
                  fw = new FileWriter("E:/Tanke.txt");
                  bw = new BufferedWriter(fw);
      
                  bw.write(allEnNum + "\r\n");
      
                  // 保存当前的敌人坦克的坐标和方向
                  for (int i = 0; i < ets.size(); i++) {
                      // 取出第一个坦克
                      EnemyTank et = ets.get(i);
                      if (et.isLive) {
                          // 活的就保存
                          String recode = et.x + " " + et.y + " " + et.direct;
                          // 写入
                          bw.write(recode + "\r\n");
      
                      }
                  }
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } finally {
                  try {
                      bw.close();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  try {
                      fw.close();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
          }
      
          // 从文件中读取,记录
          public static void getRecoring() {
              try {
                  fr = new FileReader("E:/Tanke.txt");
                  br = new BufferedReader(fr);
                  String n = br.readLine();
                  allEnNum = Integer.parseInt(n);
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } finally {
                  try {
                      br.close();
                      fr.close();
                  } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
              }
      
          }
      
          // 把玩家击毁敌人坦克数量保存到文件中
          public static void keepRecording() {
              try {
                  fw = new FileWriter("E:/Tanke.txt");
                  bw = new BufferedWriter(fw);
      
                  bw.write(allEnNum + "\r\n");
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              } finally {
                  try {
                      bw.close();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  try {
                      fw.close();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
      
              }
      
          }
      
          public static int getAllEnNum() {
              return allEnNum;
          }
      
          public static void setAllEnNum(int allEnNum) {
              Recorder.allEnNum = allEnNum;
          }
      
          public static int getEnNum() {
              return enNum;
          }
      
          public static void setEnNum(int enNum) {
              Recorder.enNum = enNum;
          }
      
          public static int getMyLife() {
              return myLife;
          }
      
          public void setMyLife(int myLife) {
              Recorder.myLife = myLife;
          }
      
          // 减少敌人数
          public static void reduceEnNum() {
              enNum--;
          }
      
          // 消灭敌人
          public static void addEnNumRec() {
              allEnNum++;
          }
      
      }
      
      // 炸弹类(没必要定义为线程,因为它不会移动,没有坐标改变)
      class Bomb {
          // 定义炸弹的坐标
          int x, y;
          int life = 9;// 炸弹的生命(三张图片)
          // 可以看出isLive很有用,它可以决定类(或者对象)要不要展现在面板上
          boolean isLive = true;
      
          public Bomb(int x, int y) {
              this.x = x;
              this.y = y;
          }
      
          // 炸弹减少生命值
          public void lifeDown() {
              if (life > 0) {
                  life--;
              } else {
                  this.isLive = false;
              }
          }
      
      }
      
      // 子弹类
      class Shot implements Runnable {
          int x;
          int y;
          int direct;
          // 设置子弹的消亡(默认活着的)
          boolean isLive = true;
          // speed要给个初始值1,之前给0,按J键,子弹没有动
          int speed = 1;
      
          public Shot(int x, int y, int direct) {
              super();
              this.x = x;
              this.y = y;
              this.direct = direct;
      
          }
      
          @Override
          public void run() {
              // TODO Auto-generated method stub
      
              while (true) {
                  // 设置子弹休息50毫秒
      
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
      
                  switch (direct) {
                  case 0:
                      y -= speed;
                      break;
                  case 1:
                      x += speed;
                      break;
                  case 2:
                      y += speed;
                      break;
                  case 3:
                      x -= speed;
                      break;
                  }
                  // 测试用:System.out.println("子弹坐标x=" + x + "y=" + y);
                  // 子弹什么时候死亡
                  // 判断该子弹是否碰到边缘
                  if (x < 0 || x > 400 || y < 0 || y > 300) {
                      this.isLive = false;
                      break;
                  }
              }
          }
      }
      
      // 坦克类
      class Tank1_2 {
      
          int x = 0;
          int y = 0;
          boolean isLive = true;
      
          // 坦克方向:0表示上,1表示右,2表示下,3表示左
          int direct = 0;
          int speed = 1;
          // 坦克的颜色
          int color;
      
          public int getColor() {
              return color;
          }
      
          public void setColor(int color) {
              this.color = color;
          }
      
          public int getSpeed() {
              return speed;
          }
      
          public void setSpeed(int speed) {
              this.speed = speed;
          }
      
          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;
          }
      
          // 构造函数
          public Tank1_2(int x, int y) {
              this.x = x;
              this.y = y;
      
          }
      
      }
      
      // 敌人的坦克(做成线程,会移动)
      class EnemyTank extends Tank1_2 implements Runnable {
      
          int times = 0;
          // 定义一个向量,可以访问MyPanel上所有敌人的坦克
          Vector<EnemyTank> ets = new Vector<EnemyTank>();
          // 定义向量,可以存放敌人的子弹
          Vector<Shot> ss = new Vector<Shot>();
      
          // 敌人添加子弹,应该刚刚创建坦克和敌人子弹死亡后
      
          public EnemyTank(int x, int y) {
              super(x, y);
          }
      
          // 得到MyPaneld的敌人坦克向量
          public void setEts(Vector<EnemyTank> vv) {
              // 此时拥有一种能力,可以拿到yPan el上所有敌人的坦克
              this.ets = vv;
          }
      
          // 判断是否碰到别的敌人的坦克
          public boolean isTouchOtherEnemy() {
              boolean b = false;
      
              switch (this.direct) {
              case 0:
                  // 我的坦克向上
                  for (int i = 0; i < ets.size(); i++) {
                      // 取出第一个坦克(很有可能是自己哦)
                      EnemyTank et = ets.get(i);
                      // 如果不是自己
                      if (et != this) {
                          // 如果敌人的方向是向下或者向下
                          if (et.direct == 0 || et.direct == 2) {
                              if (this.x >= et.x && this.x <= et.x + 20
                                      && this.y >= et.y && this.y <= et.y + 30) {
                                  return true;
                              }
                              if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20
                                      && this.y >= et.y && this.y <= et.y + 30) {
                                  return true;
                              }
                          }
                          if (et.direct == 1 || et.direct == 3) {
                              if (this.x >= et.x && this.x <= et.x + 30
                                      && this.y >= et.y && this.y <= et.y + 20) {
                                  return true;
                              }
                              if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30
                                      && this.y >= et.y && this.y <= et.y + 20) {
                                  return true;
                              }
                          }
                      }
                  }
                  break;
              case 1:
                  for (int i = 0; i < ets.size(); i++) {
                      EnemyTank et = ets.get(i);
                      if (et != this) {
                          if (et.direct == 0 || et.direct == 2) {
                              if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20
                                      && this.y >= et.y && this.y <= et.y + 30) {
                                  return true;
                              }
                              if (this.x + 30 >= et.x && this.x + 30 <= et.x + 20
                                      && this.y + 20 >= et.y
                                      && this.y + 20 <= et.y + 30) {
                                  return true;
                              }
                          }
                          if (et.direct == 1 || et.direct == 3) {
                              if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30
                                      && this.y >= et.y && this.y <= et.y + 20) {
                                  return true;
                              }
                              if (this.x + 30 >= et.x && this.x + 30 <= et.x + 30
                                      && this.y + 20 >= et.y
                                      && this.y + 20 <= et.y + 20) {
                                  return true;
                              }
                          }
                      }
                  }
                  break;
              case 2:
                  for (int i = 0; i < ets.size(); i++) {
                      EnemyTank et = ets.get(i);
                      if (et != this) {
                          if (et.direct == 0 || et.direct == 2) {
                              if (this.x >= et.x && this.x <= et.x + 20
                                      && this.y + 30 >= et.y
                                      && this.y + 30 <= et.y + 30) {
                                  return true;
                              }
                              if (this.x + 20 >= et.x && this.x + 20 <= et.x + 20
                                      && this.y + 30 >= et.y
                                      && this.y + 30 <= et.y + 30) {
                                  return true;
                              }
                          }
                          if (et.direct == 1 || et.direct == 3) {
                              if (this.x >= et.x && this.x <= et.x + 30
                                      && this.y + 30 >= et.y
                                      && this.y + 30 <= et.y + 20) {
                                  return true;
                              }
                              if (this.x + 20 >= et.x && this.x + 20 <= et.x + 30
                                      && this.y + 30 >= et.y
                                      && this.y + 30 <= et.y + 20) {
                                  return true;
                              }
                          }
                      }
                  }
                  break;
              case 3:
                  for (int i = 0; i < ets.size(); i++) {
                      EnemyTank et = ets.get(i);
                      if (et != this) {
                          if (et.direct == 0 || et.direct == 2) {
                              if (this.x >= et.x && this.x <= et.x + 20
                                      && this.y >= et.y && this.y <= et.y + 30) {
                                  return true;
                              }
                              if (this.x >= et.x && this.x <= et.x + 20
                                      && this.y + 20 >= et.y
                                      && this.y + 20 <= et.y + 30) {
                                  return true;
                              }
                          }
                          if (et.direct == 1 || et.direct == 3) {
                              if (this.x >= et.x && this.x <= et.x + 30
                                      && this.y >= et.y && this.y <= et.y + 20) {
                                  return true;
                              }
                              if (this.x >= et.x && this.x <= et.x + 30
                                      && this.y + 20 >= et.y
                                      && this.y + 20 <= et.y + 20) {
                                  return true;
                              }
                          }
                      }
                  }
                  break;
              }
              return b;
          }
      
          @Override
          public void run() {
              // TODO Auto-generated method stub
              while (true) {
                  try {
                      // 设置坦克休息一会
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  switch (this.direct) {
                  case 0:
                      // 说明坦克正在向上运动(继续往上走,符合实际)
                      // y -= speed;设置坦克平滑移动的效果
                      for (int i = 0; i < 30; i++) {
                          if (y > 0 && !this.isTouchOtherEnemy()) {
                              y -= speed;
                          }
                          try {
                              Thread.sleep(50);
                          } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                      }
                      break;
                  case 1:
                      for (int i = 0; i < 30; i++) {
                          // 这里注意坐标起点问题不是(400x300)
                          if (x < 400 && !this.isTouchOtherEnemy()) {
                              x += speed;
                          }
                          try {
                              Thread.sleep(50);
                          } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                      }
                      break;
                  case 2:
                      for (int i = 0; i < 30; i++) {
                          if (y < 300 && !this.isTouchOtherEnemy()) {
                              y += speed;
                          }
                          try {
                              Thread.sleep(50);
                          } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                      }
                      break;
                  case 3:
                      for (int i = 0; i < 30; i++) {
                          if (x > 0 && !this.isTouchOtherEnemy()) {
                              x -= speed;
                          }
                          try {
                              Thread.sleep(50);
                          } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                          }
                      }
                      break;
                  }
                  this.times++;
                  // 设置3秒发一颗子弹
                  if (times % 2 == 0) {
                      if (isLive) {
                          if (ss.size() < 5) {
                              Shot s = null;
                              // 没有子弹,添加
                              switch (direct) {
                              case 0:
                                  s = new Shot(x + 10, y, 0);
                                  ss.add(s);
                                  break;
                              case 1:
                                  s = new Shot(x + 30, y + 10, 1);
                                  ss.add(s);
                                  break;
                              case 2:
                                  s = new Shot(x + 10, y + 30, 2);
                                  ss.add(s);
                                  break;
                              case 3:
                                  s = new Shot(x, y + 10, 3);
                                  ss.add(s);
                                  break;
                              }
                              // 启动子弹线程
                              Thread t = new Thread(s);
                              t.start();
                          }
                      }
                  }
                  // 让坦克随机产生一个新的方向
                  this.direct = (int) (Math.random() * 4);
                  // 判断敌人坦克是否死亡了(双等号)
                  if (this.isLive == false) {
                      // 让坦克死亡,后退出线程
                      return;
                  }
      
              }
          }
      }
      
      // 我的坦克
      class Hero1_2 extends Tank1_2 {
          // 多个子弹,用向量创建
          Vector<Shot> ss = new Vector<Shot>();
          // 子弹
          Shot s = null;
      
          public Hero1_2(int x, int y) {
              super(x, y);
          }
      
          // 坦克开火
          public void shotEnemy() {
      
              switch (this.direct) {
              case 0:
                  s = new Shot(x + 10, y, 0);
                  // 把子弹加入向量
                  ss.add(s);
                  break;
      
              case 1:
                  s = new Shot(x + 30, y + 10, 1);
                  // 把子弹加入向量
                  ss.add(s);
                  break;
      
              case 2:
                  s = new Shot(x + 10, y + 30, 2);
                  // 把子弹加入向量
                  ss.add(s);
                  break;
      
              case 3:
                  s = new Shot(x, y + 10, 3);
                  // 把子弹加入向量
                  ss.add(s);
                  break;
              }
              // 启动子弹线程(创建线程,赶紧传参,我在这里吃了大亏!)
              Thread t = new Thread(s);
              t.start();
          }
      
          public void moveUp() {
              y -= speed;
          }
      
          public void moveRight() {
              x += speed;
          }
      
          public void moveDown() {
              y += speed;
          }
      
          public void moveLeft() {
              x -= speed;
          }
      }

      实现图片:

      相关素材:

      1.爆炸效果的图片(3张)

      2.游戏声音素材

      这个自己下载一个好啦(我的是上面命名为111.wav的文件,这里不支持上传)

      www.1click-soft.comtruehttp://www.1click-soft.com/Javabc/1304229.htmlTechArticleJava坦克大战(四),java坦克大战 这是我的坦克游戏大战的最后一版,里面添加很多新的功能。这个坦克大战的有很多不足之处,但是对于...

      相关文章

        暂无相关文章
      相关搜索:

      帮客评论

      视觉看点
      百度 360 搜狗