简体   繁体   中英

How can I save and load a level file with abstract objects?

I'm trying to make a level editor that provides a save functionality like mario maker - the user can create a level and save the level data. How is this usually done? Specifically what I'm struggling with is my level contains a list of Enemies (an abstract class). When I write to a file I can write the json representation of the concrete enemy classes, but when I read from the file, I'd need to know what concrete class it is in order to reconstruct it into that specific class. That seems like a pain - I'd have to manually add some code to write out what class type the enemy is when it gets saved and also add code to read what class type and create an instance of that class when read. I'm afraid of maintaining that for every new Enemy that I create. So my main question is how can I most easily read a list of concrete Enemies into a list of abstract Enemies? It seems like some knowledge about the class is required on save/load.

Also, is saving as JSON the way to go here or is serialization better? Does it matter?

Since your going to be creating concrete classes when the program starts up, you will need to know the actual class of each one. There are a bunch of ways you could do this. To do something easy, you could add a getLabel() method to each concrete class and use that as a switch to figure out the correct concrete class.

// 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);

I really like using JSON libraries functionality to parse my JSON into a POJO. However, doing the above would actually require double parsing - 1) Parse into some generic structure (like a Map or JsonNode), check the label and then 2) Parse into POJO.

Another thing you could do is prepend a "Magic Number" before each JSON string to let you know which type it is. Then you don't have to double parse 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);
}

As far as if JSON is the right serialization to use, it's up to you. The things that are nice about it is it's human readable and editable. There are other serialization technologies if performance or disk usage are more important to you. For something like this, JSON seems fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM