2016-04-03 10 views
0

Ich habe ein Mario-Spiel gemacht und gute Fortschritte gemacht. Jetzt muss ich zwischen den Welten wechseln. Zuerst stoppe ich den Thread mit meinen Update- und Draw-Methoden, dann entferne ich alles was in der Welt ist (Spieler, Feinde, Gras, etc.) und dann lade ich eine neue Welt. Dann versuche ich den Thread erneut zu starten. Aber aus irgendeinem Grund wird nach dem Stoppen danach nichts mehr ausgeführt und es "friert" genau dort ein.Nach Thread.join() konnte ich nichts ausführen.

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

Vielleicht hilft das. "Sobald ein Thread stoppt, können Sie es nicht neu starten" http://stackoverflow.com/questions/1881714/how-to-start-stop-restart-a-thread-in-java – RubioRic

+0

Aber es wird nicht einmal gedruckt gestoppt! Sehen Sie sich die clearWorld-Methode an –

+0

Ich vermute, Sie haben eine Deadlock-Situation. Können Sie uns einen Stack-Dump zeigen und sehen, was die Threads in Ihrem Debugger tun, wenn das passiert? –

Antwort

1

Thread.join unterbricht den aufrufenden Thread und wartet auf den Ziel-Thread zu sterben. Was in deinem Code passiert, ist, dass der Thread, der clearWorld aufruft, darauf wartet, dass der Spiel-Thread beendet wird.

EDIT: Nach dem Update sehe ich, dass es der Spiel-Thread selbst ist, der join aufruft. Das führt dazu, dass der Ruf nach join für immer blockiert wird. Eine Erläuterung finden Sie unter Thread join on itself.

Da Sie alles in einem Thread tun, gibt es wirklich keine Notwendigkeit für die join oder start überhaupt.

Wenn Sie mehrere Threads hatten, wäre es besser, eine Variable in Ihrem Spiel-Thread zu haben, die überprüft, ob die Ausführung des Spiels pausiert ist. Vielleicht so etwas wie folgt aus:

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; 
    } 
} 

Ihre clearWorld und switchWorld Methoden dann pause und unpause auf das Spiel Thread aufrufen können.

Verwandte Themen