Java笔记(二十五):坦克大战【三】(IO流---存盘退出 / 继续上局、碰撞检测---防止坦克重叠)

IO流 - 应用到坦克大战

一、坦克大战6.0版

在这里插入图片描述

1、防止坦克重叠运动

在这里插入图片描述
当前坦克向上时:当左上角右上角进入敌方坦克区域,则视为重叠

当前坦克向左时:当左上角左下角进入敌方坦克区域,则视为重叠

当前坦克向下时:当左下角右下角进入敌方坦克区域,则视为重叠

当前坦克向右时:当右上角右下角进入敌方坦克区域,则视为重叠

变化:
EnemyTank:

  1. 增加成员Vector enemys ,用于接收myPanel的Vector
  2. 编写方法isTouchEnemyTank,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
  3. 修改run中敌人移动的代码,在移动前判断是否重叠。重叠则不移动

MyPanel:

  1. 每创建一个enemy,就将enemyTanks对象传入EnemyTank类中(由于MyPanel是一个线程,run中有循环,所以会不断调用构造器)

EnemyTank类

public class EnemyTank extends Tank implements Runnable{
	//1. 增加成员,EnemyTank 可以得到敌人坦克的Vector
	private Vector<EnemyTank> enemyTanks = new Vector<>();

    //2. 编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
    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:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
            case 1: //右
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克右上坐标
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克右上边坐标
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() +60 <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                    }
                }
            case 2: //下
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左下坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左边坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克右边的坐标
                            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;
                            }
                        }
                    }
                }

            case 3: //左
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
        }
        return false;
    }


	//在移动时调用isTouchEnemyTank(),判断是否重叠
	@Override
    public void run() {
        while(true) {
          	//...
            switch (getDirect()) {
                case 0: //向上
                    for (int i = 0; i < 30; i++) { //移动30步再变化方向
                    	//4. 移动前判断是否重叠
                        if((getY() > 0) && !isTouchEnemyTank()){  //在画布范围内移动
                            moveUp();
                        }
                        //休眠...
                    }
                    break;
                case 1: //向左
                    for (int i = 0; i < 30; i++) { //移动30步再变化方向
                        if((getX() > 0) && !isTouchEnemyTank()) {
                            moveLeft();
                        }
                        //休眠...
                    }
                    break;
                case 2: //向下
                    for (int i = 0; i < 30; i++) { //移动30步再变化方向
                        if ((getY() + 60 < 750) && !isTouchEnemyTank()) {
                            moveDown();
                        }
                        //休眠...
                    }
                    break;
                case 3: //向右
                    for (int i = 0; i < 30; i++) { //移动30步再变化方向
                        if((getX() + 60 < 1000) && !isTouchEnemyTank()) {
                            moveRight();
                        }
                        //休眠...
                    }
                    break;
            }
            //...
        }
    }
}

MyPanel类

	public MyPanel(){
	//...
        //初始化敌人坦克
         for (int i = 0; i < 5; i++) {
            //创建一个敌人坦克
            EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
            //把敌方坦克集合传给Enemy类
            enemyTank.setEnemyTanks(enemyTanks);
            //...
        }
		//...
    }

2、记录上局游戏信息,存盘退出【IO流】

创建一个Recorder类,记录相关信息,用于和文件交互

Recorder类

  1. 定义IO、文件路径
  2. 实现保存信息方法(keepRecord)

MyPanel类

  1. 给Recorder传入enemyTanks集合

TankGame类

  1. 在关闭窗口时调用Recorder的KeepRecord方法保存信息

Recorder类

/**
 * 该类记录文件信息和文件交互
 */
public class Recorder {

    //定义变量记录我方击毁敌人坦克数
    private static int hitTankNums = 0;
    //定义IO对象
    private static BufferedWriter bw = null;
    private static BufferedReader br = null;
    private static String recordFile = "d:\\myRecord.txt";

    private static Vector<EnemyTank> enemyTanks = null;

