保存游戏数据 - Java

7

我已经创建了一个简单的游戏,并且有几个对象。 我希望让程序用户能够保存和加载程序状态。

我查阅了多篇文章并阅读了很多overstack帖子。 我惊讶于这么多方法的数量以及每种方法的复杂性。

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

是的,我是新手程序员。 但我不是要什么好处。 我要求一个简明扼要的解释。

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

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

正如我所说,我是新手程序员。 我应该同时学习Java和XML吗?

我的问题如下:

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

B)有没有一种方法可以保存所有对象而不必逐个指定它们?

C)我是否过分强调了保存一个简单程序的复杂性?


保存和加载程序?保存对象?不清楚你在问什么。你想把一个对象保存到文件中吗? - Jaroslaw Pawlak
也许可以看一下序列化 - gtgaxiola
抱歉造成歧义。我想要保存游戏进度。我希望用户能够保存游戏进度,离开一天后回来,然后在原地重新加载他们的游戏,所有物品都完好无损。 - Joseph Erickson
1
感谢所有的评论。我想答案是,它绝对像我想象的那样令人不知所措。听起来我要看一些关于如何将游戏状态转换为JSON的YouTube视频了。 - Joseph Erickson
我没有使用过JSONBeans,但如果您想要一个简单的Bean->Object转换,我真的可以推荐XStream。您可以在一行代码中保存状态。并不是说这是最好的解决方案,但是是一个合理的选择。 - Magnilex
显示剩余8条评论
3个回答

6

我应该和Java一起学习XML吗?

除非你想学习XML或者认为XML是你的应用程序的好选择,否则没有必要同时学习。在没有使用XML的情况下,有很多序列化的方式。

我的IDE在编译成功后不会知道我有多少对象、它们的数据类型以及它们属于哪个类吗?

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

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

有多少个Foo被创建了?编译器不知道。

当然,编译器对数据类型非常了解。

B) 是否有一种方法可以保存所有对象而不需要逐个指定它们。

也许可以使用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)我是否夸大了保存简单程序的复杂性?

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


2

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

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

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

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

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

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

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


0
拥有一个能够保存游戏当前状态的类。
public class Game{
    int coOrdinateX;
    int coOrdinateY;
    int score;
    String[] powersCurrentlyTheUserHad;
    ...
}

每当用户退出时,使用相关数据加载此类。由于一旦游戏终止,内存就会消失,因此需要将其保存在文件中。
序列化是一种将对象存储到磁盘(基本上是文件)的方法,这样,当您使用库函数进行反序列化时,您可以直接获得具有当前状态的对象。
请查看http://www.tutorialspoint.com/java/java_serialization.htm以获取更多详细信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接