2016-04-03 7 views
0

私はマリオゲームを作っており、進歩しました。今私は世界を切り替える必要があります。最初に私の更新を実行しているスレッドを停止し、メソッドを描画し、次に世界にあるすべてのもの(プレイヤー、敵、草など)を削除してから、新しい世界をロードします。それから私は再びスレッドを開始しようとします。しかし、何らかの理由でスレッドを停止した後、それ以降は何も実行されず、ただそこで「フリーズ」します。Thread.join()の後に何も実行できません

private synchronized void clearWorld() { 
    stop(); 
    System.out.println("Stopped"); 
    for(int a = 0 ; a < handler.wall.size() ; a++) handler.wall.remove(handler.wall.get(a)); 
    for(int b = 0 ; b < handler.creature.size() ; b++) handler.creature.remove(handler.creature.get(b)); 
    System.out.println("Everything removed"); 
} 

private synchronized void switchWorld(String path) { 
    world = new World(this , path); 
    start(); 
    System.out.println("Thread started"); 
} 
public synchronized void stop() { 
    if(!running) return ; 
    running = false ; 
    try { 
     Main.getGame().thread.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
public synchronized void start() { 
    if(running) return ; 
    running = true ; 
    Main.game.thread.start(); 
} 

public void run() { 
    init(); 
    long lastTime = System.nanoTime(); 
    final double amountOfTicks = 60.0; 
    double ns = 1000000000/amountOfTicks; 
    double delta = 0; 
    int updates = 0; 
    int frames = 0; 
    long timer = System.currentTimeMillis(); 

    while(running){ 
     long now = System.nanoTime(); 
     delta += (now - lastTime)/ns; 
     lastTime = now; 
     if(delta >= 1){ 
      tick(); 
      updates++; 
      delta--; 
     } 
     render(); 
     frames++; 

     if(System.currentTimeMillis() - timer > 1000){ 
      if(world.Goombas==getPlayer().gKilled) { 
       clearWorld(); 
       switchWorld("/pipe_world1.txt"); 
      } 
      timer += 1000; 
      System.out.println(updates + " Ticks, Fps " + frames); 
      updates = 0; 
      frames = 0; 
     } 

    } 
} 
+0

おそらくこれが役に立ちます。 「スレッドが停止すると再起動できません」http://stackoverflow.com/questions/1881714/how-to-start-stop-restart-a-thread-in-java – RubioRic

+0

しかし、それでも停止しません! clearWorldメソッドを参照してください –

+0

私はあなたがデッドロック状況が疑わしいです。スタックダンプを表示して、デバッガでスレッドが何をしているのかを見てみることができますか? –

答えて

1

Thread.joinは、呼び出しスレッドを中断し、ターゲットスレッドが終了するのを待ちます。あなたのコードで何が起こっているのは、clearWorldを呼び出すスレッドが、ゲームスレッドが終了するのを待っているということです。

EDIT:更新後、ゲームスレッド自体がjoinを呼び出していることがわかります。これにより、joinへの呼び出しが永久にブロックされることが保証されます。説明はThread join on itselfを参照してください。

1つのスレッドですべてを実行しているので、joinまたはstartはまったく必要ありません。

複数のスレッドを持っていた場合は、これを行うより良い方法は、ゲームの実行が一時停止しているかどうかを確認する変数をゲームスレッドに含めることです。たぶん、このような何か:

class GameThread extends Thread { 
    private volatile boolean paused; 

    public void run() { 
     while (true) { 
      if (!paused) { 
       executeGameLogic(); 
      } else { 
       // Put something in here so you're not in a tight loop 
       // Thread.sleep(1000) would work, but in reality you want 
       // to use wait and notify to make this efficient 
      } 
     } 
    } 

    public void pause() { 
     paused = true; 
    } 

    public void unpause() { 
     paused = false; 
    } 
} 

あなたclearWorldswitchWorld方法は、ゲームスレッド上pauseunpauseを呼び出すことができます。

関連する問題