    //添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
    public static void keepRecord(){
        try {
            bw = new BufferedWriter(new FileWriter(recordFile));

            //记录每个存活的敌方坦克
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);
                if (enemyTank.isLive()){
                    bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect() + "\r\n");
                }
            }

            bw.write(hitTankNums + "\r\n");

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static int getHitTankNums() {
        return hitTankNums;
    }

    public static Vector<EnemyTank> getAnemyTanks() {
        return enemyTanks;
    }

    public static void setAnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    public static void setHitTankNums(int hitTankNums) {
        Recorder.hitTankNums = hitTankNums;
    }

    public static void addHitTankNums(){
        Recorder.hitTankNums++;
    }
}

MyPanel类

	public MyPanel(){
        //1. 传入 anemyTanks 并记录
        Recorder.setAnemyTanks(enemyTanks);
        //...
	}

TankGame类

public class TankGame extends JFrame {
	//...

    public TankGame(){
        mp = new MyPanel();
        //...
        
        //1. 在JFrame 中增加相应关闭窗口的处理
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                Recorder.keepRecord();
                System.exit(0);
            }
        });
        
    }
}

3、玩游戏时,可以选择是开新游戏还是继续上局游戏

在这里插入图片描述
Recorder类

  1. 定义一个node 的Vector,用于恢复信息
  2. 实现读取信息方法:getNodesAndEnemyNums

MyPanel类

  1. 定义nodes,接收从Recorder读取到的上局敌人信息
  2. 重新定义构造器,接收参数key,判断是重新开始还是继续上局游戏
    • (1)重新开始:用enemyTanks,重新遍历创建敌人
    • (2)继续上局:用nodes,获取敌人信息并调用EnemyTank构造器创建敌人

TankGame类

  1. 给MyPanel传入参数key

Recorder类

	//1.定义一个node 的Vector,用于恢复信息
    private static Vector<Node> nodes = new Vector<>();

 	//2. 添加一个方法,用于读取recordFile,恢复相关的信息
    public static Vector<Node> getNodesAndEnemyNums(){

        try {
            br = new BufferedReader(new FileReader(recordFile));
            //循环读取文件,生成 nodes 集合
            String line = "";//255 40 0
            while ((line = br.readLine()) != null){
                String[] s = line.split(" ");
                if (s.length == 3){
                    Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
                    nodes.add(node);
                }else if (s.length == 1){
                    line = s[0];
                    int hitTankNums = Integer.parseInt(line);
                    setHitTankNums(hitTankNums);

                }

            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return nodes;
    }

MyPanel类

//1. 定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
    Vector<Node> nodes = null;
	//2. 接收一个key,用于判断是重新开始,还是继续游戏
	public MyPanel(String key){
        
        //判断是重新开始,还是继续游戏
        switch (key){
            case "1": //重新开始,重置击毁敌人数,使用enemyTanks集合创建敌人坦克
                //重置击毁敌人数
                Recorder.setHitTankNums(0);

                //初始化敌人坦克
                for (int i = 0; i < 5; i++) {
                    //创建一个敌人坦克
                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
                    //把敌方坦克集合传给Enemy类
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(2);
                    //启动敌方坦克
                    Thread thread = new Thread(enemyTank);
                    thread.start();
                    //给anemyTank加入一个子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.getShots().add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    enemyTanks.add(enemyTank);
                }
                break;
            case "2": //继续游戏,使用nodes集合创建敌人坦克
                nodes = Recorder.getNodesAndEnemyNums();
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    //创建一个敌人坦克
                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
                    //将 anemyTanks设置个AnemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(node.getDirect());
                    //启动敌方坦克
                    Thread thread = new Thread(enemyTank);
                    thread.start();
                    //给anemyTank加入一个子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.getShots().add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    enemyTanks.add(enemyTank);
                }
                break;
            default:
                System.out.println("你输入的有误:");
        }
	}

TankGame类

public class TankGame extends JFrame {
	//...
    static Scanner scanner = new Scanner(System.in);

	//...

    public TankGame(){
        System.out.println("请输入选择: 1.新游戏 2.继续上局");
        String key = scanner.next();
        mp = new MyPanel(key);
       	//...
    }
}

4、游戏开始时,播放经典的坦克大战音乐

创建工具类AePlayWave,导入音频文件(注意必须是wav格式,而且不能直接通过改后缀改变音频格式)—》 用格式工厂

AePlayWave类


/**
 * 播放音乐
 */
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();
        }

    }
}

