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 世界正在发生变化。你有一些想法如何同步这个吗?我应该把它放在一个线程中吗?

4

1 回答 1

0

正如您所说,box2d 世界在渲染时正在发生变化,这会产生这个线程问题。

您可以做的是使用 Javasynchronized原语来确保一次只有一个线程能够访问 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);
   ...
}

这里 usingworld不是唯一的选择,this如果两个线程共存于同一个类中,您还可以使用引用。

关于将所有内容放在一个线程中的选项,它肯定会解决您的问题。但是,在我看来,在两个线程中分离渲染和更新是一个好主意。首先,您将更好地使用您的 CPU 资源(这可能能够并行运行多个线程,也可以在移动平台中)。其次,如果游戏更新速度和渲染速度分开,你的游戏会更容易扩展。

问候,

于 2013-05-12T10:55:12.980 回答