2016-12-13 121 views
1

我瞭解JSON的基礎知識,但是我更加好奇的是,我將如何使用它來實現我需要完成的任務。Libgdx存儲遊戲物品

讓我解釋一下,我要存儲在一個JSON文件中的所有我的遊戲項目,因此將舉行的項目名稱「無論武器」,那麼有它的統計信息,例如buyPricesellPriceminDamagemaxDamage,等...

如何在JSON中做這樣的事情?

回答

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時(尤其是使用 地圖時,您希望使用com.badlogic.gdx.utils下的libGDX實現)並不支持所有Java數據結構。這是因爲GWT的本質對反思有一定的限制。
  • 請注意,當我們呼叫Json#fromJson()時,我們必須通過Array.classItem.class,以便它知道要返回Array<Item>對象。

現在我們該如何構建JSON?算出這個最簡單的方法是創建產生幾個對象一個小的測試程序,然後將它們寫入一個文件或標準輸出:

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不需要知道它是一個數組對象。

綜上所述,libGDX庫本身自帶的JSON解析器(可further customized,如果你有特殊的序列化需求),但代價是你必須使用在某些情況下libGDX數據結構(特別是當使用GWT)。

+0

非常感謝,真的有幫助!有一個問題,假設你想獲得一個特定的項目,你只需要加載json,然後根據名稱調用你想要的項目? – johnnyboy5566

+0

除非文件是淫穢的大文件,否則最簡單的方法是加載數組,然後在數組中搜索所需的項目。在我的使用案例中,我想加載所有這些文件並將它們存儲在內存中。如果性能確實成爲問題,我想你可以使用「基於事件的分析」(在libGDX wiki頁面上引用)來創建某種查詢。 – John

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(); 
} 
+0

嗯感謝回覆,但使用偏好可能不是我的最佳選擇,因爲我使用它的其他地方我只是需要直讀和寫入到JSON文件,但我不是100%確定如何這樣做有物品的子屬性和多個項目 – johnnyboy5566