IO 流-利用到坦克大战

坦克大战0.5版

减少性能

  1. 避免敌人坦克重叠静止
  2. 记录玩家的总成绩(累积击毁敌方坦克数),存盘退出【io流】
  3. 记泉退出游戏时敌人坦克坐标/方向,存盘退出【io流】
  4. 玩游戏时,能够抉择是开新游戏还是持续上局游戏

package com.hspedu.tankgame5;/** * 炸弹 */public 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 {            isLive = false;        }    }}
package com.hspedu.tankgame5;import java.util.Vector;/** * 敌人的坦克 */@SuppressWarnings({"all"})public class EnemyTank extends Tank implements Runnable {    //在敌人坦克类,应用Vector 保留多个Shot    Vector<Shot> shots = new Vector<>();    //减少成员,EnemyTank 能够失去敌人坦克的Vector    //剖析    //1. Vector<EnemyTank> 在    Vector<EnemyTank> enemyTanks = new Vector<>();    boolean isLive = true;    public EnemyTank(int x, int y) {        super(x, y);    }    //这里提供一个办法,能够将MyPanel 的成员 Vector<EnemyTank> enemyTanks = new Vector<>();    //设置到 EnemyTank 的成员 enemyTanks    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {        this.enemyTanks = enemyTanks;    }    //编写办法,判断以后的这个敌人坦克,是否和 enemyTanks 中的其余坦克产生的重叠或者碰撞    public boolean isTouchEnemyTank() {        //判断以后敌人坦克(this) 方向        switch (this.getDirect()) {            case 0: //上                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY()]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右上角的坐标 [this.getX() + 40, this.getY()]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY()]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右上角的坐标 [this.getX() + 40, this.getY()]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 1: //右                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 右上角的坐标 [this.getX() + 60, this.getY()]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 40                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 右上角的坐标 [this.getX() + 60, this.getY()]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 60                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 2: //下                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 60]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 40                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 60]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 60                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 3: //左                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY() ]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 40]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY() ]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 40]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;        }        return  false;    }    @Override    public void run() {        while (true) {            //这里咱们判断如果shots size() =0, 创立一颗子弹,放入到            //shots汇合,并启动            if (isLive && shots.size() < 1) {                Shot s = null;                //判断坦克的方向,创立对应的子弹                switch (getDirect()) {                    case 0:                        s = new Shot(getX() + 20, getY(), 0);                        break;                    case 1:                        s = new Shot(getX() + 60, getY() + 20, 1);                        break;                    case 2: //向下                        s = new Shot(getX() + 20, getY() + 60, 2);                        break;                    case 3://向左                        s = new Shot(getX(), getY() + 20, 3);                        break;                }                shots.add(s);                //启动                new Thread(s).start();            }            //依据坦克的方向来持续冲动            switch (getDirect()) {                case 0:  //向上                    //让坦克放弃一个方向,走30步                    for (int i = 0; i < 30; i++) {                        if (getY() > 0 && !isTouchEnemyTank()) {                            moveUp();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 1:  //向右                    for (int i = 0; i < 30; i++) {                        if (getX() + 60 < 1000 && !isTouchEnemyTank()) {                            moveRight();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 2:  //向下                    for (int i = 0; i < 30; i++) {                        if (getY() + 60 < 750 && !isTouchEnemyTank()) {                            moveDown();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 3:  //向左                    for (int i = 0; i < 30; i++) {                        if (getX() > 0 && !isTouchEnemyTank()) {                            moveLeft();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;            }            //而后随机的扭转坦克方向 0-3            setDirect((int) (Math.random() * 4));            //写并发程序,肯定要思考分明,该线程什么时候完结            if (!isLive) {                break; //退出线程.            }        }    }}
package com.hspedu.tankgame5;import java.util.Vector;/** * 本人的坦克 */public class Hero extends Tank {    //定义一个Shot对象, 示意一个射击(线程)    Shot shot = null;    //能够发射多颗子弹    //Vector<Shot> shots = new Vector<>();    public Hero(int x, int y) {        super(x, y);    }    //射击    public void shotEnemyTank() {        //发多颗子弹怎么办, 管制在咱们的面板上,最多只有5颗//        if(shots.size() == 5) {//            return;//        }        //创立 Shot 对象, 依据以后Hero对象的地位和方向来创立Shot        switch (getDirect()) {//失去Hero对象方向            case 0: //向上                shot = new Shot(getX() + 20, getY(), 0);                break;            case 1: //向右                shot = new Shot(getX() + 60, getY() + 20, 1);                break;            case 2: //向下                shot = new Shot(getX() + 20, getY() + 60, 2);                break;            case 3: //向左                shot = new Shot(getX(), getY() + 20, 3);                break;        }        //把新创建的shot放入到shots        //shots.add(shot);        //启动咱们的Shot线程        new Thread(shot).start();    }}
package com.hspedu.tankgame5;import javax.swing.*;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.Scanner;public class HspTankGame05 extends JFrame {    // 定义MyPanel    MyPanel mp = null;    static Scanner scanner = new Scanner(System.in);    public static void main(String[] args) {        HspTankGame05 hspTankGame01 = new HspTankGame05();    }    public HspTankGame05() {        System.out.println("请输出抉择 1: 新游戏 2: 持续上局");        String key = scanner.next();        mp = new MyPanel(key);        //将mp 放入到Thread ,并启动        Thread thread = new Thread(mp);        thread.start();        this.add(mp);//把面板(就是游戏的绘图区域)        this.setSize(1300, 950);        this.addKeyListener(mp);//让JFrame 监听mp的键盘事件        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.setVisible(true);        //在JFrame 中减少相应敞开窗口的解决        this.addWindowListener(new WindowAdapter() {            @Override            public void windowClosing(WindowEvent e) {                Recorder.keepRecord();                System.exit(0);            }        });    }}
package com.hspedu.tankgame5;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.File;import java.io.FileInputStream;import java.util.Vector;/** * 坦克大战的绘图区域 *///为了监听 键盘事件, 实现KeyListener//为了让Panel 不停的重绘子弹,须要将 MyPanel 实现Runnable ,当做一个线程应用@SuppressWarnings({"all"})public class MyPanel extends JPanel implements KeyListener, Runnable {    //定义我的坦克    Hero hero = null;    //定义敌人坦克,放入到Vector    Vector<EnemyTank> enemyTanks = new Vector<>();    //定义一个寄存Node 对象的Vector, 用于复原敌人坦克的坐标和方向    Vector<Node> nodes = new Vector<>();    //定义一个Vector ,用于寄存炸弹    //阐明,当子弹击中坦克时,退出一个Bomb对象到bombs    Vector<Bomb> bombs = new Vector<>();    int enemyTankSize = 3;    //定义三张炸弹图片,用于显示爆炸成果    Image image1 = null;    Image image2 = null;    Image image3 = null;    public MyPanel(String key) {        nodes = Recorder.getNodesAndEnemyTankRec();        //将MyPanel对象的 enemyTanks 设置给 Recorder 的 enemyTanks        Recorder.setEnemyTanks(enemyTanks);        hero = new Hero(500, 100);//初始化本人坦克        switch (key) {            case "1":                //初始化敌人坦克                for (int i = 0; i < enemyTankSize; i++) {                    //创立一个敌人的坦克                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);                    //将enemyTanks 设置给 enemyTank !!!                    enemyTank.setEnemyTanks(enemyTanks);                    //设置方向                    enemyTank.setDirect(2);                    //启动敌人坦克线程,让他动起来                    new Thread(enemyTank).start();                    //给该enemyTank 退出一颗子弹                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());                    //退出enemyTank的Vector 成员                    enemyTank.shots.add(shot);                    //启动 shot 对象                    new Thread(shot).start();                    //退出                    enemyTanks.add(enemyTank);                }                break;            case "2": //持续上局游戏                //初始化敌人坦克                for (int i = 0; i < nodes.size(); i++) {                    Node node = nodes.get(i);                    //创立一个敌人的坦克                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());                    //将enemyTanks 设置给 enemyTank !!!                    enemyTank.setEnemyTanks(enemyTanks);                    //设置方向                    enemyTank.setDirect(node.getDirect());                    //启动敌人坦克线程,让他动起来                    new Thread(enemyTank).start();                    //给该enemyTank 退出一颗子弹                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());                    //退出enemyTank的Vector 成员                    enemyTank.shots.add(shot);                    //启动 shot 对象                    new Thread(shot).start();                    //退出                    enemyTanks.add(enemyTank);                }                break;            default:                System.out.println("你的输出有误...");        }        //初始化图片对象        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"));    }    //编写办法,显示我方击毁敌方坦克的信息    public void showInfo(Graphics g) {        //画出玩家的总成绩        g.setColor(Color.BLACK);        Font font = new Font("宋体", Font.BOLD, 25);        g.setFont(font);        g.drawString("您累积击毁敌方坦克", 1020, 30);        drawTank(1020, 60, g, 0, 0);//画出一个敌方坦克        g.setColor(Color.BLACK);//这里须要从新设置成彩色        g.drawString(Recorder.getAllEnemyTankNum() + "", 1080, 100);    }    @Override    public void paint(Graphics g) {        super.paint(g);        g.fillRect(0, 0, 1000, 750);//填充矩形,默认彩色        showInfo(g);        if (hero != null && hero.isLive) {            //画出本人坦克-封装办法            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);        }        //画出hero射击的子弹        if (hero.shot != null && hero.shot.isLive == true) {            g.draw3DRect(hero.shot.x, hero.shot.y, 1, 1, false);        }        //将hero的子弹汇合 shots ,遍历取出绘制//        for(int i = 0; i < hero.shots.size(); i++) {//            Shot shot = hero.shots.get(i);//            if (shot != null && shot.isLive) {//                g.draw3DRect(shot.x, shot.y, 1, 1, false);////            } else {//如果该shot对象曾经有效 ,就从shots汇合中拿掉//                hero.shots.remove(shot);//            }//        }        //如果bombs 汇合中有对象,就画出        for (int i = 0; i < bombs.size(); i++) {            //取出炸弹            Bomb bomb = bombs.get(i);            //依据以后这个bomb对象的life值去画出对应的图片            if (bomb.life > 6) {                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);            } else if (bomb.life > 3) {                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);            } else {                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);            }            //让这个炸弹的生命值缩小            bomb.lifeDown();            //如果bomb life 为0, 就从bombs 的汇合中删除            if (bomb.life == 0) {                bombs.remove(bomb);            }        }        //画出敌人的坦克, 遍历Vector        for (int i = 0; i < enemyTanks.size(); i++) {            //从Vector 取出坦克            EnemyTank enemyTank = enemyTanks.get(i);            //判断以后坦克是否还存活            if (enemyTank.isLive) {//当敌人坦克是存活的,才画出该坦克                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);                //画出 enemyTank 所有子弹                for (int j = 0; j < enemyTank.shots.size(); j++) {                    //取出子弹                    Shot shot = enemyTank.shots.get(j);                    //绘制                    if (shot.isLive) { //isLive == true                        g.draw3DRect(shot.x, shot.y, 1, 1, false);                    } else {                        //从Vector 移除                        enemyTank.shots.remove(shot);                    }                }            }        }    }    //编写办法,画出坦克    /**     * @param x      坦克的左上角x坐标     * @param y      坦克的左上角y坐标     * @param g      画笔     * @param direct 坦克方向(上下左右)     * @param type   坦克类型     */    public void drawTank(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;        }        //依据坦克方向,来绘制对应形态坦克        //direct 示意方向(0: 向上 1 向右 2 向下 3 向左 )        //        switch (direct) {            case 0: //示意向上                g.fill3DRect(x, y, 10, 60, false);//画出坦克右边轮子                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克左边轮子                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子                g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒                break;            case 1: //示意向右                g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子                g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒                break;            case 2: //示意向下                g.fill3DRect(x, y, 10, 60, false);//画出坦克右边轮子                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克左边轮子                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子                g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒                break;            case 3: //示意向左                g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子                g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒                break;            default:                System.out.println("临时没有解决");        }    }    //如果咱们的坦克能够发射多个子弹    //在判断我方子弹是否击中敌人坦克时,就须要把咱们的子弹汇合中    //所有的子弹,都取出和敌人的所有坦克,进行判断    //老韩给的局部代码..    public void hitEnemyTank() {//        //遍历咱们的子弹//        for(int j = 0;j < hero.shots.size();j++) {//            Shot shot = hero.shots.get(j);//            //判断是否击中了敌人坦克//            if (shot != null && hero.shot.isLive) {//当我的子弹还存活////                //遍历敌人所有的坦克//                for (int i = 0; i < enemyTanks.size(); i++) {//                    EnemyTank enemyTank = enemyTanks.get(i);//                    hitTank(hero.shot, enemyTank);//                }////            }//        }        //单颗子弹。        if (hero.shot != null && hero.shot.isLive) {//当我的子弹还存活            //遍历敌人所有的坦克            for (int i = 0; i < enemyTanks.size(); i++) {                EnemyTank enemyTank = enemyTanks.get(i);                hitTank(hero.shot, enemyTank);            }        }    }    //编写办法,判断敌人坦克是否击中我的坦克    public void hitHero() {        //遍历所有的敌人坦克        for (int i = 0; i < enemyTanks.size(); i++) {            //取出敌人坦克            EnemyTank enemyTank = enemyTanks.get(i);            //遍历enemyTank 对象的所有子弹            for (int j = 0; j < enemyTank.shots.size(); j++) {                //取出子弹                Shot shot = enemyTank.shots.get(j);                //判断 shot 是否击中我的坦克                if (hero.isLive && shot.isLive) {                    hitTank(shot, hero);                }            }        }    }    //编写办法,判断我方的子弹是否击中敌人坦克.    //什么时候判断 我方的子弹是否击中敌人坦克 ? run办法    //前面咱们将 enemyTank 改成 tank名称    public void hitTank(Shot s, Tank enemyTank) {        //判断s 击中坦克        switch (enemyTank.getDirect()) {            case 0: //坦克向上            case 2: //坦克向下                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60) {                    s.isLive = false;                    enemyTank.isLive = false;                    //当我的子弹击中敌人坦克后,将enemyTank 从Vector 拿掉                    enemyTanks.remove(enemyTank);                    //当我方击毁一个敌人坦克时,就对数据allEnemyTankNum++                    //解读, 因为 enemyTank 能够是 Hero 也能够是 EnemyTank                    if (enemyTank instanceof EnemyTank) {                        Recorder.addAllEnemyTankNum();                    }                    //创立Bomb对象,退出到bombs汇合                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());                    bombs.add(bomb);                }                break;            case 1: //坦克向右            case 3: //坦克向左                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40) {                    s.isLive = false;                    enemyTank.isLive = false;                    //当我的子弹击中敌人坦克后,将enemyTank 从Vector 拿掉                    enemyTanks.remove(enemyTank);                    //解读, 因为 enemyTank 能够是 Hero 也能够是 EnemyTank                    if (enemyTank instanceof EnemyTank) {                        Recorder.addAllEnemyTankNum();                    }                    //创立Bomb对象,退出到bombs汇合                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());                    bombs.add(bomb);                }                break;        }    }    @Override    public void keyTyped(KeyEvent e) {    }    //解决wdsa 键按下的状况    @Override    public void keyPressed(KeyEvent e) {        System.out.println(e.getKeyCode());        if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键            //扭转坦克的方向            hero.setDirect(0);//            //批改坦克的坐标 y -= 1            if (hero.getY() > 0) {                hero.moveUp();            }        } else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右            hero.setDirect(1);            if (hero.getX() + 60 < 1000) {                hero.moveRight();            }        } else if (e.getKeyCode() == KeyEvent.VK_S) {//S键            hero.setDirect(2);            if (hero.getY() + 60 < 750) {                hero.moveDown();            }        } else if (e.getKeyCode() == KeyEvent.VK_A) {//A键            hero.setDirect(3);            if (hero.getX() > 0) {                hero.moveLeft();            }        }        //如果用户按下的是J,就发射        if (e.getKeyCode() == KeyEvent.VK_J) {            //判断hero的子弹是否销毁,发射一颗子弹            if (hero.shot == null || !hero.shot.isLive) {                hero.shotEnemyTank();            }            //发射多颗子弹            //hero.shotEnemyTank();        }        //让面板重绘        this.repaint();    }    @Override    public void keyReleased(KeyEvent e) {    }    @Override    public void run() { //每隔 100毫秒,重绘区域, 刷新绘图区域, 子弹就挪动        while (true) {            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            //判断是咱们子弹否击中了敌人坦克            hitEnemyTank();            //判断敌人坦克是否击中咱们            hitHero();            this.repaint();        }    }}
package com.hspedu.tankgame5;/** * 一个Node 对象,示意一个敌人坦克的信息 */public class Node {    private int x;    private int y;    private int direct;    public Node(int x, int y, int direct) {        this.x = x;        this.y = y;        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 int getDirect() {        return direct;    }    public void setDirect(int direct) {        this.direct = direct;    }}
package com.hspedu.tankgame5;import java.io.*;import java.nio.Buffer;import java.util.Vector;/** * 该类用于记录相干信息的.和文件交互 */@SuppressWarnings({"all"})public class Recorder {    //定义变量,记录我方击毁敌人坦克数    private static int allEnemyTankNum = 0;    //定义IO对象, 筹备写数据到文件中    private static BufferedWriter bw = null;    private static BufferedReader br = null;    private static String recordFile = "e:\\myRecord.txt";    //定义Vector ,指向 MyPanel 对象的 敌人坦克Vector    private static Vector<EnemyTank> enemyTanks = null;    //定义一个Node 的Vector ,用于保留敌人的信息node    private static Vector<Node> nodes = new Vector<>();    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {        Recorder.enemyTanks = enemyTanks;    }    public static String getRecordFile() {        return recordFile;    }    //减少一个办法,用于读取recordFile, 复原相干信息    //该办法,在持续上局的时候调用即可    public static Vector<Node> getNodesAndEnemyTankRec() {        try {            br = new BufferedReader(new FileReader(recordFile));            allEnemyTankNum = Integer.parseInt(br.readLine());            //循环读取文件,生成nodes 汇合            String line = "";//255 40 0            while ((line = br.readLine()) != null) {                String[] xyd = line.split(" ");                Node node = new Node(Integer.parseInt(xyd[0]), Integer.parseInt(xyd[1]),                        Integer.parseInt(xyd[2]));                nodes.add(node); //放入nodes Vector            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (br != null) {                    br.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return nodes;    }    //减少一个办法,当游戏退出时,咱们将allEnemyTankNum 保留到 recordFile    //对keepRecord 进行降级, 保留敌人坦克的坐标和方向    public static void keepRecord() {        try {            bw = new BufferedWriter(new FileWriter(recordFile));            bw.write(allEnemyTankNum + "\r\n");            //遍历敌人坦克的Vector ,而后依据状况保留即可.            //OOP, 定义一个属性 ,而后通过setXxx失去 敌人坦克的Vector            for (int i = 0; i < enemyTanks.size(); i++) {                //取出敌人坦克                EnemyTank enemyTank = enemyTanks.get(i);                if (enemyTank.isLive) { //倡议判断.                    //保留该enemyTank信息                    String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();                    //写入到文件                    bw.write(record + "\r\n");                }            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (bw != null) {                    bw.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    public static int getAllEnemyTankNum() {        return allEnemyTankNum;    }    public static void setAllEnemyTankNum(int allEnemyTankNum) {        Recorder.allEnemyTankNum = allEnemyTankNum;    }    //当我方坦克击毁一个敌人坦克,就该当 allEnemyTankNum++    public static void addAllEnemyTankNum() {        Recorder.allEnemyTankNum++;    }}
package com.hspedu.tankgame5;/** * 射击子弹 */public class Shot implements Runnable {    int x; //子弹x坐标    int y; //子弹y坐标    int direct = 0; //子弹方向    int speed = 2; //子弹的速度    boolean isLive = true; //子弹是否还存活    //结构器    public Shot(int x, int y, int direct) {        this.x = x;        this.y = y;        this.direct = direct;    }    @Override    public void run() {//射击        while (true) {            //休眠 50毫秒            try {                Thread.sleep(50);            } catch (InterruptedException e) {                e.printStackTrace();            }            //依据方向来扭转x,y坐标            switch (direct) {                case 0://上                    y -= speed;                    break;                case 1://右                    x += speed;                    break;                case 2://下                    y += speed;                    break;                case 3://左                    x -= speed;                    break;            }            //老师测试,这里咱们输入x,y的坐标            System.out.println("子弹 x=" + x + " y=" + y);            //当子弹挪动到面板的边界时,就应该销毁(把启动的子弹的线程销毁)            //当子弹碰到敌人坦克时,也应该完结线程            if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750 && isLive)) {                System.out.println("子弹线程退出");                isLive = false;                break;            }        }    }}
package com.hspedu.tankgame5;public class Tank {    private int x;//坦克的横坐标    private int y;//坦克的纵坐标    private int direct = 0;//坦克方向 0 上1 右 2下 3左    private int speed = 1;    boolean isLive = true;    public int getSpeed() {        return speed;    }    public void setSpeed(int speed) {        this.speed = speed;    }    //上右下左挪动办法    public void moveUp() {        y -= speed;    }    public void moveRight() {        x += speed;    }    public void moveDown() {        y += speed;    }    public void moveLeft() {        x -= speed;    }    public int getDirect() {        return direct;    }    public void setDirect(int direct) {        this.direct = direct;    }    public Tank(int x, int y) {        this.x = x;        this.y = y;    }    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;    }}

坦克大战0.6版

减少性能

  1. 游戏开始时,播放经典的坦克大战音乐,[思路, 应用一个播放音乐的类,即可]
  2. 修改下文件存储地位
  3. 解决文件相干异样 =》提醒代码的健壮性
package com.hspedu.tankgame6;import javax.sound.sampled.*;import java.io.File;import java.io.IOException;public 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();        }    }}
package com.hspedu.tankgame6;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.io.File;import java.util.Vector;/** * 坦克大战的绘图区域 *///为了监听 键盘事件, 实现KeyListener//为了让Panel 不停的重绘子弹,须要将 MyPanel 实现Runnable ,当做一个线程应用@SuppressWarnings({"all"})public class MyPanel extends JPanel implements KeyListener, Runnable {    //定义我的坦克    Hero hero = null;    //定义敌人坦克,放入到Vector    Vector<EnemyTank> enemyTanks = new Vector<>();    //定义一个寄存Node 对象的Vector, 用于复原敌人坦克的坐标和方向    Vector<Node> nodes = new Vector<>();    //定义一个Vector ,用于寄存炸弹    //阐明,当子弹击中坦克时,退出一个Bomb对象到bombs    Vector<Bomb> bombs = new Vector<>();    int enemyTankSize = 3;    //定义三张炸弹图片,用于显示爆炸成果    Image image1 = null;    Image image2 = null;    Image image3 = null;    public MyPanel(String key) {        //先判断记录的文件是否存在        //如果存在,就失常执行,如果文件不存在,提醒,只能开启新游戏,key = "1"        File file = new File(Recorder.getRecordFile());        if (file.exists()) {            nodes = Recorder.getNodesAndEnemyTankRec();        } else {            System.out.println("文件不存在,只能开启新的游戏");            key = "1";        }        //将MyPanel对象的 enemyTanks 设置给 Recorder 的 enemyTanks        Recorder.setEnemyTanks(enemyTanks);        hero = new Hero(500, 100);//初始化本人坦克        switch (key) {            case "1":                //初始化敌人坦克                for (int i = 0; i < enemyTankSize; i++) {                    //创立一个敌人的坦克                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);                    //将enemyTanks 设置给 enemyTank !!!                    enemyTank.setEnemyTanks(enemyTanks);                    //设置方向                    enemyTank.setDirect(2);                    //启动敌人坦克线程,让他动起来                    new Thread(enemyTank).start();                    //给该enemyTank 退出一颗子弹                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());                    //退出enemyTank的Vector 成员                    enemyTank.shots.add(shot);                    //启动 shot 对象                    new Thread(shot).start();                    //退出                    enemyTanks.add(enemyTank);                }                break;            case "2": //持续上局游戏                //初始化敌人坦克                for (int i = 0; i < nodes.size(); i++) {                    Node node = nodes.get(i);                    //创立一个敌人的坦克                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());                    //将enemyTanks 设置给 enemyTank !!!                    enemyTank.setEnemyTanks(enemyTanks);                    //设置方向                    enemyTank.setDirect(node.getDirect());                    //启动敌人坦克线程,让他动起来                    new Thread(enemyTank).start();                    //给该enemyTank 退出一颗子弹                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());                    //退出enemyTank的Vector 成员                    enemyTank.shots.add(shot);                    //启动 shot 对象                    new Thread(shot).start();                    //退出                    enemyTanks.add(enemyTank);                }                break;            default:                System.out.println("你的输出有误...");        }        //初始化图片对象        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"));        //这里,播放指定的音乐        new AePlayWave("src\\111.wav").start();    }    //编写办法,显示我方击毁敌方坦克的信息    public void showInfo(Graphics g) {        //画出玩家的总成绩        g.setColor(Color.BLACK);        Font font = new Font("宋体", Font.BOLD, 25);        g.setFont(font);        g.drawString("您累积击毁敌方坦克", 1020, 30);        drawTank(1020, 60, g, 0, 0);//画出一个敌方坦克        g.setColor(Color.BLACK);//这里须要从新设置成彩色        g.drawString(Recorder.getAllEnemyTankNum() + "", 1080, 100);    }    @Override    public void paint(Graphics g) {        super.paint(g);        g.fillRect(0, 0, 1000, 750);//填充矩形,默认彩色        showInfo(g);        if (hero != null && hero.isLive) {            //画出本人坦克-封装办法            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);        }        //画出hero射击的子弹        if (hero.shot != null && hero.shot.isLive == true) {            g.draw3DRect(hero.shot.x, hero.shot.y, 1, 1, false);        }        //将hero的子弹汇合 shots ,遍历取出绘制//        for(int i = 0; i < hero.shots.size(); i++) {//            Shot shot = hero.shots.get(i);//            if (shot != null && shot.isLive) {//                g.draw3DRect(shot.x, shot.y, 1, 1, false);////            } else {//如果该shot对象曾经有效 ,就从shots汇合中拿掉//                hero.shots.remove(shot);//            }//        }        //如果bombs 汇合中有对象,就画出        for (int i = 0; i < bombs.size(); i++) {            //取出炸弹            Bomb bomb = bombs.get(i);            //依据以后这个bomb对象的life值去画出对应的图片            if (bomb.life > 6) {                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);            } else if (bomb.life > 3) {                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);            } else {                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);            }            //让这个炸弹的生命值缩小            bomb.lifeDown();            //如果bomb life 为0, 就从bombs 的汇合中删除            if (bomb.life == 0) {                bombs.remove(bomb);            }        }        //画出敌人的坦克, 遍历Vector        for (int i = 0; i < enemyTanks.size(); i++) {            //从Vector 取出坦克            EnemyTank enemyTank = enemyTanks.get(i);            //判断以后坦克是否还存活            if (enemyTank.isLive) {//当敌人坦克是存活的,才画出该坦克                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);                //画出 enemyTank 所有子弹                for (int j = 0; j < enemyTank.shots.size(); j++) {                    //取出子弹                    Shot shot = enemyTank.shots.get(j);                    //绘制                    if (shot.isLive) { //isLive == true                        g.draw3DRect(shot.x, shot.y, 1, 1, false);                    } else {                        //从Vector 移除                        enemyTank.shots.remove(shot);                    }                }            }        }    }    //编写办法,画出坦克    /**     * @param x      坦克的左上角x坐标     * @param y      坦克的左上角y坐标     * @param g      画笔     * @param direct 坦克方向(上下左右)     * @param type   坦克类型     */    public void drawTank(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;        }        //依据坦克方向,来绘制对应形态坦克        //direct 示意方向(0: 向上 1 向右 2 向下 3 向左 )        //        switch (direct) {            case 0: //示意向上                g.fill3DRect(x, y, 10, 60, false);//画出坦克右边轮子                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克左边轮子                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子                g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒                break;            case 1: //示意向右                g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子                g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒                break;            case 2: //示意向下                g.fill3DRect(x, y, 10, 60, false);//画出坦克右边轮子                g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克左边轮子                g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子                g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子                g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒                break;            case 3: //示意向左                g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子                g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子                g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子                g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子                g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒                break;            default:                System.out.println("临时没有解决");        }    }    //如果咱们的坦克能够发射多个子弹    //在判断我方子弹是否击中敌人坦克时,就须要把咱们的子弹汇合中    //所有的子弹,都取出和敌人的所有坦克,进行判断    //老韩给的局部代码..    public void hitEnemyTank() {//        //遍历咱们的子弹//        for(int j = 0;j < hero.shots.size();j++) {//            Shot shot = hero.shots.get(j);//            //判断是否击中了敌人坦克//            if (shot != null && hero.shot.isLive) {//当我的子弹还存活////                //遍历敌人所有的坦克//                for (int i = 0; i < enemyTanks.size(); i++) {//                    EnemyTank enemyTank = enemyTanks.get(i);//                    hitTank(hero.shot, enemyTank);//                }////            }//        }        //单颗子弹。        if (hero.shot != null && hero.shot.isLive) {//当我的子弹还存活            //遍历敌人所有的坦克            for (int i = 0; i < enemyTanks.size(); i++) {                EnemyTank enemyTank = enemyTanks.get(i);                hitTank(hero.shot, enemyTank);            }        }    }    //编写办法,判断敌人坦克是否击中我的坦克    public void hitHero() {        //遍历所有的敌人坦克        for (int i = 0; i < enemyTanks.size(); i++) {            //取出敌人坦克            EnemyTank enemyTank = enemyTanks.get(i);            //遍历enemyTank 对象的所有子弹            for (int j = 0; j < enemyTank.shots.size(); j++) {                //取出子弹                Shot shot = enemyTank.shots.get(j);                //判断 shot 是否击中我的坦克                if (hero.isLive && shot.isLive) {                    hitTank(shot, hero);                }            }        }    }    //编写办法,判断我方的子弹是否击中敌人坦克.    //什么时候判断 我方的子弹是否击中敌人坦克 ? run办法    //前面咱们将 enemyTank 改成 tank名称    public void hitTank(Shot s, Tank enemyTank) {        //判断s 击中坦克        switch (enemyTank.getDirect()) {            case 0: //坦克向上            case 2: //坦克向下                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60) {                    s.isLive = false;                    enemyTank.isLive = false;                    //当我的子弹击中敌人坦克后,将enemyTank 从Vector 拿掉                    enemyTanks.remove(enemyTank);                    //当我方击毁一个敌人坦克时,就对数据allEnemyTankNum++                    //解读, 因为 enemyTank 能够是 Hero 也能够是 EnemyTank                    if (enemyTank instanceof EnemyTank) {                        Recorder.addAllEnemyTankNum();                    }                    //创立Bomb对象,退出到bombs汇合                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());                    bombs.add(bomb);                }                break;            case 1: //坦克向右            case 3: //坦克向左                if (s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60                        && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40) {                    s.isLive = false;                    enemyTank.isLive = false;                    //当我的子弹击中敌人坦克后,将enemyTank 从Vector 拿掉                    enemyTanks.remove(enemyTank);                    //解读, 因为 enemyTank 能够是 Hero 也能够是 EnemyTank                    if (enemyTank instanceof EnemyTank) {                        Recorder.addAllEnemyTankNum();                    }                    //创立Bomb对象,退出到bombs汇合                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());                    bombs.add(bomb);                }                break;        }    }    @Override    public void keyTyped(KeyEvent e) {    }    //解决wdsa 键按下的状况    @Override    public void keyPressed(KeyEvent e) {        System.out.println(e.getKeyCode());        if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键            //扭转坦克的方向            hero.setDirect(0);//            //批改坦克的坐标 y -= 1            if (hero.getY() > 0) {                hero.moveUp();            }        } else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右            hero.setDirect(1);            if (hero.getX() + 60 < 1000) {                hero.moveRight();            }        } else if (e.getKeyCode() == KeyEvent.VK_S) {//S键            hero.setDirect(2);            if (hero.getY() + 60 < 750) {                hero.moveDown();            }        } else if (e.getKeyCode() == KeyEvent.VK_A) {//A键            hero.setDirect(3);            if (hero.getX() > 0) {                hero.moveLeft();            }        }        //如果用户按下的是J,就发射        if (e.getKeyCode() == KeyEvent.VK_J) {            //判断hero的子弹是否销毁,发射一颗子弹            if (hero.shot == null || !hero.shot.isLive) {                hero.shotEnemyTank();            }            //发射多颗子弹            //hero.shotEnemyTank();        }        //让面板重绘        this.repaint();    }    @Override    public void keyReleased(KeyEvent e) {    }    @Override    public void run() { //每隔 100毫秒,重绘区域, 刷新绘图区域, 子弹就挪动        while (true) {            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }            //判断是咱们子弹否击中了敌人坦克            hitEnemyTank();            //判断敌人坦克是否击中咱们            hitHero();            this.repaint();        }    }}
package com.hspedu.tankgame5;import java.io.*;import java.nio.Buffer;import java.util.Vector;/** * 该类用于记录相干信息的.和文件交互 */@SuppressWarnings({"all"})public class Recorder {    //定义变量,记录我方击毁敌人坦克数    private static int allEnemyTankNum = 0;    //定义IO对象, 筹备写数据到文件中    private static BufferedWriter bw = null;    private static BufferedReader br = null;    private static String recordFile = "e:\\myRecord.txt";    //定义Vector ,指向 MyPanel 对象的 敌人坦克Vector    private static Vector<EnemyTank> enemyTanks = null;    //定义一个Node 的Vector ,用于保留敌人的信息node    private static Vector<Node> nodes = new Vector<>();    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {        Recorder.enemyTanks = enemyTanks;    }    public static String getRecordFile() {        return recordFile;    }    //减少一个办法,用于读取recordFile, 复原相干信息    //该办法,在持续上局的时候调用即可    public static Vector<Node> getNodesAndEnemyTankRec() {        try {            br = new BufferedReader(new FileReader(recordFile));            allEnemyTankNum = Integer.parseInt(br.readLine());            //循环读取文件,生成nodes 汇合            String line = "";//255 40 0            while ((line = br.readLine()) != null) {                String[] xyd = line.split(" ");                Node node = new Node(Integer.parseInt(xyd[0]), Integer.parseInt(xyd[1]),                        Integer.parseInt(xyd[2]));                nodes.add(node); //放入nodes Vector            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (br != null) {                    br.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return nodes;    }    //减少一个办法,当游戏退出时,咱们将allEnemyTankNum 保留到 recordFile    //对keepRecord 进行降级, 保留敌人坦克的坐标和方向    public static void keepRecord() {        try {            bw = new BufferedWriter(new FileWriter(recordFile));            bw.write(allEnemyTankNum + "\r\n");            //遍历敌人坦克的Vector ,而后依据状况保留即可.            //OOP, 定义一个属性 ,而后通过setXxx失去 敌人坦克的Vector            for (int i = 0; i < enemyTanks.size(); i++) {                //取出敌人坦克                EnemyTank enemyTank = enemyTanks.get(i);                if (enemyTank.isLive) { //倡议判断.                    //保留该enemyTank信息                    String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();                    //写入到文件                    bw.write(record + "\r\n");                }            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (bw != null) {                    bw.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }    public static int getAllEnemyTankNum() {        return allEnemyTankNum;    }    public static void setAllEnemyTankNum(int allEnemyTankNum) {        Recorder.allEnemyTankNum = allEnemyTankNum;    }    //当我方坦克击毁一个敌人坦克,就该当 allEnemyTankNum++    public static void addAllEnemyTankNum() {        Recorder.allEnemyTankNum++;    }}
package com.hspedu.tankgame6;/** * 炸弹 */public 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 {            isLive = false;        }    }}
package com.hspedu.tankgame6;import java.util.Vector;/** * 敌人的坦克 */@SuppressWarnings({"all"})public class EnemyTank extends Tank implements Runnable {    //在敌人坦克类,应用Vector 保留多个Shot    Vector<Shot> shots = new Vector<>();    //减少成员,EnemyTank 能够失去敌人坦克的Vector    //剖析    //1. Vector<EnemyTank> 在    Vector<EnemyTank> enemyTanks = new Vector<>();    boolean isLive = true;    public EnemyTank(int x, int y) {        super(x, y);    }    //这里提供一个办法,能够将MyPanel 的成员 Vector<EnemyTank> enemyTanks = new Vector<>();    //设置到 EnemyTank 的成员 enemyTanks    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {        this.enemyTanks = enemyTanks;    }    //编写办法,判断以后的这个敌人坦克,是否和 enemyTanks 中的其余坦克产生的重叠或者碰撞    public boolean isTouchEnemyTank() {        //判断以后敌人坦克(this) 方向        switch (this.getDirect()) {            case 0: //上                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //老韩剖析                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY()]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右上角的坐标 [this.getX() + 40, this.getY()]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //老韩剖析                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY()]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右上角的坐标 [this.getX() + 40, this.getY()]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 1: //右                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //老韩剖析                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 右上角的坐标 [this.getX() + 60, this.getY()]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 40                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //老韩剖析                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 右上角的坐标 [this.getX() + 60, this.getY()]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]                            if (this.getX() + 60 >= enemyTank.getX()                                    && this.getX() + 60 <= enemyTank.getX() + 60                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 2: //下                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //老韩剖析                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 60]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 40                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //老韩剖析                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 60]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]                            if (this.getX() + 40 >= enemyTank.getX()                                    && this.getX() + 40 <= enemyTank.getX() + 60                                    && this.getY() + 60 >= enemyTank.getY()                                    && this.getY() + 60 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;            case 3: //左                //让以后敌人坦克和其它所有的敌人坦克比拟                for (int i = 0; i < enemyTanks.size(); i++) {                    //从vector 中取出一个敌人坦克                    EnemyTank enemyTank = enemyTanks.get(i);                    //不和本人比拟                    if (enemyTank != this) {                        //如果敌人坦克是上/下                        //老韩剖析                        //1. 如果敌人坦克是上/下 x的范畴 [enemyTank.getX(), enemyTank.getX() + 40]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 60]                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY() ]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 60) {                                return true;                            }                            //3. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 40]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 40                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 60) {                                return true;                            }                        }                        //如果敌人坦克是 右/左                        //老韩剖析                        //1. 如果敌人坦克是右/左  x的范畴 [enemyTank.getX(), enemyTank.getX() + 60]                        //                     y的范畴 [enemyTank.getY(), enemyTank.getY() + 40]                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {                            //2. 以后坦克 左上角的坐标 [this.getX(), this.getY() ]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() >= enemyTank.getY()                                    && this.getY() <= enemyTank.getY() + 40) {                                return true;                            }                            //3. 以后坦克 左下角的坐标 [this.getX(), this.getY() + 40]                            if (this.getX() >= enemyTank.getX()                                    && this.getX() <= enemyTank.getX() + 60                                    && this.getY() + 40 >= enemyTank.getY()                                    && this.getY() + 40 <= enemyTank.getY() + 40) {                                return true;                            }                        }                    }                }                break;        }        return  false;    }    @Override    public void run() {        while (true) {            //这里咱们判断如果shots size() =0, 创立一颗子弹,放入到            //shots汇合,并启动            if (isLive && shots.size() < 1) {                Shot s = null;                //判断坦克的方向,创立对应的子弹                switch (getDirect()) {                    case 0:                        s = new Shot(getX() + 20, getY(), 0);                        break;                    case 1:                        s = new Shot(getX() + 60, getY() + 20, 1);                        break;                    case 2: //向下                        s = new Shot(getX() + 20, getY() + 60, 2);                        break;                    case 3://向左                        s = new Shot(getX(), getY() + 20, 3);                        break;                }                shots.add(s);                //启动                new Thread(s).start();            }            //依据坦克的方向来持续冲动            switch (getDirect()) {                case 0:  //向上                    //让坦克放弃一个方向,走30步                    for (int i = 0; i < 30; i++) {                        if (getY() > 0 && !isTouchEnemyTank()) {                            moveUp();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 1:  //向右                    for (int i = 0; i < 30; i++) {                        if (getX() + 60 < 1000 && !isTouchEnemyTank()) {                            moveRight();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 2:  //向下                    for (int i = 0; i < 30; i++) {                        if (getY() + 60 < 750 && !isTouchEnemyTank()) {                            moveDown();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;                case 3:  //向左                    for (int i = 0; i < 30; i++) {                        if (getX() > 0 && !isTouchEnemyTank()) {                            moveLeft();                        }                        //休眠50毫秒                        try {                            Thread.sleep(50);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    break;            }            //而后随机的扭转坦克方向 0-3            setDirect((int) (Math.random() * 4));            //听老韩说,写并发程序,肯定要思考分明,该线程什么时候完结            if (!isLive) {                break; //退出线程.            }        }    }}
package com.hspedu.tankgame6;/** * 本人的坦克 */public class Hero extends Tank {    //定义一个Shot对象, 示意一个射击(线程)    Shot shot = null;    //能够发射多颗子弹    //Vector<Shot> shots = new Vector<>();    public Hero(int x, int y) {        super(x, y);    }    //射击    public void shotEnemyTank() {        //发多颗子弹怎么办, 管制在咱们的面板上,最多只有5颗//        if(shots.size() == 5) {//            return;//        }        //创立 Shot 对象, 依据以后Hero对象的地位和方向来创立Shot        switch (getDirect()) {//失去Hero对象方向            case 0: //向上                shot = new Shot(getX() + 20, getY(), 0);                break;            case 1: //向右                shot = new Shot(getX() + 60, getY() + 20, 1);                break;            case 2: //向下                shot = new Shot(getX() + 20, getY() + 60, 2);                break;            case 3: //向左                shot = new Shot(getX(), getY() + 20, 3);                break;        }        //把新创建的shot放入到shots        //shots.add(shot);        //启动咱们的Shot线程        new Thread(shot).start();    }}
package com.hspedu.tankgame6;import javax.swing.*;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.Scanner;public class HspTankGame06 extends JFrame {    //定义MyPanel    MyPanel mp = null;    static Scanner scanner = new Scanner(System.in);    public static void main(String[] args) {        HspTankGame06 hspTankGame01 = new HspTankGame06();    }    public HspTankGame06() {        System.out.println("请输出抉择 1: 新游戏 2: 持续上局");        String key = scanner.next();        mp = new MyPanel(key);        //将mp 放入到Thread ,并启动        Thread thread = new Thread(mp);        thread.start();        this.add(mp);//把面板(就是游戏的绘图区域)        this.setSize(1300, 950);        this.addKeyListener(mp);//让JFrame 监听mp的键盘事件        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.setVisible(true);        //在JFrame 中减少相应敞开窗口的解决        this.addWindowListener(new WindowAdapter() {            @Override            public void windowClosing(WindowEvent e) {                Recorder.keepRecord();                System.exit(0);            }        });    }}
package com.hspedu.tankgame6;/** * 一个Node 对象,示意一个敌人坦克的信息 */public class Node {    private int x;    private int y;    private int direct;    public Node(int x, int y, int direct) {        this.x = x;        this.y = y;        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 int getDirect() {        return direct;    }    public void setDirect(int direct) {        this.direct = direct;    }}
package com.hspedu.tankgame6;/** * 射击子弹 */public class Shot implements Runnable {    int x; //子弹x坐标    int y; //子弹y坐标    int direct = 0; //子弹方向    int speed = 2; //子弹的速度    boolean isLive = true; //子弹是否还存活    //结构器    public Shot(int x, int y, int direct) {        this.x = x;        this.y = y;        this.direct = direct;    }    @Override    public void run() {//射击        while (true) {            //休眠 50毫秒            try {                Thread.sleep(50);            } catch (InterruptedException e) {                e.printStackTrace();            }            //依据方向来扭转x,y坐标            switch (direct) {                case 0://上                    y -= speed;                    break;                case 1://右                    x += speed;                    break;                case 2://下                    y += speed;                    break;                case 3://左                    x -= speed;                    break;            }            //老师测试,这里咱们输入x,y的坐标            //System.out.println("子弹 x=" + x + " y=" + y);            //当子弹挪动到面板的边界时,就应该销毁(把启动的子弹的线程销毁)            //当子弹碰到敌人坦克时,也应该完结线程            if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750 && isLive)) {                System.out.println("子弹线程退出");                isLive = false;                break;            }        }    }}
package com.hspedu.tankgame6;public class Tank {    private int x;//坦克的横坐标    private int y;//坦克的纵坐标    private int direct = 0;//坦克方向 0 上1 右 2下 3左    private int speed = 1;    boolean isLive = true;    public int getSpeed() {        return speed;    }    public void setSpeed(int speed) {        this.speed = speed;    }    //上右下左挪动办法    public void moveUp() {        y -= speed;    }    public void moveRight() {        x += speed;    }    public void moveDown() {        y += speed;    }    public void moveLeft() {        x -= speed;    }    public int getDirect() {        return direct;    }    public void setDirect(int direct) {        this.direct = direct;    }    public Tank(int x, int y) {        this.x = x;        this.y = y;    }    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;    }}