延迟功能不能正常工作?
Delay function does not work properly?
我是这个社区的新手,我有一个问题我自己似乎无法解决,甚至在搜索 google 并向朋友寻求答案时也是如此。
我正在制作一个小模式记忆游戏,它围绕着按特定顺序单击按钮,每次成功都会变得更难,直到失败为止。通过 javafx GUI 进行设置,IDE 是 NetBeans 8.1。
现在,例如,当一个序列通过按钮发光显示给玩家时,每个按钮和序列中的下一个按钮之间需要有一个延迟,以便玩家知道他们的顺序d 单击按钮。
我尝试了三个延迟函数,但都产生了相同的结果,它们是 Thread.sleep 、时间轴和过渡。
如您在上图中所见,此 for 循环随机选择游戏中 5 个按钮之一,并使其发光,以便玩家知道这是序列中的下一个按钮。所有这些都发生在循环的每次迭代中创建的新时间轴内,因此每次选择和显示按钮时都会发生延迟。
但是,当我执行这部分代码时,我看到的很奇怪。 for 循环存在于按钮事件处理程序中。当我单击此按钮时,我确实看到了延迟,但不是在每个按钮和序列中的下一个按钮之间,而是在单击按钮和立即显示整个序列之间存在延迟。
那么如何让这个延迟按预期工作呢?据我所知,时间线是实现延迟的最佳方法之一,与不可靠的 Thread.sleep 方法相反,后者在执行代码时会大大降低设备速度。
作为参考,第一、第二、第三、第四和第五是按钮的名称。 storebutton函数存储当前按钮的位置,供以后在游戏中参考(那句话可以忽略,不影响延时的实现),borderglow是按钮发光效果,generator是从Randomclass 生成一个介于 0 和 5 之间的随机整数。
请您慢慢考虑这个问题,这很令人费解,我无法解决这个问题。在你的 IDE 中尝试这个想法,甚至可以更好地理解问题。任何帮助将不胜感激。提前致谢:)
正在调用 Timeline#play
运行 Timeline
,但立即 returns。您实际上是在创建多个单独的时间线,并且几乎同时 运行 将它们全部连接起来。
要达到预期效果,您有以下几种选择:
创建一个单独的时间线,向其中添加 KeyFrame
s,每个时间线依次增加:
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
s 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();
A 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);
我是这个社区的新手,我有一个问题我自己似乎无法解决,甚至在搜索 google 并向朋友寻求答案时也是如此。
我正在制作一个小模式记忆游戏,它围绕着按特定顺序单击按钮,每次成功都会变得更难,直到失败为止。通过 javafx GUI 进行设置,IDE 是 NetBeans 8.1。
现在,例如,当一个序列通过按钮发光显示给玩家时,每个按钮和序列中的下一个按钮之间需要有一个延迟,以便玩家知道他们的顺序d 单击按钮。 我尝试了三个延迟函数,但都产生了相同的结果,它们是 Thread.sleep 、时间轴和过渡。
如您在上图中所见,此 for 循环随机选择游戏中 5 个按钮之一,并使其发光,以便玩家知道这是序列中的下一个按钮。所有这些都发生在循环的每次迭代中创建的新时间轴内,因此每次选择和显示按钮时都会发生延迟。
但是,当我执行这部分代码时,我看到的很奇怪。 for 循环存在于按钮事件处理程序中。当我单击此按钮时,我确实看到了延迟,但不是在每个按钮和序列中的下一个按钮之间,而是在单击按钮和立即显示整个序列之间存在延迟。
那么如何让这个延迟按预期工作呢?据我所知,时间线是实现延迟的最佳方法之一,与不可靠的 Thread.sleep 方法相反,后者在执行代码时会大大降低设备速度。
作为参考,第一、第二、第三、第四和第五是按钮的名称。 storebutton函数存储当前按钮的位置,供以后在游戏中参考(那句话可以忽略,不影响延时的实现),borderglow是按钮发光效果,generator是从Randomclass 生成一个介于 0 和 5 之间的随机整数。
请您慢慢考虑这个问题,这很令人费解,我无法解决这个问题。在你的 IDE 中尝试这个想法,甚至可以更好地理解问题。任何帮助将不胜感激。提前致谢:)
正在调用 Timeline#play
运行 Timeline
,但立即 returns。您实际上是在创建多个单独的时间线,并且几乎同时 运行 将它们全部连接起来。
要达到预期效果,您有以下几种选择:
创建一个单独的时间线,向其中添加
KeyFrame
s,每个时间线依次增加: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
s 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();
A 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);