MyPanel类

	public MyPanel(String key){
		//... 
		
		// 播放音乐,调用start方法
        new AePlayWave("src\\start.wav").start();
    }

5、修正下文文件存储的位置

将存盘数据保存到项目中(src下)

  1. 新建一个myRecord.txt,因为第一次开始游戏的时候,会读取这个文件,如果没有会报错
    在这里插入图片描述

  2. 修改Recorder类

public class Recorder {
    private static String recordFile = "src\\myRecord.txt";
}

6、处理文件相关异常

假如没有记录文件,就直接开启上局游戏,会因为读取不到而报错

那么在判断是开启上局还是开启新游戏之前,就应该先判断文件是否存在


Recorder类

	//新增方法
    public static String getRecordFile() {
        return recordFile;
    }

MyPanel类

	public MyPanel(String key){

        //判断文件是否存在
        if(new File(Recorder.getRecordFile()).exists()) {
            //读文件
            nodes = Recorder.getNodesAndEnemyNums();
        } else {
            System.out.println("文件不存在,只能开启新游戏");
            key = "1";
        }
        //...
        
        switch(key) {
        	case "1":
        		//...
        	case "2":
        		//这里不用再Recorder.getNodesAndEnemyNums();
        		//...
        }
        //...
     }

7、完整版

1)Tank类

package com.rxli.game;


/**
 * 坦克类
 */
public class Tank {
    private int x;//坦克的横坐标
    private int y;//坦克的纵坐标
    private int direct;//坦克的方向
    private boolean life = true;//坦克是否存活

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;

    }

    public boolean isLife() {
        return life;
    }

    public void setLife(boolean life) {
        this.life = life;
    }

    //坦克移动
    //上移
    public void moveUp(){
        if (getY() > 0){
            y-=3;
        }
    }

    //下移
    public void moveDown(){
        if (getY() + 60 < 700) {
            y+=3;
        }
    }

    //左移
    public void moveLeft(){
        if (getX() > 0) {
            x-=3;
        }
    }

    //右移
    public void moveRight(){
        if (getX() + 60 < 800){
            x+=3;
        }
    }


    public int getDirect() {
        return direct;
    }

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

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }


}

2)Hero类

package com.rxli.game;


import java.util.Vector;

/**
 * 这个是我们的坦克
 */
public class Hero extends Tank {

    //定义一个Shot对象,表示一个射击行为(线程)
    private Shot shot = null;

    //可以发射多颗子弹
    private Vector<Shot> shots = new Vector<>();

    private boolean life = true;

    public boolean isLife() {
        return life;
    }

    public void setLife(boolean life) {
        this.life = life;
    }

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

    public Shot getShot() {
        return shot;
    }

    public void setShot(Shot shot) {
        this.shot = shot;
    }

    public Vector<Shot> getShots() {
        return shots;
    }

    public void setShots(Vector<Shot> shots) {
        this.shots = shots;
    }

    public void shotEnemyTank(){

        //只能存储五颗子弹,如果子弹数目大于5就不再存贮
        if (getShots().size() == 5){
            return;
        }

        //创建Shot对象,根据当前Hero对象的位置和方向来创建shot
        //只有当当前子弹消亡才能再次发射子弹
        switch (getDirect()){
            case 0://向上
                shot = new Shot(getX() + 18, getY(), 0);
                break;
            case 1://向右
                shot = new Shot(getX() + 60, getY() + 18, 1);
                break;
            case 2://向下
                shot = new Shot(getX() + 18,getY() + 60, 2);
                break;
            case 3://向左
                shot = new Shot(getX(), getY() + 18, 3);
                break;
        }
        //把新建的shot放入到集合中
        shots.add(shot);

        //启动我们的shot线程
        new Thread(shot).start();

    }

}

3)EnemyTank类

package com.rxli.game;

import java.util.Vector;

public class EnemyTank extends Tank implements Runnable{

    private boolean isLive = true;

