3

私はworld.step(timeStep, iterations, iterations)1つのスレッドで呼び出しており、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 の世界が変化しています。これを同期する方法はありますか?1つのスレッドに入れるべきですか?

4

1 に答える 1

0

あなたが言ったように、レンダリング中にbox2dの世界が変化しているため、このスレッドの問題が発生します。

できることは、Javasynchronizedプリミティブを使用して、一度に 1 つのスレッドのみが box2d リソースにアクセスできるようにすることです。

最初のスレッド (ゲームの更新):

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

2 番目のスレッド (レンダリング):

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

ここでの使用worldは唯一のオプションではありませんthis。両方のスレッドが同じクラスに共存する場合は、への参照を使用することもできます。

すべてを単一のスレッドに入れるオプションに関しては、問題を確実に解決します。ただし、私の意見では、レンダリングと更新を 2 つのスレッドに分けることは素晴らしいアイデアです。まず、CPU リソースをより有効に使用できます (モバイル プラットフォームでも複数のスレッドを並行して実行できる可能性があります)。第 2 に、ゲームの更新とレンダリングの速度を分離すると、ゲームのスケーリングが容易になります。

よろしく、

于 2013-05-12T10:55:12.980 に答える