我正在使用javafx开发一款小游戏(炸弹人)。基本上,我有玩家可以种植炸弹。炸弹持续时间(例如爆炸前1500毫秒)。
所以,当我的播放器播放炸弹时,我使用Thread.sleep(ms)在炸弹中开始一个线程,然后我通知播放器炸弹爆炸了。
事情是,我的玩家可以放下他的炸弹然后移动......但是当炸弹爆炸时,它会在炸弹播种时用坐标通知玩家的实例...
例如,如果我的玩家在[2; 2]中,植入炸弹,然后移动到[2; 4],然后炸弹爆炸,我的玩家回到[2; 2] ...
任何人都知道如何实现我的炸弹所指向的玩家实例......?
以下是代码示例:
public class Player{
public void putBomb(){
listBomb.add(new Bomb(this));
}
public void refresh(){
System.out.println(xCoordinate+" "+yCoordinate);
}
}
public class Bomb{
public Bomb(Player p){
observer=p;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1500);
notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
public void sendNotification(){
observer.refresh();
}
}
答案 0 :(得分:1)
由于您的问题是特定于JavaFX,因此有关如何执行此操作的建议与非GUI Java程序不同(因为JavaFX具有内置并发协助和单线程应用程序编程模型)。
您不需要其他帖子,您可以使用PauseTransition。
public class Bomb{
public Bomb(final Player player){
PauseTransition pause = new PauseTransition(Duration.seconds(1.5));
pause.setOnFinished(event -> player.refresh());
pause.play();
}
);
如果由于某种原因您不希望使用转换,并且您想使用自己的线程,那么您应该使用JavaFX concurrency utilities等Task。
如果您不想使用任务,那么您仍然可以创建自己的线程或可运行,但请确保使用Platform.runLater()进行任何回调。例如:
public class Bomb{
public Bomb(final Player player){
new Thread(() -> {
try {
Thread.sleep(1500);
Platform.runLater(() -> player.refresh());
} catch (InterruptedException e) {}
}
}).start();
}
}
在不同的方法中,我推荐PauseTransition而不是其他方法,因为您不需要处理容易出错的并发细节,例如线程。
答案 1 :(得分:0)
您的运行方法在[this.]notify()
上调用synchronized
而不是this
。我希望它总是抛出一个IllegalMonitorStateException
。
此外,如果不设置其他线程可以检查的变量,则调用notify()
几乎总是错误的。 notify()
的问题在于它根本不做任何事情,除非某个其他线程碰巧在同一个对象的wait()
调用中。没有适当的同步,你无法保证这是真的。
只有一种正确的方法可以使用wait()
和notify()
,这是Oracle调用保护块的设计模式。 https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html