目录

一、实现思路

二、实现过程

1. 创建Java类

2. 实现读取数据方法

3. 实现修改数据方法

3.1. 修改关卡数

3.2. 修改金币数

3.3. 解锁所有模式

3.4 解决输入错误

4. 实现写入数据方法

三、实验测试

四、完整代码


上次任务已经使用Hex Editor Neo工具成功修改游戏存档,具体实现探索和步骤请参考:修改植物大战僵尸游戏存档——跳关并快速实现财富自由,本次任务目的将使用java代码替换工具,实现同样的修改功能。

一、实现思路

  1. 读取数据:修改的user1.dat文件的本地路径已知,使用IO流知识读取数据并存放在程序中。
  2. 修改数据:利用控制台输入,获取用户修改意向,并根据任务的不同采取不同的修改策略。
  3. 写入数据:将修改后的数据重新写入到原文件中。

二、实现过程

1. 创建Java类

按图示创建Java工程。

之后在创建好的Java工程src目录下创建Java类。

输入类名称就可以进行敲代码啦。如下图,定义两个全局变量,分别是可变数组userIndex,用来存放.dat文件下读取出来的数据、.dat所在的本地路径。并设为static类型,可以不用创建类对象就能使用。

2. 实现读取数据方法

有两种读取文件方式,读取文本形式使用Reader,读取二进制数据使用InputStreamFileInputStream是InputStream的一个子类。顾名思义,FileInputStream就是从文件流中读取数据。BufferedInputStream继承于FilterInputStream,提供缓冲输入流功能。缓冲输入流相对于普通输入流的优势是,它提供了一个缓冲数组,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户。由于从缓冲区里读取数据远比直接从物理数据源读取速度快。代码如下:

//    从二进制文件中读取数据(读取到的数据从十六进制数据自动转成十进制)public static void readData(){try{FileInputStream fis= new FileInputStream(fileName);BufferedInputStream br = new BufferedInputStream(fis);int record = -1;while((record = br.read()) != -1){userIndex.add(record);  //将读到的数据添加到可变数组中(全局变量)}System.out.println("从文档中读取第一行数据显示(十进制):");for(int i=0; i<16; i++){System.out.print(userIndex.get(i) + " ");}System.out.println();}catch(Exception e){System.out.print(e.toString());}}

3. 实现修改数据方法

修改数据思路是:主方法中先用Scanner获取用户输入的任务类型,将用户输入数据以参数方式传给changeData方法,在方法内部判断,根据类型采取不同的修改方式。具体措施如下:

3.1. 修改关卡数

3.1.1 用Scanner获取用户输入的关卡数,得到类型为字符串,例"5-1"。

3.1.2 计算修改的十进制数(因为从文件中读取时十六进制自动转换成十进制):先用substring分别获取“-”前面和后面的数字,用变量存取(此时为字符串类型)。用valueof()方法将字符串转为数字,并用前数字*10加后数字。

