保存游戏数据 - Java

Save Game data - Java

我用一些对象创建了一个基本的游戏。我想让程序的用户能够保存和加载程序的状态。

我研究了多篇文章并阅读了很多重叠的帖子。我对方法的数量以及每种方法的复杂性感到惊讶。

大多数方法都要求我创建要保存的所有对象的框架或骨架,然后逐行加载它们,手动调用每个对象,然后将其转换回其数据类型和 class.

是的,我是编程新手。但我不是要施舍。我要求一个简洁的解释。

我阅读了下面的文章,探索了输出到 XML 文件的想法。

http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/

正如我所说,我是编程新手。我应该和 Java 一起学习 XML 吗?

我的问题如下:

A) 难道我的 IDE 在编译成功后不知道我有多少个对象、它们的数据类型以及它们属于什么 class?

B) 有没有一种方法可以保存所有对象而无需单独指定它们。

c) 我是否夸大了保存一个简单程序的复杂性?

A) 我的 IDE 在编译成功后不知道我有多少个对象,它们的数据类型,以及它们属于什么 class?

加载程序的状态与IDE或编译无关。你启动你的程序,它已经 运行,你想通过从文件加载一些状态来改变它的状态。

如果您使用序列化,您可能会遇到与版本和 classes 不兼容相关的问题 - 例如如果您决定向 class 添加一个新字段,您将需要编写额外的代码才能加载没有该字段的旧状态。所以其他格式,如 XML、JSON 或纯文本(并自己进行转换)可能是更好的主意。

B) 有没有办法在不单独指定的情况下保存所有对象。

好吧,理论上应该可以保存整个 JVM 的状态并在以后加载它。这是一个高级主题,由于 JVM 内部发生的所有聪明的事情(例如即时编译器、垃圾收集和各种即时优化),将会有很多问题。不建议往下走。很可能,您根本无法更改您的代码 - 例如如果您在 GUI 中添加新按钮,加载的版本将不会有它,因为它将加载 classes 的旧版本。因此无法将旧游戏状态加载到新版本的游戏中。

C) 我是否夸大了保存一个简单程序的复杂性?

假设您的游戏 class 调用了 Game,构造函数 Game(String name)(以及一些其他参数)。第一次,您只需调用 new Game("firstGame") 即可创建它。但是现在你想从一些保存的状态创建这个对象。您可以序列化对象然后将其加载回来,结果将是对象本身。或者您可以读取文件以获取该字符串,然后使用该字符串自己调用构造函数。更进一步,有些库可以将对象转换为 JSON 并将 JSON 转换为对象(例如 Jackson 序列化程序)。

Should I be learning XML in tandem with Java?

除非您想学习 XML 或认为 XML 对您的申请来说是一个不错的选择,否则没有理由这样做。不用XML.

序列化的方法有很多

Doesn't my IDE, upon succesful compilation, know how many objects I have, their data type, and what class they belong to?

不,不必。由于分配是在 Java 中动态完成的,因此在某些情况下甚至不可能静态地知道此信息。

Foo[] foos = new Foo[ new Scanner(System.in).nextInt() ];
for(int i = 0; i < foos.length; ++i)
    foos[i] = new Foo();

(创建了多少个Foo?编译器不知道。)

当然,编译器对数据的类型了解很多。

B) Is there a way to save ALL objects without specifying them individually.

也许可以使用 Serializable。基本上,您会将所有程序状态放在一个对象中。当您序列化该单个对象时,其他所有对象都会递归序列化。

class FooState implements Serializable {
    Integer a, b, c; // Integer and String
    String d, e, f;  // also implement Serializable
}

class Foo {
    static FooState allMyState = new FooState();

    public static void main(String[] args) throws IOException {
        try(ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(new File("myFile.data")))) {
            // no need to specify members individually
            oos.writeObject(allMyState);
        }
    }
}

同样的概念可能适用于其他序列化方案,如 JSON、XML 等

您需要仔细考虑放入状态对象的内容,因为其中的所有内容都会被保存。

c) Have I overdramitized the complexity of saving a simple program?

不是真的。如果不仅仅是一些值,保存程序状态可能会很复杂。

有一个class可以保存当前游戏状态

public class Game{
    int coOrdinateX;
    int coOrdinateY;
    int score;
    String[] powersCurrentlyTheUserHad;
    ...
}

当用户退出时,加载此 class 相关数据。因为一旦游戏结束,记忆就会消失,你需要将其保存在一个文件中。

序列化是一种将对象存储到磁盘(本质上是文件)的方法,这样,当您使用库函数反序列化时,您可以直接取回具有当前状态的对象。

检查 http://www.tutorialspoint.com/java/java_serialization.htm了解更多详情