植物大战僵尸修改器(仅仅是关卡 Java实现)
1、Java写一个修改器 通过翻阅别人博文发现 我发现我的上次使用Java写的半成品(也不算 )的设计理念本身就有问题 首先我们已经通过hex 编辑器 已经知道了修改的位置 而程序的实现是要求简单高效 我上次 竟然想通过比较两个文件的不同来确定操作位置并修改,虽然并没有成功。 但如果成功了 这样的操作无疑是费时且效率低下的 ,此次实训使我认识了: 程序设计要偏向于高效率,低成本 才能使你的开发更快乐
2、前面我们已经通过hexeditor 16进制编辑器的方式来修改植物大战僵尸 ,然后Java已经学到了io流 可以对文件进行一些基本的操作 所以想到了可以用Java写一个简易版本的植物大战僵尸修改器
3、实现思路:首先我们利用io流读取文件的操作 将数据读取到集合中 我们采用了 ArrayList 集合 因为它可以按照顺序来存放元素 并且可以存放相同值 能够很好的修改数据
第一步 、读取数据文件
io流的知识 我以前的博客虽然写的不好但是还能将就看~~~
package Tool;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ReadDataFile {
public static List<Integer> arrayList = new ArrayList<>();//数据保存在这一个集合中 共享这个集合 增加了修改的方便性
private static String path = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
public static void acquireGameData(){
FileInputStream in = null;
try {
in = new FileInputStream(path);
int i = 0;
while ((i = in.read()) != -1 ){
arrayList.add(i);//存取数据变量。
}
System.out.println(arrayList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//我们首先测试一下这样的代码
//以下为输出结果
第二步 修改集合元素
之后我们只要修改集合中的元素 再将集合中的元素写入植物大战僵尸的user1.dat 文件中就可以完成这个修改操作 我们测试一下修改集合元素的操作
package Tool;
import java.util.List;
import java.util.Scanner;
public class ChangeData {
int checkpointInformation;
//已经知道了关卡的修改位置 只要修改对应位置的数值即可
public void change(){
System.out.println("请输入要修改关卡 10关1大关 例如 31 代表第 2 - 1 关");
Scanner sc = new Scanner(System.in);
checkpointInformation = sc.nextInt();
ReadDataFile.arrayList.set(4,checkpointInformation);
}
}
我们发现已经修改成功了
第三步 导入数据到数据文件
首先我们试一下 如果将集合现在直接写入数据文件会发生什么情况。
出现了类转换异常
package Tool;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
public class ChangeData {
int checkpointInformation;
//已经知道了关卡的修改位置 只要修改对应位置的数值即可
public void change() throws FileNotFoundException {
System.out.println("请输入要修改关卡 10关1大关 例如 31 代表第 2 - 1 关");
Scanner sc = new Scanner(System.in);
checkpointInformation = sc.nextInt();
ReadDataFile.arrayList.set(4,checkpointInformation);
FileOutputStream fileOutputStream = new FileOutputStream(ReadDataFile.path);
ListIterator it = ReadDataFile.arrayList.listIterator();
while (it.hasNext()){
try {
fileOutputStream.write((byte)it.next());
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//这是出现异常的代码
然而当我再次运行时
我的数据文件已经被损坏了
我们将原来文件删除 重新运行一下游戏 生成新的数据文件 改变我们的思路试试
使用包装类的方法是否可行?
我们将语句注释掉换为下面的套娃转换法
// fileOutputStream.write((Byte)it.next());
fileOutputStream.write(Integer.parseInt(Integer.toHexString((Integer) it.next())));
好~ ~ 又报错了 看来这样不可行
byte[] b = Integer.toHexString(it.next()).getBytes();
fileOutputStream.write(b);
// 修改成功
但又出现了这样的问题、没有拼接的结果 有踩坑了 应该拼接。
拼接之后16进制文件可以正常打开了但是关卡并没有修改成功。
我想应该是拼接在源文件后面了 我又加了个文件清除的操作。
他也是终于没报错 我们看一下结果
永远在踩坑的过程中。。
最后翻阅博客找到了一个DataOutPutStreatm流 是我以前没有接触过的 代码放在下面了
这里只做了关卡的修改 其它方法类似。。。
Java代码 没有加判断
TOOL包下
package Tool;
import java.io.*;
import java.util.ListIterator;
import java.util.Scanner;
public class ChangeData {
int checkpointInformation;
//已经知道了关卡的修改位置 只要修改对应位置的数值即可
public void change() throws FileNotFoundException {
System.out.println("请输入要修改关卡 10关1大关 例如 31 代表第 4 - 1 关");
Scanner sc = new Scanner(System.in);
checkpointInformation = sc.nextInt();
if (checkpointInformation > 0 && checkpointInformation <= 40 )
ReadDataFile.arrayList.set(4, checkpointInformation);
DataOutputStream outputStream = null;
FileClear.clear();
ListIterator<Integer> it = ReadDataFile.arrayList.listIterator();
try {// outputStream = new FileOutputStream(ReadDataFile.path);
// fileOutputStream.write((Byte)it.next());
// byte[] b = Integer.toHexString(it.next()).getBytes();
// fileOutputStream.write(b);
outputStream = new DataOutputStream(new FileOutputStream(ReadDataFile.path));
for (Integer integer : ReadDataFile.arrayList) {
outputStream.write(integer);
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("修改关卡成功!");
}
}
package Tool;
import java.io.*;
public class FileClear {
public static void clear(){
FileWriter out = null;
FileInputStream in = null;
try {
in = new FileInputStream(ReadDataFile.path);
out = new FileWriter(ReadDataFile.path);
int i = 0 ;
while ((i = in.read()) != -1){
out.write("");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package Tool;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ReadDataFile {
public static List<Integer> arrayList = new ArrayList<>();//数据保存在这一个集合中 共享这个集合 增加了修改的方便性
public static String path = "C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
public static void acquireGameData(){
FileInputStream in = null;
try {
in = new FileInputStream(path);
int i = 0;
while ((i = in.read()) != -1 ){
arrayList.add(i);//存取数据变量。
}
System.out.println(arrayList);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
小测一下
package Test;
import Tool.ChangeData;
import Tool.ReadDataFile;
import java.io.FileNotFoundException;
public class Test1 {
public static void main(String[] args) throws FileNotFoundException {
ReadDataFile.acquireGameData();
ChangeData c = new ChangeData();
c.change();
}
}
此时进入游戏
我们发现已经修改成功为相应的关卡
在测试一下