观看完韩顺平老师的坦克大战项目之后写的优化版本

在韩顺平老师的坦克大战基础之上和在博客中观看各位别的大佬写的坦克大战内容,也是自己进行了一些新功能的添加(大一新生,写的内容可能并不完美,不喜勿喷)

新增功能如下:

1.增加了地形设置,黄墙代表木墙(可被破坏),灰墙代表铁墙(无法被破坏)

2.坦克发射子弹有时间间隔(设置为了500ms)

3.坦克被击毁一辆之后会再次刷新一辆新的坦克(以确保场上永远有5辆坦克)

4.当击毁敌方十辆坦克之后显示出游戏结束界面,我方坦克被击毁后也显示游戏结束界面

5.当选择继续上一局游戏时,先前被破坏的地形也会被记录下来而不是重置

另外,本代码中未添加音乐类,因为当初看视频学习的时候韩老师并未太过提及和重视,因此也就偷了个懒没写(

MyPanel类:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Iterator;
import java.util.Vector;

//为了让panel不停地重绘子弹,需要将MyPanel实现Runnable接口,当作一个线程使用
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<Itemnode> itemnodes = new Vector<>();
    //定义一个Vector用于存放炸弹
    //当子弹击中坦克时,就加入一个Bomb对象到bombs
    Vector<Bomb> bombs = new Vector<>();

    Vector<Wood> woods = new Vector<>();
    Vector<Metal> metals = new Vector<>();
    int enemyTankSize = 5;

    int count = 0; //控制敌方坦克生成速度

    //定义三张炸弹图片,用于显示爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;
    int destroyedEnemyTanks = 0; // 记录我方击毁的敌方坦克数量

    boolean gameOver = false; // 游戏结束状态标志

    public MyPanel(String key) {
        //先判断记录的文件是否存在
        //如果存在,就正常执行,如果文件不存在,提示,只能开启新游戏,key = “1”;
        File file = new File(Recorder.getRecordFile());
        if (file.exists()) {
            nodes = Recorder.getNodesAndEnemyTankRec();
            itemnodes = Recorder.getItemNodes();
        } else {
            System.out.println("文件不存在,只能开启新游戏");
            key = "1";
        }
        //将MyPanel对象的enemyTanks设置给Recorder的enemyTanks
        Recorder.setWoods(woods);
        Recorder.setEnemyTanks(enemyTanks);
        hero = new Hero(800, 600);//初始化自己的坦克
        hero.setSpeed(4);  //体现封装

        switch (key) {
            case "1":
                //初始化敌人的坦克
                for (int i = 0; i < enemyTankSize; i++) {
                    //创建敌人的坦克
                    EnemyTank tank = new EnemyTank((100 * (i + 1)), 0);
                    //将enemyTanks设置给tank
                    tank.setEnemyTanks(enemyTanks);
                    //将障碍物设置给tank去检测
                    tank.setMetals(metals);
                    tank.setWoods(woods);
                    hero.setMetals(metals);
                    hero.setWoods(woods);
                    //设置方向
                    tank.setDirect(2);
                    //启动敌人坦克线程,让它动起来
                    new Thread(tank).start();
                    //给enemyTank加入一颗子弹
                    Shot shot = new Shot(tank.getX() + 20, tank.getY() + 60, tank.getDirect());
                    //加入enemyTank的Vector成员
                    tank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    //加入
                    enemyTanks.add(tank);
                }
                for (int i = 0; i < 2; i++) {
                    Metal metal1 = new Metal(260 + 40 * i, 340);
                    metals.add(metal1);
                    Metal metal2 = new Metal(560 + 40 * i, 340);
                    metals.add(metal2);
                }
                for (int i = 0; i < 6; i++) {
                    Wood wood = new Wood(120, 80 + i * 40);
                    woods.add(wood);
                    Wood wood1 = new Wood(120, 400 + i * 40);
                    woods.add(wood1);
                    Wood wood2 = new Wood(420, 80 + i * 40);
                    woods.add(wood2);
                    Wood wood3 = new Wood(420, 400 + i * 40);
                    woods.add(wood3);
                    Wood wood4 = new Wood(720, 80 + i * 40);
                    woods.add(wood4);
                    Wood wood5 = new Wood(720, 400 + i * 40);
                    woods.add(wood5);
                }
                break;
            case "2":
                //初始化敌人的坦克
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    //创建敌人的坦克
                    EnemyTank tank = new EnemyTank(node.getX(), node.getY());
                    //将enemyTanks设置给tank
                    tank.setEnemyTanks(enemyTanks);
                    //将障碍物设置给tank去检测
                    tank.setMetals(metals);
                    tank.setWoods(woods);
                    hero.setMetals(metals);
                    hero.setWoods(woods);
                    //设置方向
                    tank.setDirect(node.getDirect());
                    //启动敌人坦克线程,让它动起来
                    new Thread(tank).start();
                    //给enemyTank加入一颗子弹
                    Shot shot = new Shot(tank.getX() + 20, tank.getY() + 60, tank.getDirect());
                    //加入enemyTank的Vector成员
                    tank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    //加入
                    enemyTanks.add(tank);
                }
                for (int i = 0; i < 2; i++) {
                    Metal metal1 = new Metal(260 + 40 * i, 340);
                    metals.add(metal1);
                    Metal metal2 = new Metal(560 + 40 * i, 340);
                    metals.add(metal2);
                }
                for (int i = 0; i < itemnodes.size(); i++) {
                    Itemnode itemnode = itemnodes.get(i);
                    Wood wood = new Wood(itemnode.getX(), itemnode.getY());
                    woods.add(wood);
                }
                break;
            default:
                System.out.println("你的输入有误...");
        }


        //初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/20190215210241592.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/20190215210304713.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/20190215210323305.png"));
    }

    //编写方法,显示我方击毁坦克的信息
    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);
        if (!gameOver) {
            g.fillRect(0, 0, 1000, 750);//填充坦克活动区域,默认黑色
            drawWood(woods, g);//画出木墙
            drawMetal(metals, g);//画出铁墙
            showInFo(g);
            if (hero.isLive && hero != null) {
                //封装坦克的方法
                drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
            }
            //画出hero射击的子弹
//        if(hero.shot != null && hero.shot.isLive){
//            g.draw3DRect(hero.shot.x, hero.shot.y, 3, 3, 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, 3, 3, false);
                } else { //如果该shot对象已经无效,就从shots集合中拿掉
                    hero.shots.remove(shot);
                }
            }

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //如果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 tank = enemyTanks.get(i);
                //判断当前坦克是否还存活
                if (tank.isLive) { //当敌人坦克是存活的,才画出该坦克
                    drawTank(tank.getX(), tank.getY(), g, tank.getDirect(), 0);
                    //画出enemyTank的所有子弹
                    for (int j = 0; j < tank.shots.size(); j++) {
                        //取出子弹
                        Shot shot = tank.shots.get(j);
                        //绘制
                        if (shot.isLive) {
                            g.draw3DRect(shot.x, shot.y, 3, 3, false);
                        } else {
                            //从Vector移除
                            tank.shots.remove(shot);
                        }
                    }
                }
            }
        } else {
            // 绘制游戏结束界面
            drawGameOver(g);
        }
    }

    //画出铁墙障碍物
    public void drawMetal(Vector<Metal> metals, Graphics g) {
        g.setColor(Color.white);
        for (int i = 0; i < metals.size(); i++) {
            Metal metal = metals.get(i);
            g.fill3DRect(metal.getX(), metal.getY(), 40, 40, false);
        }
    }

    //画出木墙障碍物
    public void drawWood(Vector<Wood> woods, Graphics g) {
        g.setColor(Color.yellow);
        for (int i = 0; i < woods.size(); i++) {
            Wood wood = woods.get(i);
            if (wood.getIsLive()) {
                g.fill3DRect(wood.getX(), wood.getY(), 40, 40, false);
            }
        }
    }

    //画出坦克-封装到方法里

    /**
     * @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("暂时没有处理");
        }
    }

    //如果我们的坦克能够发射多颗子弹
    //在判断我方坦克是否击中敌人的坦克时i,就需要把我们的子弹集合中所有的子弹取出和所有的敌人坦克进行判断
    public void hitEnemyTank() {

        //遍历我们的子弹
        for (int j = 0; j < hero.shots.size(); j++) {
            Shot shot = hero.shots.get(j);
            //判断是否击中了敌人的坦克
            if (shot != null && shot.isLive) {
                //遍历敌人所有的坦克
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank tank = enemyTanks.get(i);
                    hitTank(shot, tank);
                }
            }
        }
        // 更新游戏状态
        gameOver = isGameOver();
    }

    //编写方法,判断敌人坦克是否击中我方坦克
    public void hitHero() {
        //遍历所有敌人的坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            //取出敌人坦克
            EnemyTank tank = enemyTanks.get(i);
            //遍历enemyTank 对象的所有子弹
            for (int j = 0; j < tank.shots.size(); j++) {
                Shot shot = tank.shots.get(j);
                //判断shot是否击中我方坦克
                if (hero.isLive && shot.isLive) {
                    hitTank(shot, hero);
                }
            }
        }
        // 更新游戏状态
        gameOver = isGameOver();
    }

    //编写方法判断我方坦克是否击中敌方坦克
    public void hitTank(Shot s, Tank tank) {
        //判断s击中坦克
        switch (tank.getDirect()) {
            case 0: //坦克向上
            case 2: //坦克向下
                if (s.x > tank.getX() && s.x < tank.getX() + 40
                        && s.y > tank.getY() && s.y < tank.getY() + 60) {
                    s.isLive = false;
                    tank.isLive = false;
                    //当我方的子弹击中敌人的坦克后,将EnemyTank从集合中拿掉
                    enemyTanks.remove(tank);
                    //当我方击毁一个敌人坦克时,就对数据allEnemyTankNum++
                    //因为enemyTank可以是Hero也可以是EnemyTank
                    if (tank instanceof EnemyTank) {
                        Recorder.addAllEnemyTankNum();
                        destroyedEnemyTanks++;
                    }
                    //创建Bomb对象,放入到bombs集合中
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1: //坦克向右
            case 3: //坦克向左
                if (s.x > tank.getX() && s.x < tank.getX() + 60
                        && s.y > tank.getY() && s.y < tank.getY() + 40) {
                    s.isLive = false;
                    tank.isLive = false;
                    enemyTanks.remove(tank);
                    //因为enemyTank可以是Hero也可以是EnemyTank
                    if (tank instanceof EnemyTank) {
                        Recorder.addAllEnemyTankNum();
                        destroyedEnemyTanks++;
                    }
                    //创建Bomb对象,放入到bombs集合中
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
        }
    }

    //判断子弹是否击中木墙,击中后,子弹和木墙都消失
    public void hitWood(Shot shot, Tank tank) {
        for (int i = 0; i < woods.size(); i++) {
            Wood wood = woods.get(i);
            if (shot.x >= wood.getX()
                    && shot.x <= wood.getX() + 40
                    && shot.y >= wood.getY()
                    && shot.y <= wood.getY() + 40) {
                shot.isLive = false;
                wood.setIsLive(false);//被击中的墙状态改成false
                woods.remove(wood);//被击中的墙移除掉

            }

        }
    }

    //子弹击中铁墙之后将子弹销毁,铁墙存活
    public void hitMetal(Shot shot) {
        for (int i = 0; i < metals.size(); i++) {
            Metal metal = metals.get(i);
            if (shot.x >= metal.getX()
                    && shot.x <= metal.getX() + 40
                    && shot.y >= metal.getY()
                    && shot.y <= metal.getY() + 40) {
                shot.isLive = false;
            }

        }
    }

    //判断玩家是否击中障碍物
    public void heroHitBarrier() {
        for (int i = 0; i < hero.shots.size(); i++) {
            Shot shot = hero.shots.get(i);
            hitWood(shot, hero);
            hitMetal(shot);
        }
    }

    //判断敌方坦克是否击中障碍物
    public void enemyHitBarrier() {
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                Shot shot = enemyTank.shots.get(j);
                hitWood(shot, enemyTank);
                hitMetal(shot);
            }

        }
    }

    // 判断是否游戏结束
    public boolean isGameOver() {
        return destroyedEnemyTanks >= 10 || !hero.isLive;
    }

    // 绘制游戏结束界面
    public void drawGameOver(Graphics g) {
        // 根据实际需求绘制游戏结束界面
        // 这里简单示例为绘制文字
        g.setColor(Color.RED);
        g.setFont(new Font("Arial", Font.BOLD, 40));
        if (!hero.isLive) {
            g.drawString("You Died! Game Over", 300, 300);
        } else {
            g.drawString("Game Over, You Win !!!", 400, 300);
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //处理wasd键按下的情况
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W) { //按下W键向上
            hero.setDirect(0);
            //修改坦克的坐标
            if (hero.getY() > 0 && (!hero.isTouchWood())
                    && (!hero.isTouchMetal())) {
                hero.moveUp();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_D) { //按下D键向右
            hero.setDirect(1);
            if (hero.getX() + 60 < 1000 && (!hero.isTouchWood())
                    && (!hero.isTouchMetal())) {
                hero.moveRight();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_S) { //按下A键向左
            hero.setDirect(2);
            if (hero.getY() + 60 < 750 && (!hero.isTouchWood())
                    && (!hero.isTouchMetal())) {
                hero.moveDown();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_A) { 按下S键向下
            hero.setDirect(3);
            if (hero.getX() > 0 && (!hero.isTouchWood())
                    && (!hero.isTouchMetal())) {
                hero.moveLeft();
            }
        }

        //如果用户按下的是J,就发射子弹
        if (e.getKeyCode() == KeyEvent.VK_J) {
            System.out.println("用户按下J,开始射击");
            hero.shotEnemyTank();
        }
        //面板重绘
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() { //每隔20ms重绘区域,刷新绘图区域,子弹就移动起来了

        int enemyTankSpawnInterval = 100; // 控制敌方坦克生成间隔
        int enemyTankSpawnCounter = 0; // 用于计数

        while (!gameOver) {
            try {
                Thread.sleep(20); //休眠时间越短能使得子弹的刷新率更高
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            hitEnemyTank();
            //判断敌人坦克是否击中我们
            hitHero();

            enemyHitBarrier();//判断敌方坦克是否射击到障碍物
            heroHitBarrier();//判断玩家坦克是否射击到障碍物

            // 控制敌方坦克生成
            enemyTankSpawnCounter++;
            if (enemyTankSpawnCounter >= enemyTankSpawnInterval) {
                // 重置计数器
                enemyTankSpawnCounter = 0;
                // 生成敌方坦克
                generateEnemyTank();
            }
            this.repaint();
        }
    }

    // 生成敌方坦克方法
    public void generateEnemyTank() {
        // 判断敌方坦克数量是否达到上限
        if (enemyTanks.size() >= enemyTankSize) {
            return; // 达到上限则不再生成
        }

        // 创建敌方坦克
        EnemyTank tank = new EnemyTank((100 * (enemyTanks.size() + 1)), 0);  //设置新生成坦克的位置
        tank.setEnemyTanks(enemyTanks); //将当前敌方坦克集合 enemyTanks 设置给新创建的敌方坦克 tank,
        tank.setMetals(metals);
        tank.setWoods(woods);
        // 以便坦克能够感知其他敌方坦克的存在,避免碰撞。
        tank.setDirect(2);  //设置初始向下的方向
        new Thread(tank).start();  //每辆新生成的敌人坦克都是一个新的线程

        Shot shot = new Shot(tank.getX() + 20, tank.getY() + 60, tank.getDirect()); //创建了一个新的子弹对象 shot
        tank.shots.add(shot);  //装入到shots集合当中
        new Thread(shot).start(); //启动子弹线程
        //将新创建的坦克放入到集合中
        enemyTanks.add(tank);
    }
}

 Tank类:

public class Tank {
    private int x;
    private int y;
    private int direct;//坦克方向 0,1,2,3
    boolean isLive = true;
    // 是否可以发射子弹
    boolean attackCoolDown = true;
    // 发射的最小时间间隔
    static final long attackCoolDownTime = 500; // 1000毫秒
    private int speed = 2;

    //上右下左移动方法
    public void moveUp() {
        y -= speed;
    }

    public void moveRight() {
        x += speed;
    }

    public void moveDown() {
        y += speed;
    }

    public void moveLeft() {
        x -= speed;
    }

    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;
    }

    public int getDirect() {
        return direct;
    }

    public void setDirect(int direct) {
        this.direct = direct;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

}

Hero类:

import java.util.Vector;

public class Hero extends Tank {
    //定义一个shot对象,表示一个射击(线程)
    Shot shot = null;
    //可以发射多颗子弹
    Vector<Shot> shots = new Vector<>();

    Vector<Metal> metals = new Vector<>();
    Vector<Wood> woods = new Vector<>();

    public Hero(int x, int y) {
        super(x, y);
    }

    public void shotEnemyTank() {
        //控制在面板上最多只有5颗子弹
        if (!attackCoolDown) {
            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();
        //启动AttackCD线程
        new AttackCD().start();
    }

    public void setMetals(Vector<Metal> metals) {
        this.metals = metals;
    }
    public void setWoods(Vector<Wood> woods) {
        this.woods = woods;
    }

    //判断坦克是否碰到了铁墙
    public boolean isTouchMetal() {
        switch (this.getDirect()) {
            case 0://该坦克方向向上
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左上角是否碰到障碍物
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右上角是否碰到障碍物
                    if (this.getX() + 40 >= metal.getX()
                            && this.getX() + 40 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;

                }
                break;
            case 1://坦克方向向右
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克右上角是否碰到障碍物[this.getX()+60,this.getY()]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+60,this.getY()+40]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() + 40 >= metal.getY()
                            && this.getY() + 40 <= metal.getY() + 40)
                        return true;
                }
                break;
            case 2://坦克向下
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左下角是否碰到障碍物[this.getX(),this.getY()+60]
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() + 60 >= metal.getY()
                            && this.getY() + 60 <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+40,this.getY()+60]
                    if (this.getX() + 40 >= metal.getX()
                            && this.getX() + 40 <= metal.getX() + 40
                            && this.getY() + 60 >= metal.getY()
                            && this.getY() + 60 <= metal.getY() + 40)
                        return true;
                }
                break;
            case 3://坦克向左
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左上角是否碰到障碍物[this.getX(),this.getY()]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX(),this.getY()+40]
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() + 40 >= metal.getY()
                            && this.getY() + 40 <= metal.getY() + 40)
                        return true;
                }
                break;
        }
        return false;
    }

    //判断坦克是否碰到了铁墙
    public boolean isTouchWood() {
        switch (this.getDirect()) {
            case 0://该坦克方向向上
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左上角是否碰到障碍物
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右上角是否碰到障碍物
                    if (this.getX() + 40 >= wood.getX()
                            && this.getX() + 40 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                }
                break;
            case 1://坦克方向向右
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克右上角是否碰到障碍物[this.getX()+60,this.getY()]
                    if (this.getX() + 60 + 5 >= wood.getX()
                            && this.getX() + 60 + 5 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+60,this.getY()+40]
                    if (this.getX() + 60 + 5 >= wood.getX()
                            && this.getX() + 60 + 5 <= wood.getX() + 40
                            && this.getY() + 40 >= wood.getY()
                            && this.getY() + 40 <= wood.getY() + 40)
                        return true;
                }
                break;
            case 2://坦克向下
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左下角是否碰到障碍物[this.getX(),this.getY()+60]
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() + 60 >= wood.getY()
                            && this.getY() + 60 <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+40,this.getY()+60]
                    if (this.getX() + 40 >= wood.getX()
                            && this.getX() + 40 <= wood.getX() + 40
                            && this.getY() + 60 >= wood.getY()
                            && this.getY() + 60 <= wood.getY() + 40)
                        return true;
                }
                break;
            case 3://坦克向左
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左上角是否碰到障碍物[this.getX(),this.getY()]
                    if (this.getX() + 60 >= wood.getX()
                            && this.getX() + 60 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX(),this.getY()+40]
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() + 40 >= wood.getY()
                            && this.getY() + 40 <= wood.getY() + 40)
                        return true;
                }
                break;
        }
        return false;
    }

    //将坦克发射子弹的时间间隔设置为一个线程,主要是为了控制子弹的发射频率
    class AttackCD extends Thread {
        public void run() {
            attackCoolDown = false;
            try {
                Thread.sleep(attackCoolDownTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
            attackCoolDown = true;
        }
    }
}

EnemyTank类:

import java.util.Vector;

//敌人的坦克
public class EnemyTank extends Tank implements Runnable {
    //在敌人坦克类使用Vector保存多个shot
    Vector<Shot> shots = new Vector<>();
    //增加成员,EnemyTank可以得到敌人坦克的Vector
    Vector<EnemyTank> enemyTanks = new Vector<>();

    Vector<Metal> metals = new Vector<>();
    Vector<Wood> woods = 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;
    }
    public void setMetals(Vector<Metal> metals) {
        this.metals = metals;
    }
    public void setWoods(Vector<Wood> woods) {
        this.woods = woods;
    }

    //编写方法,判断当前的这个敌人坦克是否和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) {
                        //如果敌人的坦克是 上/下 x的范围是[enemyTank.getX(), enemyTank.getX() + 40]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 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;
                            }

                            //当前坦克右上角的坐标[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;
                            }
                        }
                        //如果敌人的坦克是 右/左 x的范围是[enemyTank.getX(), enemyTank.getX() + 60]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //当前坦克左上角坐标[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;
                            }

                            //当前坦克右上角的坐标[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) {
                        //如果敌人的坦克是 上/下 x的范围是[enemyTank.getX(), enemyTank.getX() + 40]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 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;
                            }

                            //当前坦克右下角的坐标[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;
                            }
                        }
                        //如果敌人的坦克是 右/左 x的范围是[enemyTank.getX(), enemyTank.getX() + 60]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //当前坦克左上角坐标[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;
                            }

                            //当前坦克右下角的坐标[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;
                            }
                        }
                    }
                }
                break;
            case 2:
                //让当前敌人坦克和其他所有敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从Vector中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人的坦克是 上/下 x的范围是[enemyTank.getX(), enemyTank.getX() + 40]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 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;
                            }

                            //当前坦克右下角的坐标[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;
                            }
                        }
                        //如果敌人的坦克是 右/左 x的范围是[enemyTank.getX(), enemyTank.getX() + 60]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //当前坦克左下角坐标[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;
                            }

                            //当前坦克右下角的坐标[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;
                            }
                        }
                    }
                }
                break;
            case 3:
                //让当前敌人坦克和其他所有敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从Vector中取出一个敌人坦克
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this) {
                        //如果敌人的坦克是 上/下 x的范围是[enemyTank.getX(), enemyTank.getX() + 40]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 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;
                            }

                            //当前坦克左下角的坐标[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;
                            }
                        }
                        //如果敌人的坦克是 右/左 x的范围是[enemyTank.getX(), enemyTank.getX() + 60]
                        //                   y的范围是[enemyTank.getY(), enemyTank.getY() + 40]
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {
                            //当前坦克左上角坐标[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;
                            }

                            //当前坦克左下角的坐标[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;
                            }
                        }
                    }
                }
                break;
        }
        return false;
    }

    @Override
    public void run() {
        while (true) {
            //这里我们判断如果shots size = 0,创建一颗子弹,放入到shots集合,并启动
            if (isLive && shots.size() < 3) {

                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: //向上
                    //让坦克朝一个方向移动50步
                    for (int i = 0; i < 50; i++) {
                        if (getY() > 0 && !isTouchEnemyTank() && (!isTouchWood())
                                && (!isTouchMetal())) {
                            moveUp();
                        }
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    break;
                case 1: //向右
                    for (int i = 0; i < 50; i++) {
                        if (getX() + 60 < 1000 && !isTouchEnemyTank() && (!isTouchWood())
                                && (!isTouchMetal())) {
                            moveRight();
                        }
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    break;
                case 2: //向下
                    for (int i = 0; i < 50; i++) {
                        if (getY() + 60 < 750 && !isTouchEnemyTank() && (!isTouchWood())
                                && (!isTouchMetal())) {
                            moveDown();
                        }
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    break;
                case 3: //向左
                    for (int i = 0; i < 50; i++) {
                        if (getX() > 0 && !isTouchEnemyTank() && (!isTouchWood())
                                && (!isTouchMetal())) {
                            moveLeft();
                        }
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    break;
            }

            //然后随机地改变坦克方向
            setDirect((int) (Math.random() * 4));
            //退出线程
            if (!isLive) {
                break;
            }
        }
    }

    //判断坦克是否碰到了铁墙
    public boolean isTouchMetal() {
        switch (this.getDirect()) {
            case 0://该坦克方向向上
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左上角是否碰到障碍物
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右上角是否碰到障碍物
                    if (this.getX() + 40 >= metal.getX()
                            && this.getX() + 40 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;

                }
                break;
            case 1://坦克方向向右
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克右上角是否碰到障碍物[this.getX()+60,this.getY()]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+60,this.getY()+40]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() + 40 >= metal.getY()
                            && this.getY() + 40 <= metal.getY() + 40)
                        return true;
                }
                break;
            case 2://坦克向下
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左下角是否碰到障碍物[this.getX(),this.getY()+60]
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() + 60 >= metal.getY()
                            && this.getY() + 60 <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+40,this.getY()+60]
                    if (this.getX() + 40 >= metal.getX()
                            && this.getX() + 40 <= metal.getX() + 40
                            && this.getY() + 60 >= metal.getY()
                            && this.getY() + 60 <= metal.getY() + 40)
                        return true;
                }
                break;
            case 3://坦克向左
                for (int i = 0; i < metals.size(); i++) {
                    //判断每个铁墙,看是否碰到
                    Metal metal = metals.get(i);
                    //坦克左上角是否碰到障碍物[this.getX(),this.getY()]
                    if (this.getX() + 60 >= metal.getX()
                            && this.getX() + 60 <= metal.getX() + 40
                            && this.getY() >= metal.getY()
                            && this.getY() <= metal.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX(),this.getY()+40]
                    if (this.getX() >= metal.getX()
                            && this.getX() <= metal.getX() + 40
                            && this.getY() + 40 >= metal.getY()
                            && this.getY() + 40 <= metal.getY() + 40)
                        return true;
                }
                break;
        }
        return false;
    }

    //判断坦克是否碰到了铁墙
    public boolean isTouchWood() {
        switch (this.getDirect()) {
            case 0://该坦克方向向上
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左上角是否碰到障碍物
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右上角是否碰到障碍物
                    if (this.getX() + 40 >= wood.getX()
                            && this.getX() + 40 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                }
                break;
            case 1://坦克方向向右
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克右上角是否碰到障碍物[this.getX()+60,this.getY()]
                    if (this.getX() + 60 + 5 >= wood.getX()
                            && this.getX() + 60 + 5 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+60,this.getY()+40]
                    if (this.getX() + 60 + 5 >= wood.getX()
                            && this.getX() + 60 + 5<= wood.getX() + 40
                            && this.getY() + 40 >= wood.getY()
                            && this.getY() + 40 <= wood.getY() + 40)
                        return true;
                }
                break;
            case 2://坦克向下
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左下角是否碰到障碍物[this.getX(),this.getY()+60]
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() + 60 >= wood.getY()
                            && this.getY() + 60 <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX()+40,this.getY()+60]
                    if (this.getX() + 40 >= wood.getX()
                            && this.getX() + 40 <= wood.getX() + 40
                            && this.getY() + 60 >= wood.getY()
                            && this.getY() + 60 <= wood.getY() + 40)
                        return true;
                }
                break;
            case 3://坦克向左
                for (int i = 0; i < woods.size(); i++) {
                    Wood wood = woods.get(i);
                    //坦克左上角是否碰到障碍物[this.getX(),this.getY()]
                    if (this.getX() + 60 >= wood.getX()
                            && this.getX() + 60 <= wood.getX() + 40
                            && this.getY() >= wood.getY()
                            && this.getY() <= wood.getY() + 40)
                        return true;
                    //坦克右下角是否碰到障碍物[this.getX(),this.getY()+40]
                    if (this.getX() >= wood.getX()
                            && this.getX() <= wood.getX() + 40
                            && this.getY() + 40 >= wood.getY()
                            && this.getY() + 40 <= wood.getY() + 40)
                        return true;
                }
                break;
        }
        return false;
    }
}

 Bomb类:

//炸弹
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;
        }
    }
}

Shot类:

//子弹发射出去后 移动与原坦克没关系了,看作是独立个体,因此要单独封装成一个类,享有自己的属性

/**
 * 如果不将Shot类设置为一个线程,那么每次发射子弹时,都需要等待子弹移动到目标位置或者飞出屏幕后,才能进行下一次操作。
 * 这意味着在子弹移动的过程中,游戏的其他部分(如坦克的移动或者其他子弹的发射)将会被阻塞,直到当前的子弹完成其生命周期。
 * 将Shot类设置为一个线程,可以使得每颗子弹都能够独立地、并行地移动,大大提高了游戏的流畅性和响应速度
 */
