【问题标题】:How to detect key event in diapason of time JavaFX如何检测时间 JavaFX 中的关键事件
【发布时间】:2017-02-06 11:14:31
【问题描述】:

我正在制作简单的宇宙飞船游戏。我有一个发射火箭的玩家(太空船)。当按下空格键时,玩家发射火箭。问题是,当我持有“空间”时,火箭不断发射。例如,我怎样才能防止这种影响并让每 2 秒检测一次按下空格键(并且只发射一枚火箭)?

【问题讨论】:

  • 所以你想在按下空格键时每 n 秒发射一次,或者你想在每次按下空格键时发射一枚火箭?
  • 我想在每次飞船开火时禁用空格键 2 秒。
  • @JonK 虽然概念相似,但这是 JavaFX 中的问题,而不是 Swing。我认为不给 JavaFX 机会以其他方式实现它是不公平的。
  • @user1803551 有什么不同?
  • @James_D JavaFX 有其他方法可以做到这一点,但不适用于 Swing,反之亦然。答案可能不同。我正要发布一个不适合其他问题的仅限 JavaFX 的答案。

标签: java javafx


【解决方案1】:

您可以尝试创建一个列表来存储按下的按键。按下按钮后,侦听器将该按钮添加到列表中,并开始计算压力时间。不确定这是否是最好的方法,但我知道,当开发人员想要一次处理几个按下的键时使用相同的过程。

【讨论】:

    【解决方案2】:

    你可以在你的Ship类中存储它是否准备好发射火箭,然后在发射火箭的方法中,检查这个成员。

    在火箭发射时将此成员设置为 false,然后您可以启动 Timeline 例如,它将在完成时重置标志。

    船级

    public class Ship {
    
        private boolean readyToFireRocket = true;
    
        private static final double ROCKET_LAUNCHING_DELAY = 2d;
    
        public void fireRocket() {
            if(readyToFireRocket) {
                readyToFireRocket = false;
                System.out.println("Rocket is fired");
    
                KeyFrame keyFrame = new KeyFrame(Duration.seconds(ROCKET_LAUNCHING_DELAY),
                    e -> readyToFireRocket = true);
                Timeline reloadRockets = new Timeline(keyFrame);
                reloadRockets .play();
            }
        }
    }
    

    一个示例应用程序

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            Parent root = new BorderPane();
            Ship ship = new Ship();
    
            Scene scene = new Scene(root, 300, 275);
            scene.setOnKeyPressed(e -> {
                if(e.getCode() == KeyCode.SPACE) {
                    ship.fireRocket();
                }
            });
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

      【解决方案3】:

      一种选择是在使用事件处理程序时将其注销 2 秒(并在持续时间结束时重新注册)。我假设您正在使用 setOnKeyPressed(e -> ...) 注册对按下 space 作出反应的处理程序。

      • 创建并保存对该处理程序的引用,以便您可以随意注册和取消注册。
      • 创建一个延迟 2 秒的 PauseTransition,用于在上述处理程序完成时注册(什么都不做)。
      • handle() 方法中,取消注册处理程序并开始转换。

      这是一个例子:

      public class FXExmple extends Application{
      
          private Button button = new Button("PRESS SPACE");
          private PauseTransition pt = new PauseTransition(Duration.seconds(2));
      
          @Override
          public void start(Stage stage) throws Exception {
      
              MyEventHandler eh = new MyEventHandler();
              pt.setOnFinished(e -> button.setOnKeyPressed(eh));
              button.setOnKeyPressed(eh);
      
              Pane pane = new Pane();
              pane.getChildren().add(button);
              Scene scene = new Scene(pane);
              stage.setScene(scene);
              stage.sizeToScene();
              stage.show();
          }
      
          private class MyEventHandler implements EventHandler<KeyEvent> {
      
              @Override
              public void handle(KeyEvent event) {
      
                  System.out.println("FIRED");
                  button.setOnKeyPressed(null);
                  pt.play();
              }
          }
      
          public static void main(String[] args) {
      
              launch(args);
          }
      }
      

      请注意,这不会让您很好地控制持续时间,因为存在与(取消)注册处理程序和启动转换相关的持续时间,但它们非常小。操作系统发送事件的频率也有限制,因此,如果您打算将延迟降至约 50 毫秒 - 请注意。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 2019-07-18
        相关资源
        最近更新 更多