【问题标题】:(Libgdx and Rube Box2d) merge worlds(Libgdx 和 Rube Box2d)合并世界
【发布时间】:2013-11-01 23:39:49
【问题描述】:

好吧好吧,我使用 RubeLoader 将我的 rube 文件加载到 libgdx 上。

但是我注意到我只能加载一个 json 文件

代码:

loader = new RubeSceneLoader();
scene = loader.loadScene(Gdx.files.internal("test.json"));
World mWorld ;
mWorld = scene.getWorld();

如你所见,如果我想加载另一个 json 文件,它会因为这一行而破坏前一个:

mWorld = scene.getWorld();

所以我的问题是:如何加载多个 json 文件或如何将不同的世界合并为一个?

提前感谢您的回答

【问题讨论】:

    标签: java android box2d libgdx


    【解决方案1】:

    我检查了 RubeLoader 和 libGDX 的源代码,不明白为什么它应该打破第一世界。之后我自己检查了它(不是很广泛,但我想我涵盖了你的用例),它对我来说很好。

    Box2D、LibGDX 和 RubeLoader 支持多个世界。但当然你需要多个 World 实例。

    loader1 = new RubeSceneLoader();
    scene1 = loader1.loadScene(Gdx.files.internal("XXXX.json"));
    World mWorld1 = scene1.getWorld();
    
    loader2 = new RubeSceneLoader();
    scene2 = loader2.loadScene(Gdx.files.internal("ABCD.json"));
    World mWorld2 = scene2.getWorld();
    

    现在您有两个Worlds,它们应该都能正常工作,但此时合并它们并不容易。因为您必须从mWorld2mWorld1 或其他方式重新创建所有内容。我建议您以编程方式合并两个 JSON 文件(libGDX 已经有必要的 JSON 工具,但您可能会使用其他小型 json 库,如 Jackson),然后加载这个合并的场景。这应该比合并两个Worlds 容易得多。

    编辑: 如果您不是从一开始就需要合并Worlds,但一段时间后,最简单的方法是修改RubeWorldSerializer。具体这部分:

    World world = new World(gravity, allowSleep);
    world.setAutoClearForces(autoClearForces);
    world.setContinuousPhysics(continuousPhysics);
    world.setWarmStarting(warmStarting);
    

    尝试找到一种方法在此处输入您已经存在的mWorld1,当加载第二个场景时,所有BodiesJoints 都应该自动添加到这个World,而不是一个全新的。

    编辑2: 快速了解如何完成:

    将此添加到RubeWorldSerializerpublic static World mergeWorld;

    像这样改变世界初始化:

    World world;
    if (RubeWorldSerializer.mergeWorld == null) {
        world = new World(gravity, allowSleep);
        world.setAutoClearForces(autoClearForces);
        world.setContinuousPhysics(continuousPhysics);
        world.setWarmStarting(warmStarting);
    } else {
        world = RubeWorldSerializer.mergeWorld;
    }
    

    现在你的加载应该是这样的:

    loader1 = new RubeSceneLoader();
    scene1 = loader1.loadScene(Gdx.files.internal("XXXX.json"));
    World mWorld1 = scene1.getWorld();
    
    RubeWorldSerializer.mergeWorld = mWorld1; // this is important in between your loading.
    
    loader2 = new RubeSceneLoader();
    scene2 = loader2.loadScene(Gdx.files.internal("ABCD.json"));
    World mWorld2 = scene2.getWorld(); // in theory mWorld2 should be the same like mWorld1 now, and it should be both worlds merged
    

    【讨论】:

    • 我首先要感谢您的回答,但是我的测试结果表明,当我加载场景时,它会破坏以前的世界(以前的世界是我用来加载的同一个世界变量中的世界RubeScene)。我知道我可以在不同的世界中加载不同的场景,但这对我的情况没用,但是感谢您的杰克逊图书馆,但我想知道合并不同的 RubeScenes 并因此在不同的时刻加载它们。不管怎样,我会看看我能从这个杰克逊图书馆里得到什么
    • 您说我必须在 mWorld1 中重新创建来自 mWorld2 的所有内容。如果你能告诉我如何做到这一点,我将不胜感激,无论多长时间,我都可以将它变成一个函数,以方便使用。
    • 我刚刚在我的答案中添加了一个编辑,给你一个提示,你可以如何做到这一点,虽然我现在没有时间自己制定一个功能齐全的版本。
    • 好的,现在是最后一次编辑。不确定它会起作用,但这就是我会尝试的方式。
    • 我从来没有想过这样做,我现在不能尝试,但我会尽快的,非常感谢你的帮助
    【解决方案2】:

    我不了解 libGDX 加载器,在加载器的 C++ 版本中,可以轻松修改主要加载函数以将现有世界作为参数。如果现有世界不为空,它将被使用而不是创建一个新世界。否则,将照常创建一个新世界。

    之前(伪代码!):

    World loadWorld( File f ) {
        World w = <make a new world>
        //load the scene into w
        return w;
    }
    

    之后:

    World loadWorld( File f, World w ) {
        if ( w == null )
            w = <make a new world>
        //load the scene into w
        return w;
    }
    

    同样的想法可能可以用许多其他语言来实现。

    【讨论】:

    • @noone 的回答解决了我的问题,如果您真的是制作 rube 的 iforce2d,您应该将此代码提供给制作 libgdx 加载程序的人以改进它。谢谢你
    • “同样的想法可能在许多其他语言中也可以实现。”...嗨,是的。对于 libGDX 特定的加载器,这基本上是我在回答中提供给他的:)
    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多