JAVA学习:坦克大战(怀旧版)游戏开发代码
这学期开了专业课《JAVA语言程序设计》,前面有一段时间跟着韩顺平老师的视频学习,顺着也把坦克大战的代码敲了出来。今天,应老汪的任务布置,在博客园上开了个人博客,主要目的在于学习交流,分享自己的点滴经验。这也是我在博客园上的第一篇随笔,罗嗦下~~~~
TankeGame1_3.java
/** * 功能:坦克大战 * 1.画出坦克 * 2.通过上下左右键控制坦克的移动 * 3.增加四辆敌人的坦克 * 4.画出了自己坦克的子弹,并能向敌人开火,子弹飞出去 * 5.子弹可以连发 * 6.子弹可以打死敌人的坦克,即子弹击中敌人坦克则敌人坦克消失 * 7.敌人的坦克击中我的坦克,则我的坦克消失 * 8.敌人的坦克运动时不能重叠在一起 * 9.游戏可以分关 * 9.1做一个分关panel,起提示作用 * 10.玩家在玩游戏时可以暂停 * 11.玩家结束游戏时可以保存游戏 */ import java.awt.*; import java.util.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.imageio.ImageIO; import javax.swing.*; import java.io.*; //定义MyHelpPanel,提示帮助信息 class MyHelpPanel extends JPanel { public void paint(Graphics g) { g.fill3DRect(0, 0, 570, 430, false); g.setColor(Color.blue); Font myfont = new Font("方正喵呜体",Font.BOLD,30); g.setFont(myfont); g.drawString("游戏帮助:", 30, 50); Font myfont1 = new Font("方正喵呜体",Font.BOLD,20); g.setFont(myfont1); g.drawString("1.↑,↓,←,→分别控制坦克的上下左右移动。", 38, 100); g.drawString("2.按下空格键可以发射子弹。", 38, 150); g.drawString("3.结束游戏可点击菜单栏的退出选项。", 38, 200); g.drawString("---稻草人工作室", 260, 260); } } //定义一个panel,提示首页信息 class MyStartPanel extends JPanel implements Runnable { int times = 0; public void paint(Graphics g) { g.fill3DRect(0, 0, 570, 430, false); //信息提示 if(times%2==0) { g.setColor(Color.blue); Font myfont = new Font("方正喵呜体",Font.BOLD,40); g.setFont(myfont); g.drawString("坦克大战游戏", 140, 150); Font myfont1 = new Font("方正喵呜体",Font.BOLD,25); g.setFont(myfont1); g.drawString("——稻草人工作室", 200, 200); } } @Override public void run() { // TODO Auto-generated method stub while(true) { //休眠一秒 try { Thread.sleep(1000); times++; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } //重画 this.repaint(); } } } //定义我的面板 class MyPanel extends JPanel implements KeyListener, Runnable { int x = 10, y = 10; // 定义一个我的坦克 Hero hero = null; // 定义敌人的坦克组 Vector<Enemy> en = new Vector<Enemy>(); Vector<Node> nodes = new Vector<Node>(); // 定义敌人的坦克数量 int encount = 3; // 定义炸弹向量集合 Vector<Bomb> bomb = new Vector<Bomb>(); // 构造函数 public MyPanel(String flag) { //恢复数据 Record.getRecord(); // 初始化我的坦克 hero = new Hero(80, 80); if(flag.equals("newgame")) { System.out.println("新游戏"); // 初始化敌人的坦克 for (int i = 0; i < encount; i++) { // 创建一辆坦克的对象 Enemy e = new Enemy((i + 1) * 50, 4); e.setColor(3);// 给定敌人的坦克颜色 e.setDirect(1);// 给定方向 // 启动敌人的坦克 Thread t = new Thread(e); t.start(); // 给敌人添加一颗子弹 Bullet b = new Bullet(e.x + 8, e.y + 35, 1); // 给敌人坦克加入子弹 e.bb.add(b); // 启动敌人子弹启动线程 Thread t2 = new Thread(b); t2.start(); en.add(e);// 加入 // 将panel里的敌人坦克向量交给敌人的坦克 e.setEn(en); } }else if(flag.equals("con")) { nodes = new Record().getNodes(); System.out.println(nodes.size()+"旧游戏"); // 初始化敌人的坦克 for (int i = 0; i < nodes.size(); i++) { //取出节点中的一辆坦克(即是上次幸存下来的敌人坦克) Node node = nodes.get(i); // 创建一辆坦克的对象 Enemy e = new Enemy(node.x, node.y); e.setColor(3);// 给定敌人的坦克颜色 e.setDirect(node.direct);// 给定方向 //将MyPanel的敌人坦克向量交给该敌人坦克 e.setEn(en); // 启动敌人的坦克 Thread t = new Thread(e); t.start(); // 给敌人添加一颗子弹 Bullet b = new Bullet(e.x + 8, e.y + 35, 1); // 给敌人坦克加入子弹 e.bb.add(b); // 启动敌人子弹启动线程 Thread t2 = new Thread(b); t2.start(); en.add(e);// 加入 } } // try{ // image1 = ImageIO.read(new File("bomb_1.gif")); // image2 = ImageIO.read(new File("bomb_2.gif")); // image3 = ImageIO.read(new File("bomb_3.gif")); // }catch(Exception e){ // e.printStackTrace(); // } //播放开战声音 AePlayWave apw = new AePlayWave("E:/TDDOWNLOAD/tankedazhan.wav"); apw.start(); // 初始化三张图片 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")); } // 定义三张坦克爆炸的图片 Image image1 = null; Image image2 = null; Image image3 = null; //画出提示信息的函数 public void ShowInfo(Graphics g) { //画出提示信息,用于显示坦克的数量 //画出当前敌人坦克数量 this.drawTanke(20, 306, g, 2, 0); g.setColor(Color.black); Font myfont = new Font("方正喵呜体",Font.BOLD,20); g.setFont(myfont); g.drawString(Record.getEnNum()+"辆", 60, 325); //画出当前我的坦克数量 this.drawTanke(125, 306, g, 2, 2); g.drawString(Record.getMyLife()+"辆", 165, 325); //画出玩家的总成绩 g.setColor(Color.black); g.drawString("你的总成绩为:", 405, 30); this.drawTanke(420, 45, g, 0, 0); g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*100, 445, 70); this.drawTanke(420, 105, g, 0, 1); g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*200, 445, 130); this.drawTanke(420, 165, g, 0, 2); g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*300, 445, 190); this.drawTanke(420, 225, g, 0, 3); g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*400, 445, 250); } // 重新paint public void paint(Graphics g) { super.paint(g); g.fillRect(0, 0, 400, 300);// 整个画面填充成黑色 //画出提示信息 this.ShowInfo(g); // 画出自己的坦克 if(hero.isLive) { this.drawTanke(hero.getX(), hero.getY(), g, this.hero.direct, 3); }else{ //this.remove(hero); } // 画自己坦克的子弹:从bb中取出每颗子弹,并画出来 for (int i = 0; i < hero.bb.size(); i++) { Bullet mybullet = hero.bb.get(i); // 画出子弹 if (mybullet != null && mybullet.isLive == true) { g.draw3DRect(mybullet.x, mybullet.y, 2, 2, false); } // 如果子弹死亡就把子弹从bb中删除 if (mybullet.isLive == false) { hero.bb.remove(mybullet); } } // 画出炸弹 for (int i = 0; i < bomb.size(); i++) { Bomb bo = bomb.get(i); if (bo.Life > 6) { g.drawImage(image1, bo.x, bo.y, 30, 30, this); } else if (bo.Life > 3) { g.drawImage(image2, bo.x, bo.y, 30, 30, this); } else { g.drawImage(image3, bo.x, bo.y, 30, 30, this); } // 生命值减减 bo.lifeDown(); if (bo.Life == 0) { bomb.remove(bo); } } // 画出敌人的坦克 for (int i = 0; i < en.size(); i++) { Enemy enemy = en.get(i); if (enemy.isLive) { this.drawTanke(enemy.getX(), enemy.getY(), g, enemy.getDirect(), 1); // 从bb中取出每颗子弹,并画出来 for (int j = 0; j < enemy.bb.size(); j++) { Bullet enemybullet = enemy.bb.get(j); // 画出子弹 if (enemybullet.isLive) { g.draw3DRect(enemybullet.x, enemybullet.y, 2, 2, false); } else// 如果这样就把子弹从bb中删除 { enemy.bb.remove(enemybullet); } } } } } // 判断我的子弹是否击中敌人的坦克的函数 public void ShootEnemies() { for (int i = 0; i < hero.bb.size(); i++) { // 取出子弹 Bullet bullet1 = hero.bb.get(i); // 判断子弹是否击中敌人 if (bullet1.isLive) { // 取出每个坦克与子弹判断是否击中 for (int j = 0; j < en.size(); j++) { // 取出坦克 Enemy enemy1 = en.get(j); if (enemy1.isLive) { if(this.ShootTanke(bullet1, enemy1)) { Record.ReduceenNum(); Record.DeadNum(); } } } } } } // 判断敌人的子弹是否击中我的坦克的函数 public void ShootHero() { for(int i=0;i<this.en.size();i++) { //取出敌人坦克 Enemy e = en.get(i); //取出每颗子弹判断是否击中我的坦克 if(e.isLive) { for(int j=0;j<e.bb.size();j++) { //取出子弹 Bullet bullet = e.bb.get(j); if(hero.isLive) { if(this.ShootTanke(bullet, hero)) { Record.HeroNum(); } } } } } } // 写一个专门函数判断子弹是否击中坦克 public boolean ShootTanke(Bullet b, Tanke ens) { boolean boo = false; // 判断坦克的方向 switch (ens.direct) { // 如果敌人的坦克是向上或者向下 case 0: case 1: if (b.x > ens.x && b.x < ens.x + 20 && b.y > ens.y && b.y < ens.y + 30) { // 击中,子弹死亡 b.isLive = false; // 敌人坦克死亡 ens.isLive = false; // Record.ReduceenNum(); // Record.DeadNum(); boo = true; // 创建炸弹爆炸 Bomb bo = new Bomb(ens.x, ens.y); // 放入炸弹的向量里 bomb.add(bo); } break; case 2: case 3: if (b.x > ens.x && b.x < ens.x + 30 && b.y > ens.y && b.y < ens.y + 20) { // 击中,子弹死亡 b.isLive = false; // 敌人坦克死亡 ens.isLive = false; boo = true; // 创建炸弹爆炸 Bomb bo = new Bomb(ens.x, ens.y); bomb.add(bo); } break; } return boo; } // 画坦克的函数(扩展) public void drawTanke(int x, int y, Graphics g, int direct, int type) { // 判断什么类型的坦克 switch (type) { case 0: g.setColor(Color.gray); break; case 1: g.setColor(Color.green); break; case 2: g.setColor(Color.blue); break; case 3: g.setColor(Color.red); break; } // 判断方向 switch (direct) { // 坦克向上移动 case 0: // 1.画左边的矩形框 g.fill3DRect(x, y, 5, 30, false); // 2.画右边的矩形框 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 + 10, x + 9, y - 7); g.drawLine(x + 10, y + 10, x + 10, y - 7); // 画左链条 g.drawLine(x, y + 5, x + 4, y + 5); g.drawLine(x, y + 10, x + 4, y + 10); g.drawLine(x, y + 15, x + 4, y + 15); g.drawLine(x, y + 20, x + 4, y + 20); g.drawLine(x, y + 25, x + 4, y + 25); // 画右边的链条 g.drawLine(x + 15, y + 5, x + 19, y + 5); g.drawLine(x + 15, y + 10, x + 19, y + 10); g.drawLine(x + 15, y + 15, x + 19, y + 15); g.drawLine(x + 15, y + 20, x + 19, y + 20); g.drawLine(x + 15, y + 25, x + 19, y + 25); break; // 坦克向下移动 case 1: // 1.画左边的矩形框 g.fill3DRect(x, y, 5, 30, false); // 2.画右边的矩形框 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 + 10, x + 9, y + 37); g.drawLine(x + 10, y + 10, x + 10, y + 37); // 画左链条 g.drawLine(x, y + 5, x + 4, y + 5); g.drawLine(x, y + 10, x + 4, y + 10); g.drawLine(x, y + 15, x + 4, y + 15); g.drawLine(x, y + 20, x + 4, y + 20); g.drawLine(x, y + 25, x + 4, y + 25); // 画右边的链条 g.drawLine(x + 15, y + 5, x + 19, y + 5); g.drawLine(x + 15, y + 10, x + 19, y + 10); g.drawLine(x + 15, y + 15, x + 19, y + 15); g.drawLine(x + 15, y + 20, x + 19, y + 20); g.drawLine(x + 15, y + 25, x + 19, y + 25); break; // 坦克向左移动 case 2: // 1.画上边的矩形框 g.fill3DRect(x, y, 30, 5, false); // 2.画下边的矩形框 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 + 9, x - 7, y + 9); g.drawLine(x + 15, y + 10, x - 7, y + 10); // 画上边的链条 g.drawLine(x + 5, y, x + 5, y + 4); g.drawLine(x + 10, y, x + 10, y + 4); g.drawLine(x + 15, y, x + 15, y + 4); g.drawLine(x + 20, y, x + 20, y + 4); g.drawLine(x + 25, y, x + 25, y + 4); // 画下边的链条 g.drawLine(x + 5, y + 15, x + 5, y + 19); g.drawLine(x + 10, y + 15, x + 10, y + 19); g.drawLine(x + 15, y + 15, x + 15, y + 19); g.drawLine(x + 20, y + 15, x + 20, y + 19); g.drawLine(x + 25, y + 15, x + 25, y + 19); break; // 坦克向右移动 case 3: // 1.画上边的矩形框 g.fill3DRect(x, y, 30, 5, false); // 2.画下边的矩形框 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 + 9, x + 35, y + 9); g.drawLine(x + 15, y + 10, x + 35, y + 10); // 画上边的链条 g.drawLine(x + 5, y, x + 5, y + 4); g.drawLine(x + 10, y, x + 10, y + 4); g.drawLine(x + 15, y, x + 15, y + 4); g.drawLine(x + 20, y, x + 20, y + 4); g.drawLine(x + 25, y, x + 25, y + 4); // 画下边的链条 g.drawLine(x + 5, y + 15, x + 5, y + 19); g.drawLine(x + 10, y + 15, x + 10, y + 19); g.drawLine(x + 15, y + 15, x + 15, y + 19); g.drawLine(x + 20, y + 15, x + 20, y + 19); g.drawLine(x + 25, y + 15, x + 25, y + 19); break; } } // 按下某一个键 public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP)// 上移 { this.hero.setDirect(0); this.hero.moveUp(); // 调用repaint()函数来重绘界面 this.repaint(); } else if (e.getKeyCode() == KeyEvent.VK_RIGHT)// 右移 { this.hero.setDirect(3); this.hero.moveRight(); // 调用repaint()函数来重绘界面 this.repaint(); } else if (e.getKeyCode() == KeyEvent.VK_LEFT)// 左移 { this.hero.setDirect(2); this.hero.moveLeft(); // 调用repaint()函数来重绘界面 this.repaint(); } else if (e.getKeyCode() == KeyEvent.VK_DOWN)// 下移 { this.hero.setDirect(1); this.hero.moveDown(); // 调用repaint()函数来重绘界面 this.repaint(); } // 判断玩家是否按下空格键,是否发出子弹 if (e.getKeyCode() == KeyEvent.VK_SPACE) { // 此时玩家按下空格键,则开火 if (this.hero.bb.size() < 5) { this.hero.Fire(); } } // 必须重新绘制Panel this.repaint(); } // 松开某一个键 public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } // 键的值被输出 public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(100);// 每隔100毫秒重绘 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //我打敌人 this.ShootEnemies(); //敌人打我 this.ShootHero(); // 重绘 this.repaint(); } } } public class TankeGame1_4 extends JFrame implements ActionListener{ //定义游戏面板 MyPanel mp = null; //定义一个开始面板 MyStartPanel msp = null; MyHelpPanel mhp = null; //定义菜单和菜单选项 JMenuBar jmb = null; JMenu jm1 = null,jm2 = null,jm3 = null; JMenuItem jmi1 = null, jmi2 = null,jmi3 = null, jmi4 = null, jmi5 = null,jmi6 = null,jmi7 = null; // 构造函数 public TankeGame1_4() { //创建菜单及菜单选项 jmb = new JMenuBar(); jm1 = new JMenu("游戏(G)"); jm2 = new JMenu("暂停/继续(Q)"); jm3 = new JMenu("帮助(H)"); jm1.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体 jm1.setMnemonic('G');//设置快捷方式 jm2.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体 jm2.setMnemonic('Q');//设置快捷方式 jm3.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体 jm3.setMnemonic('H');//设置快捷方式 jmi1 = new JMenuItem("开始新游戏(N)"); jmi2 = new JMenuItem("继续旧游戏(J)"); jmi3 = new JMenuItem("保存游戏(B)"); jmi4 = new JMenuItem("退出(E)"); jmi5 = new JMenuItem("暂停(S)"); jmi6 = new JMenuItem("继续(C)"); jmi7 = new JMenuItem("游戏制作"); jmi1.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi2.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi3.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi4.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi5.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi6.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi7.setFont(new Font("方正喵呜体", Font.BOLD, 15)); jmi1.setMnemonic('N');//设置快捷键 jmi2.setMnemonic('J');//设置快捷键 jmi3.setMnemonic('B');//设置快捷键 jmi4.setMnemonic('E');//设置快捷键 jmi5.setMnemonic('S');//设置快捷键 jmi6.setMnemonic('C');//设置快捷键 jm1.add(jmi1); jm1.add(jmi2); jm1.add(jmi3); jm1.add(jmi4); jm2.add(jmi5); jm2.add(jmi6); jm3.add(jmi7); jmb.add(jm1); jmb.add(jm2); jmb.add(jm3); //注册菜单项的监听 jmi1.addActionListener(this); jmi1.setActionCommand("newgame"); jmi2.addActionListener(this); jmi2.setActionCommand("jixu"); jmi3.addActionListener(this); jmi3.setActionCommand("save"); jmi4.addActionListener(this); jmi4.setActionCommand("exit"); jmi7.addActionListener(this); jmi7.setActionCommand("help"); msp = new MyStartPanel(); // 启动mp线程 Thread t = new Thread(msp); t.start(); this.setJMenuBar(jmb);//菜单Bar放到JFrame上 this.add(msp); this.setTitle("坦克大战"); this.setSize(570, 430); this.setLocation(300, 100);//设置游戏框在屏幕上出现的位置 this.setResizable(false);//游戏框不能修改大小 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { TankeGame1_4 tankegame1_1 = new TankeGame1_4(); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub //对监听到的用户的动作作出反应 if(e.getActionCommand().equals("newgame")) { //创建真正游戏面板 mp = new MyPanel("newgame"); Thread tt = new Thread(mp); tt.start(); this.remove(msp);//移除旧的MyStartPanel面板 this.add(mp);//添加游戏面板MyPanel // 注册监听 this.addKeyListener(mp); //显示一下新添加的面板,这样才能看到新面板。 this.setVisible(true); } else if(e.getActionCommand().equals("save")) { //保存当前游戏状态 System.out.println("保存"); Record record = new Record(); record.setEn(mp.en); record.keepEnemyRecord(); } else if(e.getActionCommand().endsWith("jixu")) { //创建真正游戏面板 mp = new MyPanel("con"); Thread tt = new Thread(mp); tt.start(); this.remove(msp);//移除旧的MyStartPanel面板 this.add(mp);//添加游戏面板MyPanel // 注册监听 this.addKeyListener(mp); //显示一下新添加的面板,这样才能看到新面板。 this.setVisible(true); } else if(e.getActionCommand().equals("exit")) { //退出前先保存游戏 Record record = new Record(); record.setEn(mp.en); record.keepEnemyRecord(); System.exit(0); } else if(e.getActionCommand().equals("help")) { mhp = new MyHelpPanel(); this.remove(msp); this.add(mhp); this.setVisible(true); } } }
Material.java
import java.util.Vector; import java.io.*; 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 Record { //从文件中读取记录点 static Vector<Node> nodes = new Vector<Node>(); //记录每关有多少敌人 private static int enNum = 20; //我的生命值 private static int myLife = 3; private static int allNum = 0; private static FileWriter fw = null; private static BufferedWriter bw = null; private static FileReader fr = null; private static BufferedReader br = null; private static Vector<Enemy> en = new Vector<Enemy>(); public Vector<Enemy> getEn() { return en; } public void setEn(Vector<Enemy> en1) { this.en = en1; } //写一个函数读取文件里的信息(敌人坦克数量、坐标、方向) public Vector<Node> getNodes() { try { fr = new FileReader("d:\\mykeepRecord.txt"); br = new BufferedReader(fr); String str = ""; str = br.readLine(); allNum = Integer.parseInt(str); while((str = br.readLine())!=null) { String string[] = str.split(" "); Node node = new Node(Integer.parseInt(string[0]), Integer.parseInt(string[1]),Integer.parseInt(string[2])); nodes.add(node); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ try { br.close(); fr.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } return nodes; } //退出保存我消灭的敌人坦克数量的记录 public static void keepRecord() { try { //创建txt文件 fw = new FileWriter("d:\\mykeepRecord.txt"); bw = new BufferedWriter(fw); bw.write(allNum+"\r\n"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ try { //关闭流,谁先开就后关,后开先关 bw.close(); fw.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } public void keepEnemyRecord() { try { //创建txt文件,保存被消灭的敌人坦克数 fw = new FileWriter("d:\\mykeepRecord.txt"); bw = new BufferedWriter(fw); bw.write(allNum+"\r\n"); //记录敌人活着的坦克的坐标、方向,为恢复游戏做准备。 for(int i = 0; i<en.size();i++) { //取出一辆坦克 Enemy e = en.get(i); if(e.isLive)//坦克还活着 { String enemyrecord = e.x+" "+e.y+" "+e.direct; //写入 bw.write(enemyrecord+"\r\n"); } } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ try { //关闭流,谁先开就后关,后开先关 bw.close(); fw.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } //读取击毁的敌人坦克数量记录 public static void getRecord() { try { fr = new FileReader("d:\\mykeepRecord.txt"); br = new BufferedReader(fr); String str = br.readLine(); allNum = Integer.parseInt(str); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ try { br.close(); fr.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } public static int getAllNum() { return allNum; } public static void setAllNum(int allNum) { Record.allNum = allNum; } public static int getEnNum() { return enNum; } public static void setEnNum(int enNum) { Record.enNum = enNum; } public static int getMyLife() { return myLife; } public static void setMyLife(int myLife) { Record.myLife = myLife; } //减少敌人数量 public static void ReduceenNum() { enNum--; } //被消灭的敌人的坦克 public static void DeadNum() { allNum++; } //若我被击中,我的坦克数量减少 public static void HeroNum() { myLife--; } } //炸弹类 class Bomb { int x, y; int Life = 9; 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 Bullet implements Runnable { int x, y,direct=0; boolean isLive = true; int speed = 3;//子弹的速度 public Bullet(int x, int y,int direct) { this.x = x; this.y = y; this.direct = direct; } public void run() { while(isLive){ //子弹先休息50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } switch(direct) { //子弹向上飞 case 0: y-=speed; break; //子弹向下飞 case 1: y+=speed; break; //子弹向左飞 case 2: x-=speed; break; //子弹向右飞 case 3: x+=speed; break; } //子弹何时死亡,判断子弹是否到达边缘 if(x < -2 || x > 400 || y < -2 || y > 296) { this.isLive = false; break; } } } } //坦克类 class Tanke{ int x = 0;//横坐标 int y = 0;//纵坐标 boolean isLive = true; int direct = 0; //0表示向上,1表示向下,2表示向左,3表示向右 int speed = 3;//定义速度 int type = 0;//坦克类型:0表示灰色,打一次就死;1表示绿色,打两次才死;2表示蓝色,打三次才死;3表示红色,打四次才死。 int color;//坦克颜色 public int getColor() { return color; } public void setEn(Vector<Enemy> vv) { // TODO Auto-generated method stub } public void setColor(int color) { this.color = color; } public int getType() { return type; } public void setType(int type) { this.type = type; } 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 Tanke(int x, int y){ this.x = x; this.y = y; } } //我的坦克 class Hero extends Tanke{ //子弹 //子弹向量组 Vector<Bullet> bb = new Vector<Bullet>(); Bullet b = null; //坦克 public Hero(int x,int y){ super(x,y); } //开火 public void Fire() { switch(this.direct) { //子弹向上 case 0: //创建一颗子弹 b = new Bullet(x+8, y-8,0); //把子弹加入到向量中 bb.add(b); break; //子弹向下 case 1: //创建一颗子弹 b = new Bullet(x+8, y+35,1); //把子弹加入到向量中 bb.add(b); break; //子弹向左 case 2: b = new Bullet(x-8,y+9,2); bb.add(b); break; //子弹向右 case 3: b = new Bullet(x+35, y+9,3); bb.add(b); break; } //启动子弹线程 Thread t = new Thread(b); t.start(); } //我的坦克向上移动 public void moveUp(){ if(y>0){ y-=speed; } } //我的坦克向下移动 public void moveDown(){ if(y<228){ y+=speed; } } //我的坦克向左移动 public void moveLeft(){ if(x>0){ x-=speed; } } //我的坦克向右移动 public void moveRight(){ if(x<350){ x+=speed; } } public void MyType(){ } } //敌人的坦克 class Enemy extends Tanke implements Runnable{ //定义敌人的坦克组,定义向量,可以访问到panel里敌人的坦克 Vector<Enemy> en = new Vector<Enemy>(); //定义敌人的子弹向量组 Vector<Bullet> bb = new Vector<Bullet>(); public Enemy(int x,int y) { super(x,y); } //得到panel里的敌人坦克向量 public void setEn(Vector<Enemy> vv) { this.en = vv; } //判断是否碰到了别的坦克 public boolean isTouchOtherEnemy() { boolean b = false; switch(this.direct) { case 0: //坦克向上,取出所有的敌人坦克 for(int i=0;i<en.size();i++) { //取出每一辆坦克 Enemy e = en.get(i); //如果不是自己的坦克 if(e!=this) { //如果敌人的坦克向上或者向下 if(e.direct==0||e.direct==1) { if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30) { return true; } if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y>=e.y&&this.y<=e.y+30) { return true; } } //如果敌人的坦克向左或者向右 if(e.direct==2||e.direct==3) { if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20) { return true; } if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y>=e.y&&this.y<=e.y+20) { return true; } } } } break; case 1: //坦克向下,取出所有的敌人坦克 for(int i=0;i<en.size();i++) { //取出每一辆坦克 Enemy e = en.get(i); //如果不是自己的坦克 if(e!=this) { //如果敌人的坦克向上或者向下 if(e.direct==0||e.direct==1) { if(this.x>=e.x&&this.x<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30) { return true; } if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30) { return true; } } //如果敌人的坦克向左或者向右 if(e.direct==2||e.direct==3) { if(this.x>=e.x&&this.x<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20) { return true; } if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20) { return true; } } } } break; case 2: //坦克向左,取出所有的敌人坦克 for(int i=0;i<en.size();i++) { //取出每一辆坦克 Enemy e = en.get(i); //如果不是自己的坦克 if(e!=this) { //如果敌人的坦克向上或者向下 if(e.direct==0||e.direct==1) { if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30) { return true; } if(this.x>=e.x&&this.x<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30) { return true; } } //如果敌人的坦克向左或者向右 if(e.direct==2||e.direct==3) { if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20) { return true; } if(this.x>=e.x&&this.x<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20) { return true; } } } } break; case 3: //坦克向上,取出所有的敌人坦克 for(int i=0;i<en.size();i++) { //取出每一辆坦克 Enemy e = en.get(i); //如果不是自己的坦克 if(e!=this) { //如果敌人的坦克向上或者向下 if(e.direct==0||e.direct==1) { if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y>=e.y&&this.y<=e.y+30) { return true; } if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30) { return true; } } //如果敌人的坦克向左或者向右 if(e.direct==2||e.direct==3) { if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y>=e.y&&this.y<=e.y+20) { return true; } if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20) { return true; } } } } break; } return b; } public void run() { // TODO Auto-generated method stub while(true) { //坦克休息80毫秒 try { Thread.sleep(80); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } switch(this.direct) { //坦克向上 case 0: for(int i=10;i>0;i--){ try { Thread.sleep(40); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(y>0&&!this.isTouchOtherEnemy()){ y-=speed; } } break; //下 case 1: for(int i=10;i>0;i--){ try { Thread.sleep(80); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(y<228&&!this.isTouchOtherEnemy()){ y+=speed; } } break; //左 case 2: for(int i=10;i>0;i--){ try { Thread.sleep(80); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(x>0&&!this.isTouchOtherEnemy()){ x-=speed; } } break; //右 case 3: for(int i=10;i>0;i--){ try { Thread.sleep(80); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(x<333&&!this.isTouchOtherEnemy()){ x+=speed; } } break; } //为敌人的坦克添加子弹连发 if(isLive) { if(bb.size()<3) { Bullet b = null; //没有子弹 ,则添加子弹 switch(this.direct) { //子弹向上 case 0: //创建一颗子弹 b = new Bullet(x+8, y-8,0); //把子弹加入到向量中 bb.add(b); break; //子弹向下 case 1: //创建一颗子弹 b = new Bullet(x+8, y+35,1); //把子弹加入到向量中 bb.add(b); break; //子弹向左 case 2: b = new Bullet(x-8,y+9,2); bb.add(b); break; //子弹向右 case 3: b = new Bullet(x+35, y+9,3); bb.add(b); break; } //启动子弹线程 Thread t = new Thread(b); t.start(); } } //让坦克随机产生一个数,来确定坦克的方向 this.direct =(int)(Math.random()*4); //判断坦克是否死亡 if(this.isLive == false){ break; } } } }
运行截图: