通过Java修改游戏存档的实现思路

目录
  • 前言
  • 一、实现思路
  • 二、项目准备
    • 1. 创建maven工程
    • 2. 导入依赖
  • 三、核心代码
    • 1. 使用的对象
    • 2. 修改关卡信息
    • 3. 修改金币信息
  • 四、代码测试
    • 1. 读取数据文件
    • 2. 修改关卡位置
    • 3. 修改金币数量
    • 4. 退出修改器
    • 5. 输入参数错误情况
  • 五、源码
    • 1. 项目结构
    • 2. 项目代码
  • 总结

前言

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

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

提示:以下是本篇文章正文内容,下面案例可供参考

一、实现思路

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

Java版本:JDK1.8
使用工具:IntelliJ IDEA 2021.1.2
项目管理:maven

idea2021最新激活码:

https://www.jb51.net/article/196349.htm

https://www.yuque.com/docs/share/b996d27e-c888-45f2-bb1e-f6db5efe2485?#

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

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

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

二、项目准备

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

1. 创建maven工程

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



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

2. 导入依赖

①. JSON依赖

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

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

②. Lombok依赖

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

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

③. Junit4单元测试

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

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

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

三、核心代码

1. 使用的对象

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

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

2. 读取数据文件

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

因为存储植物大战僵尸的数据文件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,这样做的原因是要进行截取两位,让高位的数据在高位存储,低位的数据在低位存储。

例如:

十进制数据转换为十六进制数据的转换方法如下:

/**
 * 将十进制整数转换为16进制的字符串
 *
 * @param num 传来的十进制整数
 * @return 转换为16进制后的字符串
 */
 public static String intToHex(int num) {
    // 如果传来的整数为0则直接返回
	if (num == 0) {
		return "0";
    }

    // 使用到StringBuilder效率会更高
    StringBuilder builder = new StringBuilder();

    // 定义16进制下的所有数字
    char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    // 如果传来的数不为0则一直进行除法运算
    while (num != 0) {
        builder = builder.append(hexChar[num % 16]);
        num = num / 16;
    }

    if (builder.length() == 1 || builder.length() % 2 != 0) {
        return "0" + builder.reverse();
    }

    // 最后将builder反转并返回
    return builder.reverse().toString();

}

修改金币数量的方法

/**
 * 修改金币数据
 *
 * @param result 要修改的金币数量(十六进制)
 */
public void writeFileMoney(String result) {
    // 进行文件的读取
    List<Integer> dataList = ReadUtil.readFile();
    // 将传来的字符长度进行除2运算
    int count = result.length() >> 1;
    if (count > 1) {
        // 以两位为单位长度进行截取,一共有两个数据
        String firstStr = result.substring(0, 2);  // 低位数据
        String secondStr = result.substring(2, 4);  // 高位数据

		// 设置低位的数据
        dataList.set(8, Integer.valueOf(secondStr, 16));
        // 设置高位的数据
        dataList.set(9, Integer.valueOf(firstStr, 16));
        // 将修改后的金币数据数据写入文件
        ReadUtil.writeFile(dataList);
        System.out.println("金币数据写入完成!");
        // 清空集合中的数据
        dataList.removeAll(dataList);

    } else {
        // 将修改关卡列上的数据
        dataList.set(8, Integer.valueOf(result, 16));
        // 当进入这里时第九位一定为0,当从很多的金币修改到很少的金币时要确保第九位为0
        dataList.set(9, 0);
        // 将修改后的整型List集合写入到dat文件中
        ReadUtil.writeFile(dataList);
        System.out.println("金币数据写入完成!");
        // 清空集合中的数据
        dataList.removeAll(dataList);
    }

}

四、代码测试

接下来对所写的Java项目进行测试,首先是一个金币为0且关卡数为0的空白存档,在修改文件时先将植物大战僵尸关闭,因为在修改数据文件时如果植物大战僵尸游戏开着,虽然将数据文件的内容做了修改,但是在关闭植物大战僵尸后,游戏仍然会将当前游戏内的数据信息覆盖到dat文件中,因此就相当于没有进行任何修改

现在关闭植物大战僵尸游戏并且在IntelliJ IDEA中将主类启动

1. 读取数据文件

首先读取数据文件,查看第4列的数据是否为01(默认第一关)与第8列的数据是否为0(默认金币为0)

读取到的数据文件内容正确

2. 修改关卡位置

现在将关卡修改到第42关,即5-2关

再读取数据文件,查看第四列的值是否为2a

