【问题标题】:Save Game data - Java保存游戏数据 - Java
【发布时间】:2015-05-10 23:33:34
【问题描述】:

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

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

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

是的,我是编程新手。但我不是要讲义。我要求一个简明的解释。

我在探索输出到 XML 文件的想法时阅读了以下文章。

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

正如我所说,我是编程新手。我应该在学习 XML 的同时学习 Java 吗?

我的问题如下:

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

B) 有没有办法保存所有对象而不单独指定它们。

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

【问题讨论】:

  • 保存并加载程序?保存对象?目前还不清楚你在问什么。是否要将对象保存到文件中?
  • 或许可以看看Serialization
  • 抱歉含糊不清。我想保存游戏。我希望用户能够保存游戏,离开一天,回来,并在他们开始的地方加载他们的游戏,所有对象都完好无损。
  • 您可以使用 XML 或 JSON 将数据序列化为文本。您也可以使用Serializable 接口和ObjectOutputStream 到字节码(?),但JSON 更可靠。如果您有一个集体 GameModel 类,其中包含与当前游戏状态相关的所有现有实体,那么您可以序列化该类,而所有其他类将递归序列化。
  • 感谢所有 cmets。我想答案是,它绝对像我想象的那样压倒一切。听起来我要去看一些关于如何将游戏状态转换为 JSON 的 youtube

标签: java save


【解决方案1】:

我应该在学习 XML 的同时学习 Java 吗?

除非您想学习 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();

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

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

B) 有没有办法保存所有对象而不单独指定它们。

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

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】:

    有一个可以保存游戏当前状态的类。

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

    当用户退出时,用相关数据加载这个类。一旦游戏终止,内存就会消失,您需要将其保存在文件中。

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      B) 有没有办法保存所有对象而不单独指定它们。

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多