Box2d 不同步。

3

我在一个线程中调用world.step(timeStep, iterations, iterations),而在另一个线程中的Screen.render()方法内,出现了以下情况:

MyBox2DDebugRenderer.render(world, cam.combined);

一段时间后,我会得到

FATAL EXCEPTION: GLThread 2328
java.lang.IndexOutOfBoundsException: Invalid index 7, size is 7
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    at java.util.ArrayList.get(ArrayList.java:304)
    at com.kingx.spacejourney.MyBox2DDebugRenderer.renderBodies(MyBox2DDebugRenderer.java:132)
    at com.kingx.spacejourney.MyBox2DDebugRenderer.render(MyBox2DDebugRenderer.java:74)
    at com.kingx.spacejourney.Universe.render(Universe.java:85)
    at com.badlogic.gdx.Game.render(Game.java:46)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:449)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

MyBox2DDebugRenderer.java

130    int len = world.getContactList().size();
131    for (int i = 0; i < len; i++)
132        drawContact(world.getContactList().get(i));

在渲染过程中,Box2D世界正在发生变化。你有什么想法来同步它吗?我应该将它放在一个线程中吗?


你已经尝试将它放在一个线程中了吗? - Jack L.
我可以这样做,那可能会解决问题。但是两个线程会做更多的工作。 - jellyfication
使用单独线程并解决时间步长问题:http://gafferongames.com/game-physics/fix-your-timestep/ - vfcosta
1个回答

0

正如你所说,box2d世界在渲染时会发生变化,这就会导致线程问题。

你可以使用Java的synchronized原语来确保只有一个线程能够访问box2d资源,即:

第一个线程(游戏更新):

synchronized(world){
   ...
   // Make the physics work by stepping into time
   world.step(1 / 50.0f, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
   ...
}

第二个线程(渲染):

synchronized(world){
   ...
   // Your rendering
   MyBox2DDebugRenderer.render(world, cam.combined);
   ...
}

这里并不是唯一的选择使用world,如果两个线程同时存在于同一个类中,你还可以使用对this的引用。

关于在单个线程中放置所有内容的选项,这确实可以解决您的问题。但是,我认为将渲染和更新分为两个线程是一个好主意。首先,您将更好地利用CPU资源(可能能够同时运行多个线程,也适用于移动平台)。其次,如果游戏更新速度和渲染速度分离,那么您的游戏将更容易扩展。

祝好!


我认为这个答案的问题在于 OP 想要将他的 box2d 世界在一个与 libGDX 渲染线程不同的线程中运行。问题是,如果你结束了渲染线程等待其他线程,libGDX 将以一种丑陋的方式死亡。 - Scuba Steve
实际上,如果必须的话,您必须让libGDX等待渲染...例如,您不能随时从box2d中删除对象。上面提到的解决方案有效,至少在我的代码中是这样的(请参见此处)。 - pmudry
有没有办法让渲染线程等待?我发现box2d已经是多线程的了,所以在渲染线程中调用step可能并不是什么大问题。 - Scuba Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接