现在进入到游戏中查看关卡是否改变

关卡的数据和我们修改的内容一样,现在再查看商店中的金币数量是否为0

金币数量也为0,说明只修改了关卡信息

3. 修改金币数量

此时进行修改金币的数量

再读取数据文件,查看第八列的数据是否为e8,第九列的数据是否为03

进入游戏中查看金币是否发生了变化


此时金币数量修改为了10000

4. 退出修改器

5. 输入参数错误情况

在项目启动时输入的内容不是修改器的功能选项时

关卡位置和金币数量越界情况


成功以JSON格式输出,至此Java项目测试完毕

五、源码

1. 项目结构

2. 项目代码

①. ResultInfo类,位于pojo包

package com.shijimo.game.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @author Dream_飞翔
 * @date 2021/10/26
 * @time 18:32
 * @email 1072876976@qq.com
 *
 * 输出提示信息
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ResultInfo {
    private Integer code;   // 状态码
    private String msg;     // 提示信息
}

②. EditorService类,位于service包

package com.shijimo.game.service;

import com.shijimo.game.util.ReadUtil;

import java.util.List;

/**
 * @author Dream_飞翔
 * @date 2021/10/26
 * @time 18:29
 * @email 1072876976@qq.com
 */
public class EditorService {

    /**
     * 修改关卡数据
     *
     * @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("关卡数据写入完成!");
    }

    /**
     * 修改金币数据
     *
     * @param result 要修改的金币数量(十六进制)
     */
    public void writeFileMoney(String result) {
        // 进行文件的读取
        List<Integer> dataList = ReadUtil.readFile();
        // 将传来的字符长度进行除2运算
        int count = result.length() >> 1;
        if (count > 1) {
            // 以两位为单位长度进行截取,一共有两个数据
            String firstStr = result.substring(0, 2);
            String secondStr = result.substring(2, 4);

            dataList.set(8, Integer.valueOf(secondStr, 16));
            dataList.set(9, Integer.valueOf(firstStr, 16));
            // 将修改后的金币数据数据写入文件
            ReadUtil.writeFile(dataList);
            System.out.println("金币数据写入完成!");
            dataList.removeAll(dataList);

        } else {
            // 将修改关卡列上的数据
            dataList.set(8, Integer.valueOf(result, 16));
            // 当进入这里时第九位一定为0,如果从高位改到低位的话要确保第九位为0
            dataList.set(9, 0);
            ReadUtil.writeFile(dataList);
            System.out.println("金币数据写入完成!");
            dataList.removeAll(dataList);
        }

    }
}

③. NumUtil类,位于util包

package com.shijimo.game.util;

/**
 * @author Dream_飞翔
 * @date 2021/10/26
 * @time 16:32
 * @email 1072876976@qq.com
 * <p>
 * 本类用于将整数进行进制的转换
 */
public class NumUtil {

    /**
     * 将十进制整数转换为16进制的字符串
     *
     * @param num 传来的整数
     * @return 转换为16进制后的字符串
     */
    public static String intToHex(int num) {
        // 如果传来的整数为0则直接返回
        if (num == 0) {
            return "0";
        }

        // 使用到StringBuilder效率会更高
        StringBuilder builder = new StringBuilder();

        // 定义16进制下的所有数字
        char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

        // 如果传来的数不为0则一直进行除法运算
        while (num != 0) {
            builder = builder.append(hexChar[num % 16]);
            num = num / 16;
        }

        if (builder.length() == 1 || builder.length() % 2 != 0) {
            return "0" + builder.reverse();
        }
//        else if (builder.length() >= 1 && builder.length() % 2 != 0) {
//            return builder.reverse() + "0";
//        }

        // 最后将builder反转并返回
        return builder.reverse().toString();
    }

}

⑥. ReadUtil类,位于util包

package com.shijimo.game.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Dream_飞翔
 * @date 2021/10/26
 * @time 10:11
 * @email 1072876976@qq.com
 * <p>
 * 该类用于读取二进制文件中的数据,植物大战僵尸的本地数据文件中只有一行数据
 * 1. 通过InputStream进行二进制方式读取
 * 2. 对每一行的内容进行特殊的处理
 */
public class ReadUtil {
    // 定义文件的路径
    static String filePath = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
    // 定义整型集合类用于存储
    static List<Integer> nums = new ArrayList<>();

