百木园-与人分享,
就是让自己快乐。

day06-IO流应用01-2

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类中

image-20220915160450882

ps:引用类型传递的是地址,地址不会变化,因此可以获取到集合的最新的状态

关闭时:

image-20220915160844262

记录状态:

image-20220915160923441

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

}

退出时:

day06-IO流应用01-2

继续上局:

image-20220915172402336
image-20220915172437378

ps:这里截图不及时,实际上恢复的位置与上局一致


来源:https://www.cnblogs.com/liyuelian/p/16697374.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » day06-IO流应用01-2