Libgdx存储游戏物品

时间:2016-12-13 03:31:13

标签: java json libgdx

我理解JSON的基础知识,但我更加好奇的是如何使用它来实现我需要完成的工作。

让我解释一下,我想将我的所有游戏ITEMS存储在一个JSON文件中,这样它就会保存项目名称“WHAPON OF WHATEVER”,然后得到buyPricesellPrice,{的统计信息。 {1}},minDamage等......

如何用JSON做这样的事情?

2 个答案:

答案 0 :(得分:2)

我使用JSON文件存储游戏的参考数据,好消息是libGDX comes with a JSON parser可以在几行代码中使用,如下所示。首先,您要定义一个可以序列化的类:

public class Item {
    private String name;
    private String description;
    private String image;
    private float baseValue;
    private int baseQuantity;
    private float rarityIndex;
    private Array<String> tags = new Array<>();

    public Item() { }
    // More Constructors/Getters/Setters/Helper Methods, etc.
}

然后你需要创建一个Json对象来读取文件(或写入文件):

Json json = new Json();
types = json.fromJson(Array.class, Item.class, Gdx.files.internal(FILE_NAME) );

这是我游戏中的实际代码。有几点需要指出:

  • 类型的类型为Array<Item>,使用的是libGDX的Array类。这意味着我们真的告诉libGDX将它解释为一个Array对象而不是一个正确的数组,但我真的很喜欢libGDX的数据结构,所以这对我来说不是问题。
  • 使用GWT时并不支持所有Java数据结构(特别是在使用时) 要在com.badlogic.gdx.utils下使用libGDX实现的地图。这是因为GWT的性质对反思有某些限制。
  • 请注意,当我们致电Json#fromJson()时,我们必须传递Array.classItem.class,以便它知道返回Array<Item>个对象。

现在我们如何构建JSON?解决这个问题的最简单方法是创建一个小型测试程序,生成一些对象,然后将它们写入文件或stdout:

System.out.println(json.prettyPrint(types));

这适用于简单的结构(可能只是你需要的,但是查看JSON并了解它的结构可能会有所帮助。回到前面的例子,JSON文件如下所示:

[
  {
    "class": "tech.otter.merchant.data.Item",
    "name": "Bindookian Spices",
    "description": "Sweet, yet spicy.",
    "image": "goods0",
    "baseValue": 150,
    "baseQuantity": 1000,
    "rarityIndex": 0.25,
    "tags": [
      "category-food",
      "category-luxury"
    ]
  },
  {
    "class": "tech.otter.merchant.data.Item",
    "name": "Italiluminum Rods",
    "description": "Shiny.",
    "image": "goods1",
    "baseValue": 400,
    "baseQuantity": 1000,
    "rarityIndex": 0.25,
    "tags": [
      "category-valuable",
      "category-material"
    ]
  }
  // More items in the real file
]

你会发现这是从JSON到我们班级的非常简单的映射。一些注意事项:

  • 请注意文件如何以方括号[]开头 - 这告诉我们数据存储为JSON数组,即使我们在代码中将其转换为Array类。
  • 我的基础是libGDX输出,因此在每个Item结构中都有一个“class”标签。我不认为这是绝对必要的,但是当你有这样的嵌套数据结构时它不会受到伤害。
  • 注意“标签”是如何存储为数组的,而libGDX不需要知道它是一个Array对象。

总之,libGDX库附带了自己的JSON解析器(如果你有特殊的序列化需求,它可以是further customized),但权衡是你必须在某些情况下使用libGDX数据结构(特别是使用GWT时。)

答案 1 :(得分:0)

我使用Gson来实现类似的目标。

首先将此添加到你的核心(你选择的项目)build.gradle

compile group: 'com.google.code.gson', name: 'gson', version: '2.6.2'

获取或分配首选项(libgdx以交叉平台的方式保存用户数据):

//It is advised to use you app package name + some name for these specific prefs to avoid collision with other apps using the same name. Since some plaform uses this name for a flat file name.
Preferences preferences = Gdx.app.getPreferences("nl.example.whatever");

加载/保存您的值:

Gson gson = new Gson();

Item getItem(String id)
{
    String data = preferences.getString(id,null);
    if(data == null)
        return null;

    Item item = gson.fromJson(preferences.getString(id),Item.class);
}

void saveItems(List<Item> items)
{
    for(Item item : items)
    {
        preferences.putString(item.getId(),gson.toJson(item));
    }
    //save from cache to file. Try to minimize flush calls.
    preferences.flush();
}

LibGDX wiki on preferences

这是假设您的数据是动态的,而不仅仅是描述等。在这种情况下,我推荐以下内容(我为成就创建了一次):

添加到build.gradle:

compile 'org.json:json:20151123'

Achievement.ID是一个枚举

void loadAchievements()
{
    JSONArray array;
    try
    {
        String json = Globals.loadResourceToString("achievements.json");
        array = new JSONArray(json);
    }
    catch (Exception ex)
    {
        throw new RuntimeException("could not load achievements");
    }

    int nr_of_achievements = array.length();
    for (int i = 0; i < nr_of_achievements; i++)
    {
        JSONObject obj = array.getJSONObject(i);
        if (obj.getString("id") == null)
            throw new RuntimeException("achievement does not exist");
        Achievement.ID id = Achievement.ID.valueOf(obj.getString("id"));
        achievementList.put(id, new Achievement(id, obj));
    }
}


public static String loadResourceToString(String resourceName) throws Exception
{
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    InputStream resourceStream = loader.getResourceAsStream(resourceName);
    StringBuilder sb = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(resourceStream, "UTF-8"));
    for (int c = br.read(); c != -1; c = br.read()) sb.append((char) c);
    return sb.toString();
}