    /**
     * 读取文件内容并将读取到的内容以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;
    }

    /**
     * 将文件内容写入到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.flush();
            // 关闭输出流
            out.close();

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

    /**
     * 将指定的文件内容输出到控制台上
     */
    public static void printFile() {
        // 定义整型集合类用于存储
        List<Integer> dataList = new ArrayList<>();

        try {
            // 声明文件对象
            File file = new File(filePath);
            // 将文件内容读取到文件读取流当中
            InputStream in;
            // 将读取的流进行封装
            in = new FileInputStream(file);

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

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

        // 定义标志变量的初值为0
        int count = 0;
        // 将读取到的内容输出
        System.out.println("00\t01\t02\t03\t04\t05\t06\t07\t08\t09\t0a\t0b\t0c\t0d\t0e\t0f");
        // 遍历读取到的整数集合
        for (Integer data : dataList) {
            // 如果标志变量的值对16做取余运算为0的话则进行换行操作
            if (count % 16 == 0)
                System.out.println();
            System.out.print(NumUtil.intToHex(data) + "\t");
            count++;
        }
    }
}

⑦. EditorApplication主启动类,位于项目的最外层包中

package com.shijimo.game;

import com.alibaba.fastjson.JSONObject;
import com.shijimo.game.pojo.ResultInfo;
import com.shijimo.game.service.EditorService;
import com.shijimo.game.util.NumUtil;
import com.shijimo.game.util.ReadUtil;

import java.util.Scanner;

/**
 * @author Dream_飞翔
 * @date 2021/10/26
 * @time 17:01
 * @email 1072876976@qq.com
 */
public class EditorApplication {

    public static void main(String[] args) {
        // 将业务处理对象实例化
        EditorService editorService = new EditorService();

        System.out.println("**********************************************************");
        System.out.println("         ,---._                                         \n" +
                "       .-- -.' \\                                        \n" +
                "       |    |   :                                       \n" +
                "       :    ;   |                                       \n" +
                "       :        |                   .---.               \n" +
                "       |    :   :   ,--.--.       /.  ./|    ,--.--.    \n" +
                "       :           /       \\    .-' . ' |   /       \\   \n" +
                "       |    ;   | .--.  .-. |  /___/ \\: |  .--.  .-. |  \n" +
                "   ___ l           \\__\\/: . .  .   \\  ' .   \\__\\/: . .  \n" +
                " /    /\\    J   :  ,\" .--.; |   \\   \\   '   ,\" .--.; |  \n" +
                "/  ../  `..-    , /  /  ,.  |    \\   \\     /  /  ,.  |  \n" +
                "\\    \\         ; ;  :   .'   \\    \\   \\ | ;  :   .'   \\ \n" +
                " \\    \\      ,'  |  ,     .-./     '---\"  |  ,     .-./ \n" +
                "  \"---....--'     `--`---'                 `--`---'     ");
        System.out.println("\n                 老张写的植物大战僵尸修改器       version: 1.0");

        while (true) {
            System.out.println("**********************************************************");
            System.out.println("*     =======>       1. 修改关卡位置       <=======        *");
            System.out.println("*     =======>       2. 修改金币数量       <=======        *");
            System.out.println("*     =======>       3. 读取数据文件       <=======        *");
            System.out.println("*     =======>       4. 退出此修改器       <=======        *");
            System.out.println("**********************************************************");
            System.out.print("请输入您的选择:");

            // 定义Scanner对象用于接收从键盘上输入的数字
            Scanner scanner = new Scanner(System.in);
            int choose = scanner.nextInt();

            switch (choose) {
                case 1: {
                    Scanner editor = new Scanner(System.in);
                    System.out.println("您的选择是 => 选择修改关卡的位置");
                    System.out.print("请输入您想要跳到的关卡位置(最高50关):");
                    // 接收关卡的位置数据
                    int checkPoint = editor.nextInt();
                    // 进行越界判断
                    if (checkPoint <= 0 || checkPoint > 50) {
                        System.out.println(JSONObject.toJSONString(new ResultInfo(500, "输入数据有误")));
                        break;
                    }
                    // 将提示信息输出
                    System.out.println("正在修改关卡数据...");

                    // 如果输入的数据合法,将其转换为十六进制数据
                    String result = NumUtil.intToHex(checkPoint);
                    // 调用业务层的方法进行修改内容
                    editorService.writeFileCheckPoint(result);

                    System.out.println("关卡数据修改成功!");
                }
                break;
                case 2: {
                    System.out.println("您的选择是 => 修改游戏的金币数量");
                    System.out.print("请输入您想要修改的金币数量(最高655350个):");
                    // 声明输入对象
                    Scanner editor = new Scanner(System.in);
                    // 接收输入的金币数量
                    int money = editor.nextInt();
                    // 进行越界判断
                    if (money > 655350 || money < 0) {
                        System.out.println(JSONObject.toJSONString(new ResultInfo(500, "输入数据有误")));
                        break;
                    }
                    // 如果输入的数据合法,将其转换为十六进制数据
                    String result = NumUtil.intToHex(money / 10);
                    // 调用业务层的方法进行修改数据并返回修改结果
                    editorService.writeFileMoney(result);
                    // 如果金币数量修改成功
                    System.out.println("金币数据修改成功!");

                }
                break;
                case 3: {
                    System.out.println("您的选择是 => 读取游戏的数据文件");
                    System.out.println("开始读取数据文件...");
                    // 读取数据文件并打印
                    ReadUtil.printFile();
                    // 换行
                    System.out.println();
                    // 输出提示信息
                    System.out.println("数据文件读取成功!");
                } break;
                case 4: {
                    System.out.println("感谢您的使用,期待下次再见!");
                    System.exit(0);
                }
                default:
                    System.out.println(JSONObject.toJSONString(new ResultInfo(500, "输入指令有误")));
            }
        }
    }
}

⑧. pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>GameEditor</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

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

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

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

