【问题标题】:LibGDX - Loading Objectmap, which is saved within another ObjectmapLibGDX - 加载 Objectmap,它保存在另一个 Objectmap 中
【发布时间】:2015-03-19 23:29:01
【问题描述】:

我正在使用带有 LibGDX 的 Eclipse,我想为我的游戏创建保存文件。实际上,我能够创建一个简单的 JSON 文件并将其读出。对于单个对象,这可以正常工作,但在我的游戏中,对象包含其他对象,这些对象包含其他对象,依此类推。每个对象都有多个值,例如 xpos、ypos、health ... 对于测试,我使用了新类。我有类 SaveDataChunk,它包含一个 int、一个字符串和一个来自类“项目”的对象。项目本身包含 3 个整数,va、vb 和 vc。为了从 JSON 文件创建和加载,我使用了来自 Toxsick Producctions 的代码 我对这段代码做了一些修改:

public class SaveManager {

private boolean encoded;
public FileHandle file = Gdx.files.absolute(Gdx.files.getLocalStoragePath().concat("bin/world1.json"));
private Save save;

public SaveManager(boolean encoded){
    this.encoded = encoded;
    save = getSave();
}

public static class Save{
    public ObjectMap<String, Object> data = new ObjectMap<String, Object>();
}

private Save getSave(){
    Save lsave = new Save();

    if(file.exists()){
        Json json = new Json();
        if(encoded){
            lsave = json.fromJson(Save.class, Base64Coder.decodeString(file.readString()));
        }else{
            lsave = json.fromJson(Save.class, file.readString());
        }
    }else{
        saveToJson(lsave);
    }
    return lsave;
}

public void saveToJson(Object pObj){
    Json json = new Json();
    json.setOutputType(OutputType.json);
    if(encoded){
        file.writeString(Base64Coder.encodeString(json.prettyPrint(pObj)), false);
    }else{
        file.writeString(json.prettyPrint(pObj), false);
    }
}

@SuppressWarnings("unchecked")
public  <T> T loadDataValue(String key, Class type){
    save = getSave();
    if(save.data.containsKey(key)){
        return (T) save.data.get(key);
    }else{
        return null;   //this if() avoids and exception, but check for null on load.
    }
}

@SuppressWarnings("unchecked")
public  <T> T loadDataValue(String key, Class type, ObjectMap<String, Object> jsonfile){
    if(jsonfile.containsKey(key)){
        return (T) jsonfile.get(key);
    }else{
        return null;   //this if() avoids and exception, but check for null on load.
    }
}

public void saveDataValue(String key, Object object){
    save = getSave();
    save.data.put(key, object);
    saveToJson(save); //Saves current save immediatly.
}

public ObjectMap<String, Object> getAllData(){
    save = getSave();
    return save.data;
}

public boolean isEncoded(){
    return encoded;
}

public void setFileName(String s){
    file = Gdx.files.absolute(Gdx.files.getLocalStoragePath().concat("bin/" + s + ".json"));
}

}

我的保存方法如下所示:

private void saveData() { //TODO
    SaveDataChunk sdc = new SaveDataChunk();
    sdc.setS("hallo! random number: " + random(7, 13));
    sdc.setA((int)random(1, 3));
    saveManager.saveDataValue("AllTheData", sdc.getJsonData());
}

SaveDataChunk 的方法:

public ObjectMap<String, Object> getJsonData(){
    ObjectMap<String, Object> mydata = new ObjectMap<String, Object>();
    mydata.put("a", a);
    mydata.put("s", s);
    mydata.put("item", item.getJsonData());
    return mydata;
}

物品的方法:

public ObjectMap<String, Object> getJsonData(){
    ObjectMap<String, Object> mydata = new ObjectMap<String, Object>();
    mydata.put("va", va);
    mydata.put("vb", vb);
    mydata.put("vc", vc);
    return mydata;
}

加载方法:

private void loadData() { //TODO
    ObjectMap<String, Object> localdata  = saveManager.loadDataValue("AllTheData", null);
    Array<String> keys = localdata.keys().toArray();
}

