2016-03-20 8 views
0

私は現在、Javaで(OpenGL(LWJGL)を使用して)非常に単純なマルチプレイヤーゲームを作成しようとしていますが、現在、プログラムは2つの異なるスレッドで実行されています。マルチスレッドの問題 - スレッド間でオブジェクトを渡す

スレッド1:すべてのゲームロジックを実行し、

スレッド2のレンダリング:サーバーとクライアント

との間の接続を処理しますので、基本的にスレッド2が着座し、着信パケットを待ち、それがログイン・パケットを受信するたびに私はそれがプレーヤーオブジェクトを作成したいが、新しいオブジェクトがスレッド2で作成され、レンダリングしようとすると次のエラーが発生するようだ:

スレッド "スレッド2"の例外java.lang.IllegalStateException :現在のthreにGLCapabilitiesインスタンスが設定されていません広告。

私はOpenGLとマルチスレッドの両方にかなり新しいです。これはかなり単純で簡単な解決策がありますが、パケットを受信して​​スレッド1に追加するときにオブジェクトを作成する方法が不思議です。

スレッド2:

public void run() { 
    while (running) { 
     byte[] data = new byte[1024]; 
     DatagramPacket packet = new DatagramPacket(data, data.length); 
     try { 
      socket.receive(packet); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     parsePacket(packet.getData(), packet.getAddress(), packet.getPort()); 
     } 
    } 

parsePacket()は、パケットの種類をチェックし、ログイン・パケットの場合には、次のメソッドを呼び出します:

public void addPlayerToGame(byte[] data, InetAddress address, int port) { 
    Packet00Login packet = new Packet00Login(data); 

    level.addObject(new PlayerMP(packet.getUsername(), new Vector3f(0.0f, 0.0f, 0.0f), address, port)); 
} 

addObjectメソッドは、単にオブジェクトをarraylistに追加します。

public void addObject(GameObject o) { 
    this.objects.add(o); 
} 

すべてのオブジェクトは、スレッド1に、この呼び出しでレンダリングされています:

public void render() { 
    for (GameObject o : objects) { 
     o.render(); 
    } 
    player.render(); 
} 
+0

ショー(少なくとも) 'PlayerMP'とスタックトレースの関連部分のコンストラクタ。おそらく、あなたはコンストラクタ内でGL演算を行っていますが、これは間違ったスレッドで発生します。解決策は、プレイヤーをGLスレッドに作成するために必要な情報を処理し、GLスレッドが実際にプレイヤーを作成するようにすることができます。 – Marco13

+0

@ Marco13はい私はコンストラクタでGL演算を呼び出していました!私はこれらの操作をすべて「準備」メソッドに移しました。これはオブジェクトをリスト(GLスレッド上)に追加する前に呼びます。ご協力いただきありがとうございます! :) – Estrozix

答えて

0

変更は非常に高いあなたがその上で反復されますされているので、あなたは、第二のスレッドから、あなたのゲームオブジェクトのリストを変更しないでください最初のスレッドのリスト現在の変更例外が発生します。あるいは、OpenGLで未定義のビヘイビアを作成する。

あなたがしなければならないことは、最初のスレッドにタスクリストを持たせることです。ループごとに、タスクリスト内のすべてのタスクを実行してから、それをクリアします。

ゲームオブジェクトを直接リストに追加する代わりに、オブジェクトを追加するタスクを追加します。

(また、タスクのスレッドセーフの実行を行うことを確認してください)

+0

私は、追加しなければならないすべてのものを追加し、それを繰り返して、別の配列リストを作った!魅力のように動作します、ありがとう! :) – Estrozix

+0

私の意見では、とにかくタスクリストが必要です。おそらくオブジェクトを更新しなければならないので、ある時点(プレイヤーが動いているときなど)に現在のリストを持ち、他のリストを持っていればそれを手助けすることはできません。また、答えを確認することを忘れないでください – Gaktan

+0

ああ、それは本当です!私は前にこのようなことは一度もしていないし、私が得ることのできるすべての助けに感謝する。私は間違いなくそれを見て、おかげで:) – Estrozix

関連する問題