【问题标题】:libGDX json errorlibGDX json 错误
【发布时间】:2016-07-01 04:07:13
【问题描述】:

我想保存一个 Arraylist 的 Items 并保存并加载它。 这就是我想要加载 Arraylist 的方式:

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 arraylist libgdx save


    【解决方案1】:

    Json 的自动反序列化依赖于空的构造函数来实例化每个对象。 Json 只能使用空的构造函数来反序列化类。由于 Item 引用了 Sprite,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;
        }
    }
    

    那么你的 Item 类将需要在加载后为其分配一个 sprite,可能是这样的:

    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 看起来像这样: [{ class: com.algrande.luckylama.Item, y: 50, speedx: -2.5, container: { y: 50, width: 50, height: 30 }, icontainer: { x: 0.5 , y: 82, width: 33, height: 18 }, 纹理: , Quality: 1, itemtype: 66 }, { class: com.algrande.luckyllama.Item, y: 50, speedx: -2.5, container: { y : 50, width: 50, height: 30 }, textures: , texture: item6, Quality: 3, itemtype: 26 }] 但我仍然在“textures:”(这是一个精灵)处收到错误,即使它为空.现在我删除了 Sprite 并将其直接设置为从 spritenam 进行渲染
    • 我不知道你的设置的来龙去脉。从已经加载的纹理图集中实例化精灵并不是特别慢。唯一更快的是在加载 Json 后重用不再使用的现有 Sprite 实例。
    • 对此有一些争论,但在我看来,LibGDX 的 Sprite 类不应该使用,因为它深度混合了游戏状态和渲染。我的游戏对象携带有关其游戏状态的数据,并且每个对象都有自己的渲染方法,其中传递了一个纹理图集,它可以从中提取一个 TextureRegion 进行绘制。 (另一方面,从理论上讲,Sprite 占用的 CPU 较少。)
    • 我不确定你在做什么来创建仍然引用textures 的 Json 文件,因为我的所有三个建议都导致 Json 文件甚至没有提及它。不需要处理精灵,但支持精灵的纹理需要处理(仅在任何地方不再使用该纹理之后)。
    • 我不知道item1 是什么。一般来说,你所有的 Sprite 都应该共享一个 Texture 实例,所以在没有人再使用它之前你不会丢弃它。您不应该在 render 方法中创建 Sprite,因为它们是相当重的对象。假设您使用上面的选项 2,您应该传入更轻量级的对象 TextureRegion 并改为绘制它。 TextureRegion 可以被许多项目重用。 Sprite 是一个 TextureRegion,它还在数组中存储位置数据,这是多余的,因为您的 Item 对象已经存储了该信息。
    猜你喜欢
    • 2016-07-19
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    相关资源
    最近更新 更多