public class Shot implements Runnable {
    int x; //子弹x坐标
    int y; //子弹y坐标
    int direct; //子弹方向
    int speed = 4; //子弹速度
    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) {

            //让子弹休眠20ms
            try {
                Thread.sleep(20); //休眠时间越短能使得子弹的刷新率更高
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //根据方向来改变x,y坐标
            switch (direct) {
                case 0: //上
                    y -= speed;
                    break;
                case 1: //右
                    x += speed;
                    break;
                case 2: //下
                    y += speed;
                    break;
                case 3: //左
                    x -= speed;
                    break;
            }
            //测试
            //System.out.println("子弹 x= " + x + " y= " + y);
            //当子弹移动到面板边界时,就应该把子弹销毁
            //当子弹碰到敌人坦克时,也应该结束线程
            if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750 && isLive)) {
                isLive = false;
                break;
            }
        }
    }
}

TankGame类:

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;

public class TankGame03 extends JFrame {

    MyPanel mp = null;
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        TankGame03 tankGame01 = new TankGame03();
    }
    public TankGame03(){
        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,785);
        this.addKeyListener(mp); //让JFrame监听键盘事件
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        //在JFrame中增加相应关闭窗口的处理
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("监听到关闭窗口了");
                Recorder.keepRecord();
                System.exit(0);
            }
        });
    }
}