    //炮弹
    private Vector<Shot> shots = new Vector<>();

    //获取所有的敌人的坦克
    private Vector<EnemyTank> enemyTanks = new Vector<>();

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

    public Vector<Shot> getShots() {
        return shots;
    }

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

    public void setShots(Vector<Shot> shots) {
        this.shots = shots;
    }

    public Vector<EnemyTank> getAnemyTanks() {
        return enemyTanks;
    }

    //这里提供一个方法,可以将 Mypanel 的成员 anemyTanks 成员变量设置到本类
    public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
        this.enemyTanks = enemyTanks;
    }

    //编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
    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:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() + 40 >= enemyTank.getX()
                                    && this.getX() + 40 <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
            case 1:
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克右上坐标
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() + 60 <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克右上边坐标
                            if (this.getX() + 60 >= enemyTank.getX()
                                    && this.getX() +60 <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                    }
                }
            case 2:
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左下坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克右下的坐标
                            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;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左边坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 60 >= enemyTank.getY()
                                    && this.getY() + 60 <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克右边的坐标
                            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;
                            }
                        }
                    }
                }

            case 3:
                //让当前坦克和所有的敌人坦克比较
                for (int i = 0; i < enemyTanks.size(); i++) {
                    //从vector取出一个坦克来
                    EnemyTank enemyTank = enemyTanks.get(i);
                    //不和自己比较
                    if (enemyTank != this){
                        //如果敌人坦克是上下
                        //敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
                        //           y:[anemyTank.getY(), nemyTank.getY() + 60]
                        if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 60) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 40
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 60) {
                                return true;
                            }
                        }
                        //如果敌人的坦克是左右
                        if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
                            //敌人坦克左上坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() >= enemyTank.getY()
                                    && this.getY() <= enemyTank.getY() + 40) {
                                return true;
                            }
                            //敌人坦克左下的坐标
                            if (this.getX() >= enemyTank.getX()
                                    && this.getX() <= enemyTank.getX() + 60
                                    && this.getY() + 40 >= enemyTank.getY()
                                    && this.getY() + 40 <= enemyTank.getY() + 40) {
                                return true;
                            }
                        }
                    }
                }
        }
        return false;
    }

    @Override
    public void run() {
        while(true){

            //如果一个子弹都没有就new一个
            //并启动
            if (isLive && getShots().size() < 2){
                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() -  60, getY() + 20, 3);
                        break;
                }
                getShots().add(s);
                new Thread(s).start();
            }

            //根据坦克的方向继续移动
            switch (getDirect()){
                case 0://向上
                    for (int i = 0; i < 30; i++) {
                        if (getY() > 0 && !isTouchEnemyTank() ) {
                            moveUp();
                        }

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 1://向右
                    for (int i = 0; i < 30; i++) {
                        if (getX() + 60 < 800 && !isTouchEnemyTank()){
                            moveRight();
                        }
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 2://向下
                    for (int i = 0; i < 30; i++) {
                        if (getY() + 60 < 700 && !isTouchEnemyTank()) {
                            moveDown();
                        }

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                case 3://向左
                    for (int i = 0; i < 30; i++) {

                        if (getX() > 0 && !isTouchEnemyTank()){
                            moveLeft();
                        }

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }

            //休眠50毫秒
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //然后随机的改变
            setDirect((int)(Math.random() * 4));

            //写多线程时,一定要考虑到线程什么时候结束
            if (!isLive){
                break;
            }

        }
    }
}

4)Shot类

package com.rxli.game;


/**
 * 子弹类
 */
public class Shot implements Runnable{
    private int x;//子弹的横坐标
    private int y;//子弹的纵坐标
    private int direct;//子弹的方向
    private int speed = 5;//子弹的速度
    private boolean isLive = true;//子弹是否成活

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

    public int getSpeed() {
        return speed;
    }

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

    public boolean isLive() {
        return isLive;
    }

    public void setLive(boolean live) {
        isLive = live;
    }

