繁体   English   中英

数组的Libgdx JSON自定义序列化<Vector2>

[英]Libgdx JSON custom serialization of Array<Vector2>

我正在尝试编写一个自定义JSON序列化程序,该序列化程序可以读取浮点数组作为Vector2对象的坐标。 假设我的班级中有一个名为:

Array<Vector2> splinePoints;

我希望能够读取和写入格式如下的JSON文件:

splinePoints: [0,0, 1,1, 2,2]

每对浮点都将作为Vector2对象的x和y坐标读取。 这种格式允许我以最小的编辑来复制和粘贴Inkscape生成的样条点。 而且,这比使用默认序列化程序的形式更紧凑:

splinePoints: [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 2}]

到目前为止,我已经尝试了以下代码(这可能是非常错误的):

public class PointsHolder {
    public Array<Vector2> splinePoints = new Array<Vector2>();
}

Json json = new Json();
json.setSerializer(PointsHolder.class, new Json.Serializer<PointsHolder>() {
    public void write(Json json, PointsHolder pointsHolder, Class knownType) {
        json.writeArrayStart();
        for(Vector2 vector2: pointsHolder.splinePoints) {
            json.writeValue(vector2.x);
            json.writeValue(vector2.y);
        }
        json.writeArrayEnd();
    }

    public PointsHolder read(Json json, JsonValue jsonData, Class type) {
        PointsHolder pointsHolder = new PointsHolder();
        for (JsonValue child = jsonData.child; child != null; child = child.next) {
            Vector2 vector2 = new Vector2();
            vector2.x = jsonData.child.asFloat();
            vector2.y = jsonData.child.next.asFloat();
            pointsHolder.splinePoints.add(vector2);
        }

        return pointsHolder;
    }
});

运行时,出现异常,无法将值转换为所需的类型。 即使阅读了教程并遍历了源代码,我仍然无法理解JSON序列化程序的工作原理。 读取数组时,JsonValue jsonData指的是什么? 读写方法中使用的第三个参数“类”是什么? 我仍然需要为Array.class而不是Vector2.class写一个序列化程序,尽管我仍想对非Vector2类型的数组使用默认的序列化程序?

问题出在您的read()方法上。 在循环内始终使用jsonData.child始终是第一个元素。 尝试以下方法:

public PointsHolder read(Json json, JsonValue jsonData, Class type) {
    PointsHolder pointsHolder = new PointsHolder();
    for (JsonValue child = jsonData.child; child != null; child = child.next.next) {
        Vector2 vector2 = new Vector2();
        vector2.x = child.asFloat();
        vector2.y = child.next.asFloat();
        pointsHolder.splinePoints.add(vector2);
    }

    return pointsHolder;
}

我使用最新版本测试了此代码,并且可以正常工作。

更新:我已经测试过字符串[0,0, 1,1, 2,2] 如果您想反序列化类似

{
  splinePoints: [0,0, 1,1, 2,2]
}

您必须用新类包装PointsHolder。 就像是:

public class PointsHolderWrapper
{
    public PointsHolder splinePoints;
}

我认为这里的问题是您在错误的级别上执行此操作。

要执行您想做的事情,序列化代码应该放在包含splinePoints数组的类中。

有了你的作家就会产生

splinePoints: [[0,0],[1,1],[2,2]]

在这里看看我们的开源libGdx游戏

特别是在执行完全序列化的Profile类以及在从手工创建的文件中读取的AchievementManager和LeaderboardManager类中。

您可能想要做类似的事情

json.writeArrayStart();
for(Vector2 v : splinePoints) {
    json.writeValue(v.x);
    json.writeValue(v.y);
}
json.writeArrayEnd();

这是序列化到json数组:

class PointsHolder {
Array<Vector2> splinePoints;

// some setters/getters
}

// in your code instead of field/variable:
Array<Vector2> splinePoints;

// use:
PointsHolder splinePointsHolder;

然后将一些项目添加到splinePointsHolder并将其序列化。 Serializator应该创建json数组,并将splinePoints列表中的所有项添加到其中(如果为Vector2定义了序列化)。 另外,也许您需要使用受支持的列表/数组(如果json serializator不支持Array)。

暂无
暂无

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

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