Java坦克大战06
8.IO流应用01-2
8.3记录退出游戏时敌人坦克坐标/方向,存盘退出
8.3.1思路分析
在Recorder类中,增加一个Vector集合,用来接收从MyPanel类中传入的enemyTanks集合,在记录时遍历集合,将还存活的敌人坦克的方向和坐标逐一取出并保存
8.3.2代码实现
修改处1
Recorder类:增加属性enemyTanks、增加方法setEnemyTanks、修改keepRecord方法:
//定义Vector,指向MyPanel对象的敌人坦克的Vector
private static Vector<EnemyTank> enemyTanks = null;
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static void keepRecord() {
try {
bw = new BufferedWriter(new FileWriter(recordFile));
bw.write(allEnemyTankNum + \"\\n\");
//遍历敌人坦克的Vector,根据情况保存即可
for (int i = 0; i < enemyTanks.size(); i++) {
//取出敌人坦克
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive) {//虽然被击中的坦克对象已经被删除了,但是还是建议判断一下
//保存该enemyTank信息
String record = enemyTank.getX()+\" \"+enemyTank.getY()+\" \"+enemyTank.getDirect();
//写入到文件中
bw.write(record+\"\\n\");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
修改处2
在MyPanel类中的MyPanel方法,调用Recorder的静态方法setEnemyTanks,将敌人坦克的集合enemyTanks传到Recorder类中
ps:引用类型传递的是地址,地址不会变化,因此可以获取到集合的最新的状态
关闭时:
记录状态:
8.4玩游戏时可以选择是开新游戏还是继续上局游戏
8.4.1思路分析
将每个敌人信息恢复(读取)成Node对象,再放到vector里面去,通过Node的vector去初始化敌人坦克的位置和方向
8.4.2代码实现
修改处1
新建一个Node类:
package li.TankGame.version06;
/**
* @author 李
* @version 6.0
* 一个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;
}
}
修改处2
在Recorder类中:
创建一个BufferedReader对象:
private static BufferedReader br = null;//输入处理流
定义一个Node的Vector对象,用于保存敌人的信息node:
//定义一个Node的Vector对象,用于保存敌人的信息node
private static Vector<Node> nodes = new Vector<>();
增加getNodesAndEnemyTankRec方法,用于读取recordFile,恢复相关信息:
//增加一个方法,用于读取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) {
//用空格将每一行的数据分割,分割完的字符数组里面存储了一组敌方坦克的x,y,direct
String[] xyd = line.split(\" \");
//将字符串转为int类型,赋值给node对象
Node node = new Node(Integer.parseInt(xyd[0]),
Integer.parseInt(xyd[1]), Integer.parseInt(xyd[2]));
//将该node对象放到nodes集合中
nodes.add(node);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return nodes;
}
修改处3
在MyPanel类中:
定义一个存放Node对象的Vector,用于恢复敌人坦克的坐标和方向:
//定义一个存放Node对象的Vector,用于恢复敌人坦克的坐标和方向
Vector<Node> nodes = new Vector<>();
修改MyPanel方法,修改了方法传入的参数String key;
在方法里面调用了getNodesAndEnemyTankRec,将其返回的nodes集合传给MyPanel类的nodes的集合;
使用switch,根据输入的key判断是新开一局还是接着上一局游戏;
public MyPanel(String key) {
nodes = Recorder.getNodesAndEnemyTankRec();
//将MyPanel对象的enemyTanks 设置给Recorder的enemyTanks
Recorder.setEnemyTanks(enemyTanks);
hero = new Hero(400, 200);//初始化自己的坦克
//hero.setSpeed(5); //改变坦克的速度
switch (key){
case \"1\": //开新游戏
Recorder.setAllEnemyTankNum(0);//重设击毁敌方坦克数目
//初始化敌人的坦克
for (int i = 0; i < enemyTankNum; i++) {
//创建一个敌人的坦克
EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
//将enemyTanks集合设置给 enemyTank
enemyTank.setEnemyTanks(enemyTanks);
//初始化敌人坦克方向向下
enemyTank.setDirect(2);
//启动敌人坦克线程,让他动起来
new Thread(enemyTank).start();
//给该enemyTank加入一颗子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//将该子弹加入到enemyTank的Vector集合中
enemyTank.shots.add(shot);
//启动 shot对象
new Thread(shot).start();
//将设置好的的敌人坦克放入到集合中
enemyTanks.add(enemyTank);
}
break;
case \"2\": //继续上局游戏
//初始化敌人的坦克
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
//创建一个敌人的坦克
EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
//将enemyTanks集合设置给 enemyTank
enemyTank.setEnemyTanks(enemyTanks);
//初始化敌人坦克方向向下
enemyTank.setDirect(node.getDirect());
//启动敌人坦克线程,让他动起来
new Thread(enemyTank).start();
//给该enemyTank加入一颗子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//将该子弹加入到enemyTank的Vector集合中
enemyTank.shots.add(shot);
//启动 shot对象
new Thread(shot).start();
//将设置好的的敌人坦克放入到集合中
enemyTanks.add(enemyTank);
}
break;
default:
System.out.println(\"输入有误\");
}
//初始化图片对象
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource(\"/bomb1.png\"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource(\"/bomb2.png\"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource(\"/bomb3.png\"));
}
修改处4
在TankGame06类中新建一个Scanner对象:
static Scanner scanner = new Scanner(System.in);
修改TankGame06构造器,是在控制台输入的选择传到MyPanel构造器中:
public TankGame06() {
System.out.println(\"请输入选择:\\n\" + \"1:新游戏 2:继续上局\");
String key = scanner.next();
mp = new MyPanel(key);
//将mp放入到Thread,并启动
Thread thread = new Thread(mp);
thread.start();
this.add(mp);//把面板(就是游戏的绘图区域)添加进来
this.setSize(950, 600);//设置大小
this.addKeyListener(mp);//让JFrame监听mp的键盘事件
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击窗口的叉时停止运行
this.setVisible(true);//设置显示
//在JFrame中增加相应关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Recorder.keepRecord();
System.exit(0);
}
});
}
退出时:
继续上局:
ps:这里截图不及时,实际上恢复的位置与上局一致
来源:https://www.cnblogs.com/liyuelian/p/16697374.html
本站部分图文来源于网络,如有侵权请联系删除。