欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

玩转CSDN实战教程:利用Java修改游戏存档(初级篇)

最编程 2024-02-19 14:31:28
...

前言


植物大战僵尸的数据文件是存储在本地的dat文件当中,修改在本地的dat文件就可以修改到游戏中的数据。之前使用二进制编码工具HexEditor Neo实现了修改植物大战僵尸的本地游戏数据,现在尝试不使用Hex Editor Neo二进制工具编辑游戏存档,使用Java程序来编辑游戏在本地存储的数据。在经历了几次失败以后成功的实现了在Java程序中修改植物大战僵尸的本地数据,在这里将实现的过程以及思路和错误记录下来,便于以后返回温习。

使用Hex Editor Neo修改游戏数据博客链接:C1任务01-修改游戏存档

image.png

一、实现思路


不论是做大型的项目或者只是实现一个小的功能,都要先明确实现的思路,哪一步要做什么要事先明确,不然就会像无头苍蝇一样不知所措。

Java版本:JDK1.8

使用工具:IntelliJ IDEA 2021.1.2

项目管理:maven

实现思路相对简单,因为植物大战僵尸游戏的数据文件存储在本地的存储位置是已知的,因此我们可以将实现过程拆分为以下三个步骤:

  1. 将.dat数据文件抽象为File对象,使用IO流将数据读取到Java程序当中
  2. 将相应位置的数据修改为用户输入的数据
  3. 最后将Java程序中存储的数据通过IO流写回到本地的dat数据文件中

这里可以覆盖回数据文件中也可以修改指定位置的数据,在这里我采用的方法是覆盖原文件的数据

二、项目准备


在正式编写代码之前要先做一些准备工作

1. 创建maven工程


因为本身并不需要在浏览器端展示数据,因此创建一个空的maven工程即可

image.png

image.png

image.png

到这里一个maven工程就创建完毕

2. 导入依赖


①. JSON依赖


在这个Java项目中如果出现异常或其它错误情况,我是以JSON形式输出到控制台,因此在这里我导入了阿里巴巴开发的fastjson依赖

image.png

<!--  导入alibaba的Json依赖  -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

②. Lombok依赖


导入lombok依赖的原因是为了减少实体类中的代码量,使代码更简洁,可读性更高

image.png

<!--  导入lombok工具  -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

③. Junit4单元测试


在写代码时确保所写方法没有问题的一种方式就是使用单元测试,在这里我导入了Junit4单元测试框架

image.png

<!--  导入单元测试依赖  -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
</dependency>

至此maven工程中的依赖全部导入完成

三、核心代码


1. 使用的对象


在读取dat数据文件中要使用到以下几个Java对象,在此进行简单的介绍

  1. InputStream该抽象类是所有的类表示字节输入流的父类
  2. FileInputStream:从文件系统中的文件中获得输入的字节
  1. DataOutputStream将数据写入到指定的基本输出流中

2. 读取数据文件


我在读取数据文件时将文件的存储路径定义成了全局变量,便于在每个方法中进行调用

image.png

因为存储植物大战僵尸的数据文件user1.dat中数据是以二进制的方式进行存储,因此我们在读取文件内容时也要使用二进制的方式进行读取

如果使用字符的方式进行读取的话会出现读取出的数据只有几个字符的情况,用记事本打开dat文件就会发现在二进制数据文件中的内容只有一行并且很多字符都是以空格形式存在的,因此使用字符读入的方式就只能读取到一行数据,并且空格数据会被当成null进行处理所以显示的结果就只有几个字符。

将读取到的整数数据存储到泛型约束为Integer类型的List集合当中,进行存储

/**
 * 读取文件内容并将读取到的内容以List集合的格式返回
 *
 * @return 数据的List集合
 */
public static List<Integer> readFile() {
    try {
        // 声明文件对象
        File file = new File(filePath);
        // 将文件内容读取到文件读取流当中
        InputStream in;
        // 将读取的流进行封装
        in = new FileInputStream(file);

        // 定义整数对象用于存储读取到的内容
        int content;
        // 一次读取一行,直到读入的内容为null时读取文件的过程结束
        while ((content = in.read()) != -1) {
            // 将读取到的内容存储到List集合中
            nums.add(content);
        }
         // 关闭流
        in.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return nums;
}

2. 修改关卡信息


在之前修改游戏存档数据时就明白,在user1.dat文件中,第4列中的十六进制内容代表着关卡信息,因此在修改游戏的关卡信息时就要指定List集合中下标为4的集合数据值为用户输入的值。在这里用户输入的数据虽然是十进制的数据,但是在将数据写入user1.dat文件时不需要再进行十进制到十六进制的转换了,因为最后在文件中存储的形式都是二进制的0和1的形式进行存储的

/**
 * 修改关卡数据
 *
 * @param result 要修改的关卡(十六进制)
 */
public void writeFileCheckPoint(String result) {
    // 进行文件的读取
    List<Integer> dataList = ReadUtil.readFile();
    // 将修改关卡列上的数据
    dataList.set(4, Integer.valueOf(result, 16));
    ReadUtil.writeFile(dataList);
    dataList.removeAll(dataList);
    System.out.println("关卡数据写入完成!");
    
}

将数据输出到数据文件的方法

/**
 * 将文件内容写入到user1.dat文件中,可以进行修改关卡和修改金币数量
 *
 * @param dataList 传来的整型数组
 */
public static void writeFile(List<Integer> dataList) {
    // 声明要输出到的文件对象
    File file = new File(filePath);
    try {
        // 定义数据输出流
        DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
        // 遍历传来的List集合
        for (Integer integer : dataList) {
            // 将List集合中的数据写入到user1.dat文件中
            out.write(integer);
            // 刷新输出流
            out.flush();
        }

        // 关闭输出流
        out.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

3. 修改金币信息


在这里还要注意到,虽然第八列和第九列的内容代表着金币信息,但是在这里的第九列的数据为高位,并不是按照惯性思维从第八列开始依次排列,因此在存储金币信息时要进行单独的处理。

具体的处理方法就是,将十进制数转换为十六进制数据时如果转换后的十六进制数的长度为3位(在Java中十进制数转换为十六进制数时,十六进制数是以String类型进行存储和显示的),则在转换后的字符串的起始位置加0,这样做的原因是要进行截取两位,让高位的数据在高位存储,低位的数据在低位存储。

例如:

上一篇: 懒人必备!GitHub 当下热门看点速览

下一篇: 首推发布:遇到Java报错 "com.sun.jna.Library 未找到类定义",全网新鲜解析