您的位置:首页 > 财经 > 产业 > 第二十章:坦克大战3

第二十章:坦克大战3

2024/10/5 20:28:28 来源:https://blog.csdn.net/weixin_47199727/article/details/141210716  浏览:    关键词:第二十章:坦克大战3

一 IO流 - 应用到坦克大战

1 坦克大战5.0版

增强功能

(1)防止坦克重叠运动;

思路

首先分析各种情况:

在这里插入图片描述

实现代码

① 首先要在EnemyTank类中加入敌人坦克集合属性,然后创建一个set敌人坦克集合的方法,然后设计碰撞的方法。

//增加成员,EnemyTank 可以得到敌人坦克的Vector//分析//1. Vector<EnemyTank> 在Vector<EnemyTank> enemyTanks = new Vector<>();//这里提供一个方法,可以将MyPanel 的成员 Vector<EnemyTank> enemyTanks = new Vector<>();//设置到 EnemyTank 的成员 enemyTankspublic void setEnemyTanks(Vector<EnemyTank> enemyTanks) {this.enemyTanks = enemyTanks;}
//编写方法,判断当前的这个敌人坦克,是否和 enemyTanks 中的其他坦克发生的重叠或者碰撞public boolean isTouchEnemyTank() {//判断当前敌人坦克(this) 方向switch (this.getDirect()) {case 0: //上//让当前敌人坦克和其它所有的敌人坦克比较for (int i = 0; i < enemyTanks.size(); i++) {//从vector 中取出一个敌人坦克EnemyTank enemyTank = enemyTanks.get(i);//不和自己比较if (enemyTank != this) {//如果敌人坦克是上/下//老韩分析//1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {//2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}//3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}}//如果敌人坦克是 右/左//老韩分析//1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {//2. 当前坦克 左上角的坐标 [this.getX(), this.getY()]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}//3. 当前坦克 右上角的坐标 [this.getX() + 40, this.getY()]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}}}}break;case 1: //右//让当前敌人坦克和其它所有的敌人坦克比较for (int i = 0; i < enemyTanks.size(); i++) {//从vector 中取出一个敌人坦克EnemyTank enemyTank = enemyTanks.get(i);//不和自己比较if (enemyTank != this) {//如果敌人坦克是上/下//老韩分析//1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {//2. 当前坦克 右上角的坐标 [this.getX() + 60, this.getY()]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}//3. 当前坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 40&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 60) {return true;}}//如果敌人坦克是 右/左//老韩分析//1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {//2. 当前坦克 右上角的坐标 [this.getX() + 60, this.getY()]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}//3. 当前坦克 右下角的坐标 [this.getX() + 60, this.getY() + 40]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 60&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 40) {return true;}}}}break;case 2: //下//让当前敌人坦克和其它所有的敌人坦克比较for (int i = 0; i < enemyTanks.size(); i++) {//从vector 中取出一个敌人坦克EnemyTank enemyTank = enemyTanks.get(i);//不和自己比较if (enemyTank != this) {//如果敌人坦克是上/下//老韩分析//1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {//2. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 60]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 60) {return true;}//3. 当前坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 40&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 60) {return true;}}//如果敌人坦克是 右/左//老韩分析//1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {//2. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 60]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 40) {return true;}//3. 当前坦克 右下角的坐标 [this.getX() + 40, this.getY() + 60]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 60&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 40) {return true;}}}}break;case 3: //左//让当前敌人坦克和其它所有的敌人坦克比较for (int i = 0; i < enemyTanks.size(); i++) {//从vector 中取出一个敌人坦克EnemyTank enemyTank = enemyTanks.get(i);//不和自己比较if (enemyTank != this) {//如果敌人坦克是上/下//老韩分析//1. 如果敌人坦克是上/下 x的范围 [enemyTank.getX(), enemyTank.getX() + 40]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2) {//2. 当前坦克 左上角的坐标 [this.getX(), this.getY() ]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}//3. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 40]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 60) {return true;}}//如果敌人坦克是 右/左//老韩分析//1. 如果敌人坦克是右/左  x的范围 [enemyTank.getX(), enemyTank.getX() + 60]//                     y的范围 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3) {//2. 当前坦克 左上角的坐标 [this.getX(), this.getY() ]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}//3. 当前坦克 左下角的坐标 [this.getX(), this.getY() + 40]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 40) {return true;}}}}break;}return  false;}

② 并且在该类的调用移动方法前面进行判断是否碰撞,例如:

if (!isTouchEnemyTank()) {downMove();
}

③ 在MyPanel类中当创建一个敌人坦克对象后,将敌人坦克集合加入。

enemyTank.setEnemyTanks(enemyTanks);
(2)记录玩家的成绩,存盘退出;【IO流】

思路

在这里插入图片描述

实现代码

① 在MyPanel类中编写方法,显示我方击毁敌方坦克的信息。

 //编写方法,显示我方击毁敌方坦克的信息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);}

② 在MyPanel类的paint方法中调用该方法。

showInfo(g);

③ 新建一个Recorder类。