    @Override
    public void run() {
        while(true){

            //休眠100毫秒
            try {
                Thread.sleep(100);
            } 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;
            }
            //System.out.println("子弹的x=" + x + "y=" + y);
            //当子弹移动到边界的时候我们就应该销毁
            //当子弹碰到敌人的坦克时,线程也应该退出
            if (!(x >= 0 && x <= 800 && y >= 0 && y <= 750 && isLive)){
                isLive = false;
                //System.out.println("子弹的线程退出");

                break;
            }

        }
    }
}

5)Bomb类

package com.rxli.game;

public class Bomb {
    private int x, y;//炸弹的坐标
    private int life = 9;//炸弹的生命周期
    private boolean isLife = true;

    public Bomb(int x, int y) {
        this.x = x;
        this.y = y;
    }

    //减少生命值
    public void lifeDown(){
        if(life > 0){
            life--;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }else {
            isLife = false;
        }
    }

    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 getLife() {
        return life;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public boolean isLife() {
        return isLife;
    }

    public void setLife(boolean life) {
        isLife = life;
    }
}

6)Recorder类

package com.rxli.game;


import java.io.*;
import java.util.Vector;

/**
 * 该类记录文件信息和文件交互
 */
public class Recorder {

    //定义变量记录我方击毁敌人坦克数
    private static int hitTankNums = 0;
    //定义IO对象
    private static BufferedWriter bw = null;
    private static BufferedReader br = null;
    private static String recordFile = "src\\myRecord.txt";

    private static Vector<EnemyTank> enemyTanks = null;

    //定义一个node 的Vector,用于恢复信息
    private static Vector<Node> nodes = new Vector<>();

    //添加一个方法,用于读取recordFile,恢复相关的信息
    public static Vector<Node> getNodesAndEnemyNums() {

        try {
            br = new BufferedReader(new FileReader(recordFile));
            //循环读取文件,生成 nodes 集合
            String line = "";//255 40 0
            while ((line = br.readLine()) != null) {
                String[] s = line.split(" ");
                if (s.length == 3) {
                    Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
                    nodes.add(node);
                } else if (s.length == 1) {
                    line = s[0];
                    int hitTankNums = Integer.parseInt(line);
                    setHitTankNums(hitTankNums);
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return nodes;
    }

    //添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
    public static void keepRecord() {
        try {
            bw = new BufferedWriter(new FileWriter(recordFile));

            //记录每个存活的敌方坦克
            for (int i = 0; i < enemyTanks.size(); i++) {
                EnemyTank enemyTank = enemyTanks.get(i);
                if (enemyTank.isLive()) {
                    bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect() + "\r\n");
                }
            }

            bw.write(hitTankNums + "\r\n");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String getRecordFile() {
        return recordFile;
    }

    public static int getHitTankNums() {
        return hitTankNums;
    }

    public static Vector<EnemyTank> getAnemyTanks() {
        return enemyTanks;
    }

    public static void setAnemyTanks(Vector<EnemyTank> enemyTanks) {
        Recorder.enemyTanks = enemyTanks;
    }

    public static void setHitTankNums(int hitTankNums) {
        Recorder.hitTankNums = hitTankNums;
    }

    public static void addHitTankNums() {
        Recorder.hitTankNums++;
    }
}

7)Node类

package com.rxli.game;

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


}

8)AePlayerWave类

package com.rxli.game;

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

    }
}

9)MyPanel类

package com.rxli.game;

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

/**
 * 坦克大战的绘图区域
 */
//为了监听键盘事件,实现KeyLister
public class MyPanel extends JPanel implements KeyListener, Runnable {
    //定义我的坦克
    private int hitNums;

    private Hero hero = null;

    private Boolean flag = false;

    //定义敌人的坦克
    Vector<EnemyTank> enemyTanks = new Vector<>();

    //定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
    Vector<Node> nodes = null;
    //定义Vector用于存放炸弹
    //说明,当子弹击中坦克时,加入Bomb对象到Bombs
    Vector<Bomb> bombs = new Vector<>();

    //定义三张图片用于爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    public MyPanel(String key){

        //判断文件是否存在
        if(new File(Recorder.getRecordFile()).exists()) {
            //读文件
            nodes = Recorder.getNodesAndEnemyNums();
        } else {
            System.out.println("文件不存在,只能开启新游戏");
            key = "1";
        }