Barrier类

//用以设置障碍物
public class Barrier {
    private int x; //障碍物的x坐标
    private int y; //障碍物的y坐标
    private int size = 40; //障碍物大小

    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 Barrier(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }

    public int getSize() {
        return size;
    }
}

Metal类

import java.util.Vector;

public class Metal extends Barrier {
    boolean isLive = true;
    Vector<Metal> metals = new Vector<>();

    public Vector<Metal> getMetals() {
        return metals;
    }

    public void setMetals(Vector<Metal> metals) {
        this.metals = metals;
    }

    public void setIsLive(boolean state) {
        this.isLive = state;
    }

    public Metal(int x, int y) {
        super(x, y);
    }

    public boolean getIsLive() {
        return isLive;
    }
}

Wood类

import java.util.Vector;
//木墙障碍物,被子弹射击到会消失
public class Wood extends Barrier {
    boolean isLive = true;
    Vector<Wood> woods = new Vector<>();

    public Vector<Wood> getWoods() {
        return woods;
    }

    public void setWoods(Vector<Wood> woods) {
        this.woods = woods;
    }

    public void setIsLive(boolean state) {
        this.isLive = state;
    }

    public Wood(int x, int y) {
        super(x, y);
    }

    public boolean getIsLive() {
        return isLive;
    }
}