public class Recorder {//定义变量,记录我方击毁敌人坦克数private static int allEnemyTankNum = 0;//定义IO对象, 准备写数据到文件中private static BufferedWriter bw = null;private static String recordFile = "e:\\myRecord.txt";//增加一个方法,当游戏退出时,我们将allEnemyTankNum 保存到 recordFilepublic static void keepRecord() throws IOException {bw = new BufferedWriter(new FileWriter(recordFile));bw.write(allEnemyTankNum + "");bw.newLine();if (bw != null){bw.close();}}public static int getAllEnemyTankNum() {return allEnemyTankNum;}public static void setAllEnemyTankNum(int allEnemyTankNum) {Recorder.allEnemyTankNum = allEnemyTankNum;}//当我方坦克击毁一个敌人坦克,就应当 allEnemyTankNum++public static void addAllEnemyTankNum() {Recorder.allEnemyTankNum++;}}

④ 在击中敌人坦克时候调用该类的addAllEnemyTankNum方法,在主类中,加入监听,在关闭窗口时候用包调用Recorder的keepRecord方法,使用包装类将击败坦克数字保存到文件里 。

//在JFrame 中增加相应关闭窗口的处理this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {Recorder.keepRecord();System.exit(0);}});
(3)记录当时的敌人坦克坐标,存盘退出;【IO流】

思路
在这里插入图片描述

实现代码

① 首先在Recorder类中添加属性Vector ,指向 MyPanel 对象的 敌人坦克Vector,并设置set方法来接受该集合。

//定义Vector ,指向 MyPanel 对象的 敌人坦克Vector
private static Vector<EnemyTank> enemyTanks = null;
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {Recorder.enemyTanks = enemyTanks;
}

② 在KeepRecord方法中遍历敌人坦克集合,将存活坦克的位置信息保存。

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

③ 在MyPanel类的构造方法中,将坦克集合赋给Recorder类的坦克集合。

//将MyPanel对象的 enemyTanks 设置给 Recorder 的 enemyTanks
Recorder.setEnemyTanks(enemyTanks);

(4)玩游戏时,可以选择是开新游戏还是继续上局游戏。
思路

在这里插入图片描述

代码实现

① 新建Node类,用于保存从recordFile文件读取的敌人坦克信息。

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

② 在Recorder类中添加Node集合,并创建读文件的方法,返回值是Node集合。

private static Vector<Node> nodes = new Vector<>();
//增加一个方法,用于读取recordFile, 恢复相关信息
//该方法,在继续上局的时候调用即可public static Vector<Node> readFile() throws IOException {bufferedReader = new BufferedReader(new FileReader(recordFile));String num = "";num = bufferedReader.readLine();allShotEnemyTankNums = Integer.parseInt(num);String info = null;//循环读取文件,生成nodes 集合while ((info = bufferedReader.readLine()) != null){String[] s = info.split(" ");Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.valueOf(s[2]));nodes.add(node);//放入nodes Vector}if (bufferedReader != null) {bufferedReader.close();}return nodes;}

③ 在TankGame类中添加num属性,main类中添加如下代码,用于选择游戏类型。

static int num = -1;//0表示继续,1表示新开
Scanner scanner = new Scanner(System.in);System.out.print("继续游戏(0)or新游戏(1):");while (true) {num = scanner.nextInt();if (num == 0 || num == 1) {break;}System.out.println("请重输..");}new TankGame04();

④ 在MyPanel类中定义并创建node集合属性,用于接受敌人坦克信息,并且在构造器中根据选择的是继续游戏还是新游戏来进行敌人坦克的初始化。

Vector<Node> nodes = new Vector<>();
//构造方法中
nodes = Recorder.readFile();
if (TankGame04.num == 1) {//开启一局新游戏//初始化敌人坦克for (int i = 0; i < enemyTankSize; i++) {//创建一个敌人的坦克EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);//将enemyTanks 设置给 enemyTank !!!enemyTank.setEnemyTanks(enemyTanks);//设置方向enemyTank.setDirect(1);//启动敌人坦克线程,让他动起来new Thread(enemyTank).start();//给该enemyTank 加入一颗子弹Bullet bullet = new Bullet((enemyTank.getX() + 20), (enemyTank.getY() + 60), 1);//加入enemyTank的Vector 成员enemyTank.bullets.add(bullet);//启动 shot 对象Thread thread = new Thread(bullet);//开启线程thread.start();//加入敌人坦克集合enemyTanks.add(enemyTank);}}else if (TankGame04.num == 0){//继续上局游戏for (int i = 0; i < nodes.size(); i++) {EnemyTank enemyTank = new EnemyTank(nodes.get(i).getX(), nodes.get(i).getY());enemyTank.setEnemyTanks(enemyTanks);enemyTank.setDirect(nodes.get(i).getDirection());new Thread(enemyTank).start();enemyTanks.add(enemyTank);}}
2 坦克大战6.0版
(1)游戏开始时,播放经典的坦克大战音乐;

加入AePlayWave类文件,并且将wav音乐文件放在指定的位置,在MyPanel类的构造器中加入如下代码即可。

new AePlayWave("src\\111.wav").start();
(2)修正下文文件存储的位置;
private static String recordFile = "src\\recordFile.txt";
(3)处理文件相关异常。

把MyPanel类的构造器的调用Recorder类的readFile方法加上条件判断,防止第一没有文件的话出现的异常。

//先判断记录的文件是否存在//如果存在,就正常执行,如果文件不存在,提示,只能开启新游戏,key = "1"File file = new File(Recorder.getRecordFile());if (file.exists()) {nodes = Recorder.getNodesAndEnemyTankRec();} else {System.out.println("文件不存在,只能开启新的游戏");key = "1";}

new AePlayWave("src\\111.wav").start();
(2)修正下文文件存储的位置;
private static String recordFile = "src\\recordFile.txt";
(3)处理文件相关异常。

把MyPanel类的构造器的调用Recorder类的readFile方法加上条件判断,防止第一没有文件的话出现的异常。

//先判断记录的文件是否存在//如果存在,就正常执行,如果文件不存在,提示,只能开启新游戏,key = "1"File file = new File(Recorder.getRecordFile());if (file.exists()) {nodes = Recorder.getNodesAndEnemyTankRec();} else {System.out.println("文件不存在,只能开启新的游戏");key = "1";}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com