libGDX json错误
问题描述:
我想保存项目的Arraylist并保存并加载它。 这是我要加载的ArrayList:libGDX json错误
public static ArrayList<Item> inventory = new ArrayList<Item>();
public mainscreen(final luckyllama gam) {
game = gam;
json = new Json();
json.setIgnoreUnknownFields(true);
if( json.fromJson(ArrayList.class,
Gdx.files.internal("data/inventory.json")) != null){
ArrayList<JsonValue> list = json.fromJson(ArrayList.class,
Gdx.files.internal("data/inventory.json"));
for (JsonValue v : list) {
inventory.add(json.readValue(Item.class, v));
}
}
...
我这是怎么保存的ArrayList:
mainscreen.json.toJson(mainscreen.inventory, Gdx.files.local("data/inventory.json"));
这是Item类的一部分:
public class Item {
public float x, y, speedx, speedy;
public Rectangle container, icontainer;
public Sprite texture;
public int Quality;
static int amount;
static int spawned;
public int itemtype;
static Item item;
这是我保存文件后的json文件:
[{
class: com.algrande.luckyllama.Item,
y: 50,
speedx: -2.5,
container: {
y: 50,
width: 50,
height: 30
},
texture: {
texture: {
glTarget: 3553,
glHandle: 1,
minFilter: Linear,
magFilter: Linear,
uWrap: ClampToEdge,
vWrap: ClampToEdge,
data: {
class: com.badlogic.gdx.graphics.glutils.FileTextureData,
file: {
class: com.badlogic.gdx.backends.lwjgl.LwjglFileHandle,
file: {
path: items\\items.png
},
type: Internal
},
width: 4096,
height: 4096,
format: RGBA8888,
pixmap: null,
useMipMaps: false,
isPrepared: false
}
},
u: 0.25,
u2: 0.5,
v2: 0.25,
regionWidth: 1024,
regionHeight: 1024,
vertices: [0,
0,
-1.7014117E38,
0.25,
0.25,
0,
0,
-1.7014117E38,
0.25,
0,
0,
0,
-1.7014117E38,
0.5,
0,
0,
0,
-1.7014117E38,
0.5,
0.25],
width: 1024,
height: 1024,
originX: 512,
originY: 512
},
Quality: 1,
itemtype: 62
}]
但我发现了这个错误:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.SerializationException: Error reading file: data/inventory.json
at com.badlogic.gdx.utils.Json.fromJson(Json.java:694)
at com.algrande.luckyllama.screens.mainscreen.<init>(mainscreen.java:78)
at com.algrande.luckyllama.luckyllama.create(luckyllama.java:19)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:147)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
Caused by: com.badlogic.gdx.utils.SerializationException: Class cannot be created (missing no-arg constructor): com.badlogic.gdx.graphics.Texture
Serialization trace:
texture (com.badlogic.gdx.graphics.g2d.Sprite)
texture (com.algrande.luckyllama.Item)
at com.badlogic.gdx.utils.Json.newInstance(Json.java:1042)
at com.badlogic.gdx.utils.Json.readValue(Json.java:892)
at com.badlogic.gdx.utils.Json.readFields(Json.java:797)
at com.badlogic.gdx.utils.Json.readValue(Json.java:919)
at com.badlogic.gdx.utils.Json.readFields(Json.java:797)
at com.badlogic.gdx.utils.Json.readValue(Json.java:919)
at com.badlogic.gdx.utils.Json.readValue(Json.java:947)
at com.badlogic.gdx.utils.Json.fromJson(Json.java:692)
... 4 more
Caused by: com.badlogic.gdx.utils.reflect.ReflectionException: Could not instantiate instance of class: com.badlogic.gdx.graphics.Texture
at com.badlogic.gdx.utils.reflect.ClassReflection.newInstance(ClassReflection.java:70)
at com.badlogic.gdx.utils.Json.newInstance(Json.java:1024)
... 11 more
Caused by: java.lang.InstantiationException: com.badlogic.gdx.graphics.Texture
at java.lang.Class.newInstance(Class.java:427)
at com.badlogic.gdx.utils.reflect.ClassReflection.newInstance(ClassReflection.java:68)
... 12 more
Caused by: java.lang.NoSuchMethodException: com.badlogic.gdx.graphics.Texture.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 13 more
什么我做错了,我该如何解决?
答
Json的自动反序列化依赖于空的构造函数来实例化每个对象。 Json只能使用它们的空构造函数反序列化类。由于Item引用了一个Sprite,它引用了一个Texture;并且由于Texture没有任何空构造函数,所以不能自动反序列化Item。
所以你的选择是
1)在保存前设置精灵参考为空。然后切换回来。
2)删除Item类中Sprite的引用。相反,将一个TextureRegion传递给Item的render方法(如果它有一个)。
3)使用定制的Json串行器。您可以将一个序列化程序分配给Sprite,它不会读取或写入任何内容。例如读取或您的JSON实例写之前:
json.setSerializer(Sprite.class, new ReadOnlySerializer<Sprite>() {
public Sprite read (Json json, JsonValue jsonData, Class type) {
return (Sprite)null;
}
}
那么你的项目类需要它的加载后,分配给它,也许这样的精灵:
public class Item {
//...
private String spriteName;
//...
/**Call this on every Item immediately after it has been loaded from Json. */
public void onLoadedFromJson (TextureAtlas atlas){
texture = atlas.createSprite(spriteName);
sprite.setPosition(x, y);
}
}
谢谢!现在,JSON看起来像这样:[{ \t类:com.algrande.luckyllama.Item, \t Y:50, \t speedx:-2.5, \t容器:{ \t \t Y:50, \t \t宽度:50, \t \t高度:30 \t}, \t的IContainer:{ \t \t X:0.5, \t \t Y:82, \t \t宽度:33, \t \t高度:18 \t}, \t纹理:, \t质量:1, \t项目类型:66 },{ \t类:com.algrande.luckyllama。项, \t Y:50, \t speedx:-2.5, \t容器:{ \t \t Y:50, \t \t宽度:50, \t \t高度:30 \t}, \t纹理:, \t质地:ITEM6, \t质量:3, \t项目类型:26 }]但我仍然得到一个错误 “\t纹理:”(这是一个精灵)连如果它是空的。现在我删除了Sprite,并直接从spritenam – AlGrande
e渲染。但我不知道这是否有利于表演。有没有更好的方法来解决它? – AlGrande
我不知道你的设置的来龙去脉。从已经加载的纹理图集中实例化一个精灵并不是特别慢。加载Json之后,重新使用现有的Sprite实例会更快。 – Tenfour04