Libgdx JSON自定义Array <vector2> </vector2>的序列化

时间:2014-11-07 09:05:29

标签: java arrays json serialization libgdx

我正在尝试编写一个自定义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引用了什么?读写方法中使用的第三个参数“Class”是什么?我是否需要为Array.class而不是Vector2.class编写序列化程序,尽管我仍然希望对不是Vector2类型的数组使用默认的序列化程序?

3 个答案:

答案 0 :(得分:3)

问题在于您的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;
}

答案 1 :(得分:0)

我认为你的问题是你在错误的程度上这样做。

要执行您想要执行的操作,您的序列化代码应该包含在包含splinePoints数组的类中。

如你所知,你的作家会产生

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

请点击我们的open source libGdx game

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

您可能想要做类似

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

答案 2 :(得分:0)

这是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序列化器不支持Array)。