【问题标题】:How can I save and load a level file with abstract objects?如何保存和加载带有抽象对象的关卡文件?
【发布时间】:2015-12-03 00:49:30
【问题描述】:

我正在尝试制作一个提供保存功能的关卡编辑器,例如 mario maker - 用户可以创建关卡并保存关卡数据。这通常是怎么做的?具体来说,我正在努力解决的是我的关卡包含一个敌人列表(一个抽象类)。当我写入文件时,我可以编写具体敌人类的 json 表示,但是当我从文件中读取时,我需要知道它是什么具体类,以便将其重构为特定类。这似乎很痛苦 - 我必须手动添加一些代码来写出敌人在保存时是什么类类型,还添加代码来读取什么类类型并在读取时创建该类的实例。我害怕为我创造的每一个新敌人都维护它。所以我的主要问题是如何最容易地将具体敌人列表读入抽象敌人列表中?保存/加载时似乎需要一些有关该类的知识。

另外,是保存为 JSON 还是序列化更好?有关系吗?

【问题讨论】:

    标签: java json serialization libgdx


    【解决方案1】:

    由于您将在程序启动时创建具体的类,因此您需要知道每个类的实际类。有很多方法可以做到这一点。为了做一些简单的事情,您可以为每个具体类添加一个getLabel() 方法,并将其用作确定正确具体类的开关。

    // Using jackson-databind
    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = mapper.readValue(json, JsonNode.class);
    
    Enemy enemy = null;
    if (GOOMBA_LABEL.equals(node.get("label").asText()))
       enemy = mapper.readValue(json, Goomba.class);
    

    我真的很喜欢使用 JSON 库功能将我的 JSON 解析为 POJO。但是,执行上述操作实际上需要双重解析 - 1) 解析为一些通用结构(如 Map 或 JsonNode),检查标签,然后 2) 解析为 POJO。

    您可以做的另一件事是在每个 JSON 字符串之前添加一个“幻数”,让您知道它是哪种类型。这样你就不必双重解析 JSON。

    DataInput input = new DataInputStream(fileInputStream);
    int magic = input.readInt();
    
    Enemy enemy = null;
    if (GOOMBA_MAGIC == magic) {
       String json = input.readUTF();
       enemy = mapper.readValue(json, Goomba.class);
    }
    

    至于 JSON 是否是正确使用的序列化,这取决于您。它的好处是它是人类可读和可编辑的。如果性能或磁盘使用对您来说更重要,还有其他序列化技术。对于这样的事情,JSON 似乎很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      相关资源
      最近更新 更多