一个可能的 Json 文件如下所示:

{
  "data": {
    "AllTheData": {
      "class": "com.badlogic.gdx.utils.ObjectMap",
      "a": {
        "class": "java.lang.Integer",
        "value": 2
      },
      "item": {
        "va": {
          "class": "java.lang.Integer",
          "value": 1
        },
        "vb": {
          "class": "java.lang.Integer",
          "value": 2
        },
        "vc": {
          "class": "java.lang.Integer",
          "value": 3
        }
      },
      "s": {
        "class": "java.lang.String",
        "value": "hallo! random number: 9.828029"
      }
    }
  }
}

实际问题: 我可以加载一个 Objectmap (localdata) 并显示所有键 (a,s,item)。我也可以只保存项目的数据:

saveManager.saveDataValue("AllTheData", sdc.getItem().getJsonData());

这行得通,我得到一个列表,其中仅包含该项目的 3 个整数。这正是我想从 sdc 加载的列表。 我正在使用“localdata.get(keys.get(0))”来获取 objectmap 的一个项目,它适用于 int (a) 和 String (s)。我也可以获得该项目,但我想访问项目中的整数,所以我想要第一个中的对象映射,这就是我失败的地方。我尝试了不同类型的投射,但总是出错,因为无法投射。

有人知道如何解决此问题,或者您知道加载此类 jason 文件的另一种方法吗?

【问题讨论】:

    标签: java json libgdx


    【解决方案1】:

    我今天正在处理这个完全相同的问题,我使用的解决方法是像这样包装 ObjectMap。

    class ObjectMapWrapper{
        public ObjectMap<String, Object> data = new ObjectMap<String, Object>();
    }
    

    然后你可以做类似的事情

    public void save( ObjectMap<String, Object> saveMap ){
        ObjectMapWrapper wrapper = new ObjectMapWrapper();
        ObjectMap<String, Object> mydata = wrapper.data;
        mydata.put("va", va);
        mydata.put("vb", vb);
        mydata.put("vc", vc);
    
        saveMap.put( "mydata", wrapper );
    }
    

    或者你想怎么做。当您从 json 恢复时,ObjectMapWrapper 类将反序列化和强制转换。

    ObjectMapWrapper wrapper = (ObjectMapWrapper)saveMap.get("mydata");
    

    我确信可能有一种正确的 json 方法可以将 ObjectMap 实际存储在 ObjectMap 中,而无需使用上述技巧,但我还没有深入研究 json doco。

    【讨论】:

      【解决方案2】:

      也许有更好的方法?但这就是我滚动的方式......

      {
        "data": {
          "AllTheData": {
            "class": "com.badlogic.gdx.utils.ObjectMap",
            "a": {
              "class": "java.lang.Integer",
              "value": 2
            },
            "item": {
              "va": {
                "class": "java.lang.Integer",
                "value": 1
              },
              "vb": {
                "class": "java.lang.Integer",
                "value": 2
              },
              "vc": {
                "class": "java.lang.Integer",
                "value": 3
              }
            },
            "s": {
              "class": "java.lang.String",
              "value": "hallo! random number: 9.828029"
            }
          }
        }
      }
      

      ...

      FileHandle file = Gdx.files.absolute(Gdx.files.getLocalStoragePath().concat("bin/world1.json"));
      
      JsonValue jsonValue = new JsonReader().parse(file /*Base64Coder.decodeString(file.readString())*/);
      JsonValue data = jsonValue.get("data");
      
      JsonValue allTheData = data.get("AllTheData");
      
      int a = allTheData.get("a").get("value").asInt();
      
      int va = allTheData.get("item").get("va").get("value").asInt();
      int vb = allTheData.get("item").get("vb").get("value").asInt();
      int vc = allTheData.get("item").get("vc").get("value").asInt();
      
      String s = allTheData.get("s").get("value").asString();
      

      【讨论】:

        猜你喜欢
        • 2017-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-28
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多