Recorder类

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Vector;

/*该类记录我方击毁敌方坦克数
 * 2.当游戏结束,将数据写入到文件(IO)
 * 3.当退出游戏时,记录敌人坦克坐标和方向
 * 4.将每个敌人信息,恢复成Node对象->Vector
 */
//用于记录相关信息,和文件交互
public class Recorder {
    //定义变量,记录我方击毁敌人坦克数
    private static int allEnemyTankNum = 0;
    //定义IO对象,准备写数据到文件中
    private static FileWriter fw = null;
    private static BufferedReader br = null;
    private static BufferedWriter bw = null;
    //把记录文件保存到src下
    private static String recordFile = "D:\\IDEA java projects\\TankFight03\\TankGame\\src\\myRecord.txt";

    public static String getRecordFile() {
        return recordFile;
    }

    //定义Vector,指向MyPanel对象的敌人坦克Vector
    private static Vector<EnemyTank> enemyTanks = null;

    public static void setWoods(Vector<Wood> woods) {
        Recorder.woods = woods;
    }

    private  static Vector<Wood> woods = null;
    //定义一个Node的Vector,用于保存敌人的信息node
    private static Vector<Node> nodes = new Vector<>();

    private static Vector<Itemnode> itemnodes = new Vector<>();
    public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    //增加一个方法,用于读取recordFile,恢复相关信息
    //该方法在继续上局时调用即可
    public static Vector<Node> getNodesAndEnemyTankRec() {
        try {
            br = new BufferedReader(new FileReader(recordFile));

            allEnemyTankNum = Integer.parseInt(br.readLine());
            //循环读取文件,生成nodes集合
            String line = "";
            while ((line = br.readLine()) != null) {
                String[] xyd = line.split(" ");
                if (xyd.length == 3) {
                    Node node = new Node(Integer.parseInt(xyd[0]), Integer.parseInt(xyd[1]),
                            Integer.parseInt(xyd[2]));
                    nodes.add(node);//放入到Vector
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
        return nodes;
    }
    public static Vector<Itemnode> getItemNodes() {
        try {
            br = new BufferedReader(new FileReader(recordFile));

            String line = "";
            while ((line = br.readLine()) != null) {
                String[] xy = line.split(" ");
                if (xy.length == 2) {
                    Itemnode itemnode = new Itemnode(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
                    itemnodes.add(itemnode);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return itemnodes;
    }

    //增加一个方法,当游戏退出时,我们将allEnemyTankNum保存到recordFile
    //对此方法进行升级,保存敌人坦克的坐标和方向
    public static void keepRecord() {
        try {

            bw = new BufferedWriter((new FileWriter(recordFile)));
            bw.write(String.valueOf(allEnemyTankNum) + "\r\n");

            //遍历敌人坦克的Vector,然后根据情况保存即可
            //定义一个属性,然后通过setXxx得到敌人坦克的Vector
            for (int i = 0; i < enemyTanks.size(); i++) {
                //取出敌人坦克
                EnemyTank enemyTank = enemyTanks.get(i);
                if (enemyTank.isLive) {
                    //保存该坦克信息
                    String record = enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect();
                    //写入到文件
                    bw.write(record + "\r\n");

                }
            }
            for (int j = 0; j < woods.size(); j++) {
                Wood wood = woods.get(j);
                if (wood.isLive) {
                    String r = wood.getX() + " " + wood.getY() + " ";
                    bw.write(r + "\r\n");
                }
            }
            bw.flush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    public static int getAllEnemyTankNum() {
        return allEnemyTankNum;
    }

    public static void setAllEnemyTankNum(int allEnemyTankNum) {
        Recorder.allEnemyTankNum = allEnemyTankNum;
    }

    //当我方坦克击毁一个敌人坦克,就应当allEnemyTankNum++
    public static void addAllEnemyTankNum() {
        Recorder.allEnemyTankNum++;
    }

}

Node类

/**
 * 一个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;
    }
}

Itemnode类

public class Itemnode {
    private int x;
    private int y;

    public Itemnode(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;
    }
}

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值