    </dependencies>

</project>

总结

以上便是使用Java修改植物大战僵尸数据文件的过程,还记得当时在使用工具去修改游戏存档数据时都感觉到不可思议与不敢相信!而此时通过Java代码进行修改文件数据时都没有一丝的感觉自己做不成功,对于自己来说,不仅仅是技术上的提高,更重要的是心态上的变化。当自己独立写过一定数量的代码时内心就会变得很有底气,变得更加相信自己,可能就像很多人说的那样,真正的技术一定是相当数量的代码堆叠起来的!

自然界没有风风雨雨,大地就不会春华秋实。若不尝试着做些本事之外的事,就永远不会成长!人生的价值并不在于成功后的荣光,而在于追求的本身,在于信念的树立与坚持的过程。坚守信念,犹如在内心撒下一颗种子,只要在适宜的条件下,种子自会生根发芽破土而出,总会有收获果实的期望。有时需要外力辅助才可取得成果,但最终还要靠自我去完成,因为任何人也不可能把信念深植于你的心中。所以,我们要坚守自我的信念,播下期望的种子。做一名自信者,牢牢把住自我生命的罗盘!

到此这篇关于通过Java修改游戏存档的文章就介绍到这了,更多相关Java修改游戏存档内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java实现简单棋盘存档和读取功能

    最近实现研究了下五子棋的存档,主要实现是将残局的五子棋棋盘保存到本地文件中,需要读取棋局时能够从本地文件获取,并展示出原有的残局局面. 主要思路 如上图所示,第一个表格是11*11的棋局,可以转换成11行11列的二维数组,1代表黑子,2代表蓝子,转换成第二个表格所示的二维数组.在保存时,考虑到二维数组中0大部分是没有被占用的空间,所以我将二维数组转换成了一个n行3列的稀疏数组,将所占用的空间压缩,保存到本地文件中.其中稀疏数组的第一行row表示11行,col表示11列,val表示除0以外的有效数

  • 通过Java修改游戏存档的实现思路

    目录 前言 一.实现思路 二.项目准备 1. 创建maven工程 2. 导入依赖 三.核心代码 1. 使用的对象 2. 修改关卡信息 3. 修改金币信息 四.代码测试 1. 读取数据文件 2. 修改关卡位置 3. 修改金币数量 4. 退出修改器 5. 输入参数错误情况 五.源码 1. 项目结构 2. 项目代码 总结 前言 植物大战僵尸的数据文件是存储在本地的dat文件当中,修改在本地的dat文件就可以修改到游戏中的数据.之前使用二进制编码工具Hex Editor Neo实现了修改植物大战僵尸的本

  • C1任务01之修改游戏存档的方法

    目录 挑战 一.任务实现工具: 游戏:植物大战僵尸中文版 十六进制编辑器:Hex Editor Neo 二.任务实现过程: 1.修改关卡 2.修改金币 3.修改用户名 4.修改局内文字信息 总结 挑战 有的玩家在玩游戏时,可能并不想⼀关⼀关地慢慢玩,⽽是希望可以直接跳到最后⼀关,或者从⾃⼰指定的关卡开始,⽐如 经典的<植物⼤战僵⼫>:再就是怎么能够「开挂」,得到更多的⾦钱.更⾼的属性.更强的道具,⽐如<三国志>系列.任何游戏都会保存玩家的进度和数据,不管是单机游戏还是⽹络游戏都是如

