我一直在制作一款马里奥游戏,并取得了很好的进展。现在我需要在不同的世界之间切换。首先,我停止运行更新和绘制方法的线程,然后删除世界上的所有内容(玩家、敌人、草地等),然后加载一个新世界。然后我尝试重新启动线程。但由于某种原因,在停止线程后,什么也不执行,它只是在那里"冻结"。
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;
}
}
}
Thread.join
挂起调用线程并等待目标线程死亡。代码中发生的情况是,调用clearWorld
的线程正在等待游戏线程终止。
编辑:在你更新后,我发现是游戏线程本身在调用join
。这保证会导致对join
的调用永远阻塞。有关解释,请参见线程连接本身。
由于您在一个线程中完成所有工作,因此实际上根本不需要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;
}
}
然后,您的clearWorld
和switchWorld
方法可以在游戏线程上调用pause
和unpause
。