        //传入 anemyTanks 并记录
        Recorder.setAnemyTanks(enemyTanks);

        //初始化自己坦克
        hero = new Hero(50,600);

        // 判断是重新开始,还是继续游戏
        switch (key){
            case "1"://重新开始

                Recorder.setHitTankNums(0);

                //初始化敌人坦克
                for (int i = 0; i < 5; i++) {
                    //创建一个敌人坦克
                    EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
                    //把敌方坦克集合传给Enemy类
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(2);
                    //启动敌方坦克
                    Thread thread = new Thread(enemyTank);
                    thread.start();
                    //给anemyTank加入一个子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.getShots().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());
                    //将 anemyTanks设置个AnemyTank
                    enemyTank.setEnemyTanks(enemyTanks);
                    //设置方向
                    enemyTank.setDirect(node.getDirect());
                    //启动敌方坦克
                    Thread thread = new Thread(enemyTank);
                    thread.start();
                    //给anemyTank加入一个子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.getShots().add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    enemyTanks.add(enemyTank);
                }
                break;
            default:
                System.out.println("你输入的有误:");
        }



        //初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha1.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha2.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha3.png"));


        // 播放音乐
        new AePlayWave("src\\start.wav").start();
    }

    //编写方法,显示我方击落敌方坦克的信息
    public void showHitInfo(Graphics g){

        //画出玩家的总成绩
        g.setColor(Color.black);
        Font font = new Font("宋体", Font.BOLD, 18);
        g.setFont(font);

        g.drawString("你累计击败敌方坦克", 810,30 );
        drawTank(820, 60, g, 0, 0);//画出个敌方坦克
        g.setColor(Color.black);//这里需要重新获取黑色
        g.drawString(String.valueOf(Recorder.getHitTankNums()), 900, 100);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        g.fillRect(0,0,800, 750);//填充矩形,默认黑色

        showHitInfo(g);

        if (hero != null && hero.isLife()){
            //画出坦克--封装方法
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
        }

        //将hero中的shots集合遍历取出绘制,发射多颗子弹
        for (int i = 0; i < hero.getShots().size(); i++) {
            Shot shot =  hero.getShots().get(i);
            if (shot != null && shot.isLive()){
                g.setColor(Color.yellow);
                g.fill3DRect(shot.getX()-1,shot.getY()-1, 5, 5, false);
            }else {//如果子弹已经失效,移除
                hero.getShots().remove(shot);
            }

        }

        //画出敌人的坦克
        for (int i = 0; i < enemyTanks.size(); i++){
            //取出坦克
            EnemyTank enemyTank = this.enemyTanks.get(i);

            //判断当前的坦克是否存活
            if (enemyTank.isLive()){//当敌人坦克是存活的
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
                //取出enemyTank所有子弹
                for (int j = 0; j < enemyTank.getShots().size(); j++){
                    //取出子弹准备绘制
                    Shot shot = enemyTank.getShots().get(j);
                    //绘制
                    if (shot.isLive()){//isLive == true;
                        g.fill3DRect(shot.getX()-1, shot.getY()-1, 5, 5, false);
                    }else {
                        //移除子弹
                        enemyTank.getShots().remove(shot);
                    }
                }
            }

        }

        //如果bombs集合中有对象,就画出
        for (int i = 0; i < bombs.size(); i++) {
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前bomb对象的life去画出对应的图像
            if (bomb.getLife() > 6){
                g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
            }else if (bomb.getLife() > 3){
                g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
            }else {
                g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
            }
            //让这个炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb life为0,就从bombs的集合中删除
            if (bomb.getLife() == 0){
                bombs.remove(bomb);
            }
        }



    }


    //边写方法画出坦克
    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.fill3DRect(x+18,y,4,20,false);
                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.fill3DRect(x+30,y+18,30,4,false);
                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.fill3DRect(x+18,y+30,4,30,false);
                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.fill3DRect(x,y+18,30,4,false);
                break;

        }


    }



    @Override
    public void keyTyped(KeyEvent e) {

    }



    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W) { //向上
            //改变我方tank1方向
            hero.setDirect(0);
            if(hero.getY() > 0) { //控制移动范围
                hero.moveUp();
            }
        } else if(e.getKeyCode() == KeyEvent.VK_A){//向左
            hero.setDirect(3);
            if(hero.getX() > 0){
                hero.moveLeft();
            }
        } else if(e.getKeyCode() == KeyEvent.VK_S){//向下
            hero.setDirect(2);
            if(hero.getY() + 60 < 700) {
                hero.moveDown();
            }
        }  else if(e.getKeyCode() == KeyEvent.VK_D){//向右
            hero.setDirect(1);
            if(hero.getX() + 60 < 800) {
                hero.moveRight();
            }
        }

        //如果用户用户按下的是J,就发射
        if (e.getKeyCode() == KeyEvent.VK_J){

            //发射多颗子弹
            hero.shotEnemyTank();


        }
        this.repaint();
    }

    //判断敌方坦克打到我方坦克
    public void hitMyTank(){
        //遍历所有的敌方坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            //取出敌方坦克
            EnemyTank enemyTank = enemyTanks.get(i);
            //遍历他的所有子弹
            for(int j = 0; j < enemyTank.getShots().size(); j++){
                Shot s = enemyTank.getShots().get(j);
                //判断shot是否击中我方的坦克
                if(hero.isLife() && s.isLive()){
                    hitTank(s, hero);
                }

            }
        }
    }

    //如果我们可以发射多颗子弹
    //在判断我方的坦克是否命中敌人时,需要把所有子弹遍历出来,挨个判断

    //编写方法,判断我方的坦克是否命中目标
    //什么时候判断我方坦克击中敌方的坦克
    public void hitTank(Shot s, Tank tank){

        switch (tank.getDirect()){
            case 0://方向为上
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
                        && s.getY() > tank.getY() && s.getY() <= tank.getY() + 60
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    enemyTanks.remove(tank);

                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof EnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1://方向为右
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
                        && s.getY() > tank.getY() && s.getY() < tank.getY() + 40
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    enemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof EnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);

                }
                break;

            case 2://方向为下
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
                        && s.getY() > tank.getY() && s.getY() <= tank.getY() + 40
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    enemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof EnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);

                }
                break;
            case 3:
                if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
                        && s.getY() > tank.getY() && s.getY() < tank.getY() + 60
                ){
                    s.setLive(false);
                    tank.setLife(false);

                    //当我的子弹击中敌人的坦克后,将tank拿掉就可以了
                    enemyTanks.remove(tank);


                    //当我方击毁一个敌方坦克时,进行数据更改
                    if (tank instanceof EnemyTank){
                        Recorder.addHitTankNums();
                    }

                    //创建Bomb对象,加入到Bombs集合中来
                    Bomb bomb = new Bomb(tank.getX(),tank.getY());
                    bombs.add(bomb);
                }
                break;
        }

    }

    public void hitAnemyTank(){
        for (int i = 0; i < hero.getShots().size(); i++) {
            Shot shot = hero.getShots().get(i);
            //判断是否击中敌人的坦克
            if (shot != null && shot.isLive()) {//当我的子弹还活着
                //遍历敌人所有的坦克
                for (int j = 0; j < enemyTanks.size(); j++) {
                    EnemyTank enemyTank = enemyTanks.get(j);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        //每隔100毫秒,重绘区域
        while (true){

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断我方子弹是否击中敌方的  坦克
            hitAnemyTank();

            hitMyTank();
            this.repaint();
        }
    }
}

10)TankGame类

package com.rxli.game;

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

public class TankGame extends JFrame {

    //定义一个MyPanel
    private MyPanel mp = null;
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {

        TankGame TankGame = new TankGame();
    }

    public TankGame(){
        System.out.println("请输入选择: 1.新游戏 2.继续上局");
        String key = scanner.next();
        mp = new MyPanel(key);
        //开启多线程
        Thread thread = new Thread(mp);
        thread.start();
        this.add(mp);//绘图区域
        this.setSize(1000,750);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addKeyListener(mp);

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值