虽然循环阻止我的听众工作
问题描述:
没关系,所以我正在进行一场桌上游戏。 第一个'while循环'检查游戏是否结束,内部'while循环'应该等待用户输入(squareSelector和rooSelector是我的mouselisteners,'k'和's'是应该输入的被听众返回) 然而,'while循环'崩溃了我的程序并阻止了我的侦听器工作。 我读了这个,发现swing是单线程的,所以我的听众在whileloop处于活动状态时无法工作。不过,我需要等待输入,以避免空指针。 关于如何解决这个问题的任何想法? (如在一个不同的方法,或者如何使我的循环等待输入)虽然循环阻止我的听众工作
的gameloop
while(currentPlayer.haveIWon() == false){
//wait for input
while(!inputIsDone){
System.out.println("waiting for move");
System.out.println(squareSelector.isDone() + " " + rooSelector.isDone()) ;
checkInput() ;
if(squareSelector.isDone() && rooSelector.isDone()){
inputIsDone = true ;
}
}
//update board
currentPlayer.performMove(k, s);
rooSelector.setDone(false);
squareSelector.setDone(false);
inputIsDone = false ;
//currentPlayer.setInput(false);
//repaint
Main.getState().getComponent().repaint();
}
//display winnner thing
的checkInput方法
public void checkInput(){
if(rooSelector.getSelected() != null){
k = rooSelector.getSelected() ;
}
if(squareSelector.getSelected() != null){
s = squareSelector.getSelected() ;
}
}
如果你需要更多的代码来了解这是怎么回事让我知道,我会添加更多。
答
Swing是单线程的。由于其设计,与GUI相关的所有内容都必须在Swing线程上完成,也称为事件分派线程。它基本上做了一件事:看事件队列,如果有某事,它会处理它,如果没有,就进入睡眠状态。每个鼠标移动,按键,重画等都是事件队列中的事件。
如果您的游戏只对GUI事件做出反应并且没有冗长的操作,则不必使用任何特殊的操作。你可以在没有while
的情况下编写你的逻辑,以便它不会阻塞,只对事件做出反应。但是,这种可能性完全取决于您正在尝试实施的内容。
如果您有任何长时间阻塞该线程的操作,则需要为此使用单独的线程。这样,其他线程不会影响您的GUI,但您需要非常小心地将数据从一个线程发送到另一个线程,或者在另一个线程上调用某些线程。
不应该阻止[事件调度线程](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)。 - 问题在于你的循环阻止了EDT处理输入事件。游戏循环(如果有必要的话)应该在其自己的线程中运行(例如通过[SwingWorker](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html))。 – Thomas
在cheking输入明智的循环包括一种方法来防止通过饥饿杀死他人的Thread:Thread.yield()或Thread.sleep(1) – Doleron
一般来说,游戏不会不断更新其UI(即没有动画)或世界(即不是“实时”)很少需要游戏循环。你声明你需要一个来防止NPE,但是这意味着设计缺陷或编码错误,而不是真正需要循环。 – Thomas