简体   繁体   English

Libgdx存储游戏项目

[英]Libgdx storing game items

I understand the basics of JSON, but what I more curious about is how I would use it to go about achieving what I need to get done. 我了解JSON的基础知识,但我更好奇的是,我将如何使用它来完成我需要完成的工作。

Let me explain, I want to store all my game ITEMS in a JSON file so it would hold the item name "WEAPON OF WHATEVER" then have its stats such as buyPrice , sellPrice , minDamage , maxDamage , etc... 让我解释一下,我想将我所有的游戏项目都存储在一个JSON文件中,这样它将保留项目名称“ WEAPON OF WHATEVER”,然后具有其统计信息,例如buyPricesellPriceminDamagemaxDamage等。

How would one go about doing something like this in JSON? 如何在JSON中执行类似的操作?

I've used JSON files to store reference data for my game, and the good news is that libGDX comes with a JSON parser that you can use in a few lines of code as shown below. 我已经使用JSON文件存储了游戏的参考数据,而且好消息是libGDX 带有JSON解析器 ,您可以在几行代码中使用它,如下所示。 First, you want to define a class that can be serialized: 首先,您要定义一个可以序列化的类:

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.
}

Then you need to create a Json object to read a file (or write to a file): 然后,您需要创建一个Json对象来读取文件(或写入文件):

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

This is actual, working code from my game. 这是我游戏中的实际工作代码。 A few things to point out: 需要指出的几点:

  • types is of type Array<Item> using libGDX's Array class. 类型是使用libGDX的Array类的Array<Item>类型。 This means we're really telling libGDX to interpret it as an Array object instead of a proper array, but I really like libGDX's data structures, so this wasn't an issue for me. 这意味着我们实际上是在告诉libGDX将其解释为Array对象而不是适当的数组,但是我真的很喜欢libGDX的数据结构,所以这对我来说不是问题。
  • Not all Java data structures are supported when using GWT (in particular, when using Maps you want to use a libGDX implementation under com.badlogic.gdx.utils ). 并非所有的Java数据结构使用GWT时(尤其是使用地图时,要使用下libGDX实现支持com.badlogic.gdx.utils )。 This is because the nature of GWT puts certain restrictions on reflection. 这是因为GWT的性质对反射进行了某些限制。
  • Note that when we call Json#fromJson() we have to pass Array.class and Item.class so that it knows to return an Array<Item> object. 请注意,当我们调用Json#fromJson()我们必须传递Array.classItem.class以便它知道要返回Array<Item>对象。

Now how do we structure the JSON? 现在我们如何构造JSON? The easiest way to figure this out is to create a small test program that generates a few objects and then writes them to a file or to stdout: 解决这个问题的最简单方法是创建一个小的测试程序,该程序会生成一些对象,然后将它们写入文件或stdout:

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

This will work for simple structures (and is probably all you need, but it might be helpful to look at the JSON and understand how it's structured. Going back to my example earlier, the JSON file looks like the following: 这将适用于简单的结构(可能是您所需要的,但查看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
]

You'll see that this is a pretty straightforward mapping from the JSON to our class. 您将看到这是从JSON到我们的类的非常简单的映射。 A few things of note: 注意事项:

  • Note how the file begins with the square brackets []- this tells us that the data is being stored as a JSON array, even though we're translating it into an Array class in our code. 请注意,文件如何以方括号[]开头-这告诉我们数据已存储为JSON数组,即使我们在代码中将其转换为Array类也是如此。
  • I based this off of the libGDX output, so inside each Item structure there is a "class" tag. 我基于libGDX输出,因此在每个Item结构内部都有一个“ class”标签。 I don't believe that this is strictly necessary, but it doesn't hurt when you have nested data structures like this. 我不认为这是绝对必要的,但是当您嵌套了这样的数据结构时,它不会受到损害。
  • Notice how "tags" got stored as an array, and libGDX doesn't need to know that it is an Array object. 注意“标签”是如何作为数组存储的,而libGDX不需要知道它是一个Array对象。

In summary, the libGDX library comes with its own JSON parser (which can be further customized if you have special serialization needs), but the tradeoff is that you have to use the libGDX data structures in certain cases (particularly when using GWT). 总而言之,libGDX库带有其自己的JSON解析器(如果您有特殊的序列化需求,可以对其进行进一步自定义 ),但是要权衡的是,在某些情况下(尤其是在使用GWT时),必须使用libGDX数据结构。

I use Gson to achieve something similar. 我使用Gson来实现类似的目的。

first add this to your core (of project of your chosing) build.gradle 首先将其添加到您选择的项目的核心(build.gradle)中

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

Get or allocate preferences (libgdx's cross plaform way to save user data): 获取或分配首选项(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");

Load/save your values: 加载/保存您的值:

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 关于首选项的LibGDX Wiki

This is asuming your data is dynamic and not just descriptions and the like. 假设您的数据是动态的,而不仅仅是描述之类的。 In that case I recommend the following (I created it for achievements once): 在这种情况下,我建议以下内容(我为成就而创建了它):

add to build.gradle: 添加到build.gradle中:

compile 'org.json:json:20151123'

Achievement.ID is an enumeration 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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