我是这个社区的新手,我有一个问题,我似乎无法自己解决,甚至在搜索谷歌和向朋友寻求答案时也是如此。
我正在制作一个小型模式记忆游戏,围绕按一定顺序点击按钮,每次成功都会变得更难,直到你失败。设置是通过javafx GUI进行的,IDE是NetBeans 8.1。
现在,当一个序列通过按钮发光显示给玩家时,每个按钮和序列中的下一个按钮之间需要有一个延迟,以便玩家知道他们点击的顺序按钮。 我尝试了三种延迟函数,但都产生相同的结果,它们是Thread.sleep,Timelines和Transitions。
正如您在上面的图像中所看到的,这个for循环随机选择游戏中的5个按钮之一,并使其发光,以便玩家知道这是序列中的下一个按钮。所有这些都发生在循环的每次迭代中创建的新时间轴内,因此每次选择和显示按钮时都会发生延迟。
然而,当我执行代码的这一部分时,我所看到的是非常奇怪的。 for循环存在于按钮事件处理程序中。当我单击此按钮时,我确实看到延迟正常,但是不是在每个按钮和序列中的下一个按钮之间,我看到按钮的单击和整个序列的显示之间的延迟。
那么如何使延迟按预期工作?据我所知,Timeline是实现延迟的最佳方法之一,而不是可靠的Thread.sleep方法,它会在您执行代码时大大降低设备速度。
作为参考,第一,第二,第三,第四和第五是按钮的名称。 storebutton函数存储当前按钮的位置,供以后在游戏中引用(你可以忽略那个句子,它不会影响延迟的执行),borderglow是按钮发光效果,而generator是Random类中的对象它生成0到5之间的随机整数。
请花点时间考虑这个问题,这是令人费解的,我无法解决这个问题。在IDE中尝试这个想法,甚至更好地理解问题。任何帮助将不胜感激。我提前感谢:)
答案 0 :(得分:1)
PauseTransition
可用于此目的。如有必要,您可以使用onFinished
事件处理程序更新UI并重播转换:
List<Button> buttons = ...
// list of glowing indices
List<Integer> indices = Arrays.asList(0, 3, 2, 1, 3, 1);
PauseTransition transition = new PauseTransition(Duration.seconds(1));
EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {
private int currentIndex = 0;
private final Iterator<Integer> iterator = indices.iterator();
private final Effect effect = new Glow(200);
@Override
public void handle(ActionEvent event) {
buttons.get(currentIndex).setEffect(null);
if (iterator.hasNext()) {
currentIndex = iterator.next();
buttons.get(currentIndex).setEffect(effect);
transition.play();
}
}
};
transition.setOnFinished(handler);
// activate first button & start animation
handler.handle(null);
答案 1 :(得分:0)
调用Timeline#play
会运行Timeline
,但会立即返回。您实际上是在创建多个单独的时间轴,并且几乎同时运行它们。
为了达到预期效果,您可以选择以下几种方法:
创建一个时间轴,向其中添加KeyFrame
,每个时间轴都有相应更高的时间目标:
Timeline timeline = new Timeline();
for (int i=0; i<buttoncount; i++) {
timeline.getKeyFrames().add(new KeyFrame(Duration.millis((i+1)*1000), e -> {
// Change highlighted button
});
}
timeline.play();
这将创建一个Timeline
,KeyFrame
的目标时间为1000,2000,3000 ......毫秒。
使用一个KeyFrame
的常量时间创建一个时间轴,并多次运行:
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1000), e -> {
// This will be called multiple times, each time reset the highlighted button and select a new one to highlight
}));
timeline.setCycleCount(buttoncount);
timeline.play();