3.1.3 将1.2的结果替换到表示关卡数的位置:用Hex Editor Neo表示第一行04位置(下标为04)。

 public static void changeData(String type){if (type.equals("1")){System.out.println("请输入您要改的关卡:");Scanner input=new Scanner(System.in);String level=input.nextLine();int firstLevel=Integer.valueOf(level.substring(0,1));int lastLevel=Integer.valueOf(level.substring(2,3));//因为从1-1开始的,5-1只需加41关即可int addLevel=(firstLevel-1)*10+lastLevel;//修改数据:关卡数在第一行04位置,即数组中下标为4userIndex.set(4,addLevel);}

3.2. 修改金币数

3.2.1 用Scanner获取用户输入的关卡数,得到类型为字符串,例"100000000"。

3.2.2 计算:因为植物大战僵尸的内部机制,二进制表示是真实金币数的十分之一,因此需要将2.1结果转换为数字并除以10。文件中以十六进制存储,将除以10后的十进制数据转换成十六进制。例如"100,000,000/10d=989680h"。

3.2.3 存储:在.dat文件中,金币数量是由08,09,0a,0b是存储位,包含8个十六进制位,因此需要将不够位数的在前面补齐。此思路用for循环,循环次数是(8-十六进制数的length)。例如"989680->00989680"。补齐之后以两位为单位,分别按低位->高位的顺序替换08->0b的值。例如"80,96,98,00"分别替换"08,09,0a,0b"位的值。代码如下:

else if (type.equals("2")){System.out.println("请输入您要改的金币数量:");Scanner input=new Scanner(System.in);String money=input.nextLine();//需要加到的金钱int needMoney=Integer.valueOf(money)/10;String HexMoney=Integer.toHexString(needMoney);//在十六进制数前面补0到8位String zero=new String();for (int i=0;i<8-HexMoney.length();i++){zero+="0";}HexMoney=zero+HexMoney;//补全的十六进制//最后两位,对应第一行08位置,进行替换int data08=Integer.valueOf(HexMoney.substring(HexMoney.length()-2));userIndex.set(8, Integer.parseInt(String.valueOf(data08),16));//倒数第3,4位,对应第一行09位置,进行替换int data09=Integer.valueOf(HexMoney.substring(4,6));userIndex.set(9, Integer.parseInt(String.valueOf(data09),16));//正数第3,4位,对应第一行0a位置,进行替换int data0a=Integer.valueOf(HexMoney.substring(2,4));userIndex.set(10, Integer.parseInt(String.valueOf(data0a),16));//正数第1,2位,对应第一行0b位置,进行替换int data0b=Integer.valueOf(HexMoney.substring(0,2));userIndex.set(11, Integer.parseInt(String.valueOf(data0b),16));}

3.3. 解锁所有模式

按照上次的实验,发现只需将0c位的数改为01即可达到目的。代码如下:

else if(type.equals("3")){//修改数据:关卡数在第一行0c位置,即数组中下标为12userIndex.set(12,1);}

3.4 解决输入错误

当输入非1-3,则提示并重新获取信息,利用递归重新进行判断。

else{
//          输入有误,重新接收数字,用递归方法修改数据System.out.println("输入有误,请输入1-3:");Scanner input=new Scanner(System.in);String level=input.nextLine();changeData(level);return;}

4. 实现写入数据方法

利用FileOutStream写入数据,并且为完全替换,append设为false。

//   将数组以二进制写入文件中public static void writeData() throws IOException {FileOutputStream fileWriter=new FileOutputStream(fileName,false);for (int singleData:userIndex) {fileWriter.write(singleData);}//写入文件fileWriter.close();}

三、实验测试

1. 任务一修改关卡数为5-1:

修改关卡数为6-1:

2. 任务二修改金币数量为1024:

修改金币数量为100,000,000:

3. 任务三解锁所有模式:

4. 其他出错检查:

四、完整代码

import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;public class modifyPlantsVsZombies {static ArrayList<Integer> userIndex=new ArrayList<>();static String fileName="C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";public static void main(String[] args) {readData();System.out.println("请输入任务标号(1/2/3):");Scanner input=new Scanner(System.in);String level=input.nextLine();changeData(level);}
//    从二进制文件中读取数据(在输出到控制台时十六进制数据自动转成十进制)public static void readData(){try{FileInputStream fis= new FileInputStream(fileName);BufferedInputStream br = new BufferedInputStream(fis);int record = -1;while((record = br.read()) != -1){userIndex.add(record);}System.out.println("从文档中读取第一行数据显示(十进制):");for(int i=0; i<16; i++){System.out.print(userIndex.get(i) + " ");}System.out.println();}catch(Exception e){System.out.print(e.toString());}}
//    判断任务,并根据用户输入意向进行修改public static void changeData(String type){if (type.equals("1")){System.out.println("请输入您要改的关卡:");Scanner input=new Scanner(System.in);String level=input.nextLine();int firstLevel=Integer.valueOf(level.substring(0,1));int lastLevel=Integer.valueOf(level.substring(2,3));//因为从1-1开始的,5-1只需加41关即可int addLevel=(firstLevel-1)*10+lastLevel;//修改数据:关卡数在第一行04位置,即数组中下标为4userIndex.set(4,addLevel);}else if (type.equals("2")){System.out.println("请输入您要改的金币数量:");Scanner input=new Scanner(System.in);String money=input.nextLine();//需要加到的金钱int needMoney=Integer.valueOf(money)/10;String HexMoney=Integer.toHexString(needMoney);//在十六进制数前面补0到8位String zero=new String();for (int i=0;i<8-HexMoney.length();i++){zero+="0";}HexMoney=zero+HexMoney;//补全的十六进制//最后两位,对应第一行08位置,进行替换int data08=Integer.valueOf(HexMoney.substring(HexMoney.length()-2));userIndex.set(8, Integer.parseInt(String.valueOf(data08),16));//倒数第3,4位,对应第一行09位置,进行替换int data09=Integer.valueOf(HexMoney.substring(4,6));userIndex.set(9, Integer.parseInt(String.valueOf(data09),16));//正数第3,4位,对应第一行0a位置,进行替换int data0a=Integer.valueOf(HexMoney.substring(2,4));userIndex.set(10, Integer.parseInt(String.valueOf(data0a),16));//正数第1,2位,对应第一行0b位置,进行替换int data0b=Integer.valueOf(HexMoney.substring(0,2));userIndex.set(11, Integer.parseInt(String.valueOf(data0b),16));}else if(type.equals("3")){//修改数据:关卡数在第一行0c位置,即数组中下标为12userIndex.set(12,1);}else{
//          输入有误,重新接收数字,用递归方法修改数据System.out.println("输入有误,请输入1-3:");Scanner input=new Scanner(System.in);String level=input.nextLine();changeData(level);return;}//修改之后输出第一行System.out.println("修改后第一行数据显示(十进制):");for(int i=0; i<16; i++){System.out.print(userIndex.get(i) + " ");}//将数组以二进制写入文件中try {writeData();} catch (IOException e) {e.printStackTrace();}}
//   将数组以二进制写入文件中public static void writeData() throws IOException {FileOutputStream fileWriter=new FileOutputStream(fileName,false);for (int singleData:userIndex) {fileWriter.write(singleData);}//写入文件fileWriter.close();}
}

心得

上次的手动修改使我了解到游戏中二进制的储存机制,并接触到了曾经认为遥不可及的事情。这次换代码实现,计算效率一下子提高了好多,只要编译成功,下次不需要再进行手动计算,就可以达到"一次编程,随时运行"的效果。另外,实现的过程也是让人感到乐在其中,首先将整体思路写出来,按照每步想实现的功能去查资料并实现。从IO流的应用到二进制的处理,再到字符串与数字的相互转换,这些知识点都在我心中有了更深的印记。感谢CSDN给我这次实训的机会,让我对Java又多了些热爱。劳伦斯曾说过“成功的秘诀,是在养成迅速去做的习惯,要趁着潮水涨得最高的一刹那,不但没有阻力,而且能帮助你迅速地成功”,对语言的真正掌握也只有不断地探索和实践。加油吧,少年!

修改植物大战僵尸游戏存档(Java实现版)相关推荐

  1. 修改植物大战僵尸游戏存档,二进制绘制字符或图形

    目录 修改植物大战僵尸游戏存档 安装游戏注册用户 找到用户的游戏存档二进制文件并修改 二进制绘制字符或图形 修改植物大战僵尸游戏存档 植物大战僵尸版本:植物大战僵尸2010年度版 操作系统:Windo ...

  2. cheat engin修改植物大战僵尸游戏

                 cheat engin修改植物大战僵尸游戏 修改阳光 思路:首先载入进程,如图黑圈勾画处 然后将初始阳光写入数值处并搜索,如下图 此时会出现许多地址,我们无法确定阳光的所在地 ...

  3. C1任务01-信息编码之修改植物大战僵尸数据存档

    任务要求: ⾸先,修改<植物⼤战僵⼫>的存档⽂件,能跳到指定关卡,例如「5-1」 其次,修改<植物⼤战僵⼫>的存档⽂件,让游戏账户有指定数量的⾦币 然后,修改<植物⼤战僵 ...

  4. 植物大战僵尸游戏道具或参数的属性-植物大战僵尸免费版提供下载

    植物大战僵尸中文版修改器是一款专用于修改植物大战僵尸游戏道具或参数的属性修改工具.使用植物大战僵尸中文版修改器你可以修改不同版本的植物大战僵尸游戏,还支持修改金钱.阳光.肥料(还有智慧树的肥料).杀虫 ...

  5. 植物大战僵尸用户存档修改(CSDN任务1,20210418)

    植物大战僵尸用户存档修改 任务目标 目标1:修改<植物⼤战僵⼫>的存档⽂件,能跳到指定关卡,例如「5-1」 目标2:修改<植物⼤战僵⼫>的存档⽂件,让游戏账户有指定数量的⾦币 ...

  6. java设计建议植物大战僵尸_基于Java的游戏设计之植物大战僵尸

    植物大战僵尸这款游戏相信大家或多或少都玩过,那么大家有没有想过自己尝试着做一下植物大战僵尸的游戏设计呢.本文将基于Java语言为大家展示如何开发出植物大战僵尸游戏的简易版本,主要内容包括规则.对象.功 ...

  7. 修改植物大战僵尸的游戏数据

    修改植物大战僵尸的游戏数据 说明 1.掌握的知识 1.了解二进制.十六进制对于计算机的意义 2.掌握二/七/八十/十二/十六等多种数据进之间的转换 3.掌握如何在windows及linux中修改并保存 ...

  8. 用Java实现一个简易的植物大战僵尸游戏

    今天给大家分享一个简易的植物大战僵尸游戏,用Java编写,还是挺好玩的. 一.设计思路 1.植物大战僵尸运用Java基础实现,通过滚轮上选择植物,随机生成各种类型僵尸,以及植物. 2.玩家可以安放各种 ...

  9. java植物大战僵尸 论文_java实现植物大战僵尸游戏

    植物卡片框 */ public class PlantsBar implements GuiConstnat { // 卡片格子数量 private int plantSum; // 太阳数量和卡片选 ...

  10. js HTML5 网页版植物大战僵尸游戏

    js HTML5 网页版植物大战僵尸游戏 源于:http://www.huiyi8.com/moban/ 植物大战僵尸Javascript版 HTML5模版 body{-moz-user-select ...

最新文章

  1. three.js(六) 地形法向量生成
  2. 【深度学习】生动分析半监督学习与负相关学习算法
  3. Numpy.array矩阵百分制化(比例化)
  4. GCC如何编译内嵌汇编代码
  5. XCTF-高手进阶区:NaNNaNNaNNaN-Batman
  6. centos7 zookeeper3.5.6单点部署
  7. linux文件系统的设计,基于Linux的文件系统设计.doc
  8. form 窗体增加边框_C#控件美化之路(13):美化Form窗口(上)
  9. 作者:冯仕政(1974-),男,中国人民大学社会与人口学院教授、副院长。
  10. python mpi多线程_使用 MPI for Python 并行化遗传算法
  11. 未经专业销密的计算机设备,DOC1-题
  12. centos6.5 redis3 开机自动启动命令设置
  13. obd协议 混动车_最新人工智能驾考系统OBD信号采集模块
  14. 全平台视频转GIF软件对比与推荐(iOS/安卓/Windows/Mac)
  15. Unity Bone weights do not match bones.
  16. 国密SSL证书正式上线,知道创宇云防御助力金融和重要领域完成国密升级改造...
  17. 计算机软硬件问题及解决方法(经验篇)
  18. 输入直角三角形的两个直角边的长度 a、b,求斜边 c 的长度。
  19. 电商3.0 属于粉丝经济的时代!
  20. 通信原理chapter2总结(内含多径效应和多普勒效应MATLAB仿真)

热门文章

  1. PHP图片尺寸调整(全填充,没有黑底)
  2. 横版过关2d游戏c语言代码,如何制作一个横版格斗过关游戏(2) Cocos2d-x 2.0.4
  3. 总结知识,提高认知--牛腩总结
  4. 关于PHP签名中的容易犯错问题记录
  5. Axure 8 网页滚动效果+APP上下垂直拖动效果
  6. css入门1 css简介
  7. 手机,电脑都能用的,整人,恶搞代码连接,“你不会百度一下吗”教你用百度
  8. vue自定义组件,ElementUi表单校验v-model不能即时生效的解决方法
  9. 访问服务器显示我被拒绝,连接到服务器localhost:8080被拒绝(The connection to the server localhost:8080 was refused)...
  10. 解决ERROR: text file '***' contains disallowed UTF-8 whitespace character(s)