我瞭解JSON的基礎知識,但是我更加好奇的是,我將如何使用它來實現我需要完成的任務。Libgdx存儲遊戲物品
讓我解釋一下,我要存儲在一個JSON文件中的所有我的遊戲項目,因此將舉行的項目名稱「無論武器」,那麼有它的統計信息,例如buyPrice
,sellPrice
,minDamage
,maxDamage
,等...
如何在JSON中做這樣的事情?
我瞭解JSON的基礎知識,但是我更加好奇的是,我將如何使用它來實現我需要完成的任務。Libgdx存儲遊戲物品
讓我解釋一下,我要存儲在一個JSON文件中的所有我的遊戲項目,因此將舉行的項目名稱「無論武器」,那麼有它的統計信息,例如buyPrice
,sellPrice
,minDamage
,maxDamage
,等...
如何在JSON中做這樣的事情?
我用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的數據結構,所以這對我來說不是問題。com.badlogic.gdx.utils
下的libGDX實現)並不支持所有Java數據結構。這是因爲GWT的本質對反思有一定的限制。Json#fromJson()
時,我們必須通過Array.class
和Item.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到我們的班級。需要注意的幾件事:
綜上所述,libGDX庫本身自帶的JSON解析器(可further customized,如果你有特殊的序列化需求),但代價是你必須使用在某些情況下libGDX數據結構(特別是當使用GWT)。
我使用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();
}
這是假設你的數據是動態的,而不僅僅是描述等。在這種情況下,我建議如下(我創造它的成就一次):
加入的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();
}
嗯感謝回覆,但使用偏好可能不是我的最佳選擇,因爲我使用它的其他地方我只是需要直讀和寫入到JSON文件,但我不是100%確定如何這樣做有物品的子屬性和多個項目 – johnnyboy5566
非常感謝,真的有幫助!有一個問題,假設你想獲得一個特定的項目,你只需要加載json,然後根據名稱調用你想要的項目? – johnnyboy5566
除非文件是淫穢的大文件,否則最簡單的方法是加載數組,然後在數組中搜索所需的項目。在我的使用案例中,我想加載所有這些文件並將它們存儲在內存中。如果性能確實成爲問題,我想你可以使用「基於事件的分析」(在libGDX wiki頁面上引用)來創建某種查詢。 – John