  • Java跳跃游戏实例真题解决思路详解

    目录 变式题—跳跃游戏 I 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 II 一.题目描述 二.思路 三.代码 变式题—跳跃游戏 I 一.题目描述 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 .数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个下标. 来源:https://leetcode.cn/problems/jump-game/ 示例: 二.思路 本题可以使用贪心法解决,对每个能到达的位置(可覆盖到的位置),计算其每次能覆盖的最大长度,

  • Java实现游戏飞机大战-III的示例代码

    目录 前言 主要设计 功能截图 代码实现 游戏面板类 商店类 总结 前言 <飞机大战-III>是一款融合了街机.竞技等多种元素的经典射击手游.华丽精致的游戏画面,超炫带感的技能特效,超火爆画面让你肾上腺素爆棚,给你带来全方位震撼感受,体验飞行战斗的无限乐趣. 游戏是用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想. 主要需求 基于Java Swing,以飞机大战为原形,以抗日电视剧<亮剑>中的“李云龙”为主题,实现菜单.选关.难度.等级.技能等功能

  • 简单实现java数独游戏

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 打算把javaFx需要的组件装好以后直接用javaFx的,但似乎eclipse的版本不对,安装了也不能用... 数独代码是在之前寒假受命写的,学了一个月java的成果,现在看来有些不足但毕竟是第一个程序,就直接放上来,数独终盘的实现直接用了暴力,时间复杂度有点高,懒得改了直接放代码 终盘实现: import java.util.Random; public class SudokuPuzzleGenerator { pri

  • Java实现飞机航班管理系统的思路详解

    学习Java实现飞机航班管理系统,本文有该系统的功能截图,和数据库设计SQL语句供大家参考 1.飞机航班管理系统背景 本系统模拟飞机航班管理业务开发. 2.飞机航班管理系统技术架构 主要技术 Spring.SpringMVC.Mybatis JSP.JSTL.jQuery.HTML.CSS.JS Mysql bootstrap 开发工具和环境 Eclipse Maven Tomcat 7 JDK 1.8 Mysql 5.6 Win10 操作系统 3.飞机航班管理系统数据库设计 CREATE TA

  • Python修改游戏内存的方法

    目录 前言 游戏的安装 思路 一句话总结 大概的思路 实战 确定修改哪一款游戏的数据 代码 地址的寻找 视频教程 修改数据 代码 效果 完整的源码 所有的软件下载包 前言 大家好,我叫善念.上篇文章我许了一个愿,就是想让大家多多关注我,然后我的粉丝就蹭蹭的涨了好几百,谢谢大家的厚爱.可是我发现粉丝是涨了,三连变少了,谢谢大家这次给我三连,我一定再接再厉.有问题留在评论区,我会一一回复,谢谢大家! 这次要做的是修改一款单机游戏的数据,学过C语言的朋友肯定经常会看到有些老师讲这个案例,就是<植物大战

  • Java实现warcraft java版游戏的示例代码

    目录 前言 主要需求 功能截图 代码实现 启动入口 ModelAttacker类 ModelUnit类 总结 前言 致敬经典的warcraft,<warcraft java版>是一款即时战略题材单机游戏,采用魔兽原味风格和机制.收集资源,建造防御工事,消灭所有敌军. 人类:洛丹伦人类联盟自兽人首次穿过黑暗之门时便告成立.他们坚韧不拔,勇敢无畏,身穿坚甲,手握利刃,英勇迎敌. 兽人:兽人是一个粗犷而坚韧的种族,他们身穿简单的皮毛和带有尖刺的皮甲,以肆意凶狠的战斗风格而闻名. 用java语言实现,

  • java数独游戏完整版分享

    本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下 自己写的数独游戏,共9关,代码如下: 1.DoShudu类用于产生数独数组 import java.util.Random; public class DoShudu { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] cells=newshudu(); //ce

  • Java修改maven的默认jdk版本为1.7的方法

    问题: 1.创建maven项目的时候,jdk版本是1.5版本,而自己安装的是1.7或者1.8版本. 2.每次右键项目名-maven->update project 时候,项目jdk版本变了,变回1.5版本或者其他版本 解决办法: 解决办法一:在项目中的pom.xml指定jdk版本,如下: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <ar

随机推荐