【问题标题】:How can I make a key get autopressed faster in Java?如何在 Java 中更快地自动按下键?
【发布时间】:2017-03-23 14:31:44
【问题描述】:

我正在尝试制作乒乓球游戏,但动作很笨拙;每当我按住一个键进行桨移动时,都会有一点延迟。

例如,我按住一个键,桨会移动一次,然后需要一秒钟才能再次开始连续移动。

有人告诉我这是操作系统的特性,而不是 Java 的特性;但是,我仍然想在 Java 中找到一种解决方法,以便从一开始就平滑且连续地移动,而不必等待操作系统开始自动按键。

有人可以帮忙吗? (我尝试过布尔值和键侦听器以及“while”循环,但这些对我不起作用。从这些失败的尝试中摘录的一段写在下面:)

root.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            switch (event.getCode()) {
                case UP:    paddle1Up = true; 
                            break;
                case DOWN:  paddle1Down = true; 
                            break;

                case W:  paddle2Up  = true; 
                            break;
                case S: paddle2Down  = true; 
                            break;
            }
        }
    });

    root.setOnKeyReleased(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            switch (event.getCode()) {
                case UP:    paddle1Up = false; 
                            break;
                case DOWN:  paddle1Down = false; 
                            break;

                case W:  paddle2Up  = false; 
                            break;
                case S: paddle2Down  = false; 
                            break;
            }
        }
    });

    root.requestFocus(); 

    primaryStage.setTitle("Pong");
    primaryStage.setScene(scene);
    primaryStage.setOnCloseRequest((event)->System.exit(0));
    primaryStage.show();

    // This is the main animation thread
    new Thread(() -> {
        while (true) {
            sim.evolve(1.0);
            while (paddle1Up){
                sim.movePaddle(sim.getPaddle1(), 0, -1);
            }
            while (paddle1Down){
                sim.movePaddle(sim.getPaddle1(), 0, 1);
            }
            while (paddle2Up){
                sim.movePaddle(sim.getPaddle2(), 0, -1);
            }
            while (paddle2Down){
                sim.movePaddle(sim.getPaddle2(), 0, 1);
            }

            Platform.runLater(()->sim.updateShapes());
            try {
                Thread.sleep(25);
            } catch (InterruptedException ex) {

            }
        }
    }).start();
}

【问题讨论】:

  • 您可以考虑不重置 keyup 事件的值。现在这将导致极快地移动到底部。为了避免这种情况,请计算自上次调用 while 循环以来的时间差,并将其与您希望使用的速度相乘。
  • 谢谢,但您能否解释一下如何计算这个时差?我不确定我明白这里的意思。
  • 只需保存最后一个循环的 System.currentTimeMillis() 并从当前循环中减去它。有了这个,你就有了自上次循环以来的毫秒数。现在您可以简单地计算“条”应随您的速度移动多远。基本上时差/1000*(speedInCMperSec)
  • 啊,我明白了。谢谢!但是,另一个问题:回到原来的评论,建议是不要重置 keyup 事件的值。这样做的目的是什么?这不是意味着桨不可能保持静止吗?
  • 啊,是的,这是真的,如果你在 keyup 事件中将速度设置为零会更好。然后它应该像预期的那样工作

标签: java keyboard keyevent


【解决方案1】:

很确定你需要写

case KeyEvent.VK_UP:

当然,除非你扩展 KeyEvent 类。

另外我认为你的 while 循环中没有必要有一个 while 循环,而是坚持使用 if 语句:

        while (true) {
        sim.evolve(1.0);
        if (! paddle1Up){
            sim.movePaddle(sim.getPaddle1(), 0, -1);
        }

也不确定是否有意,请注意 if 语句(您的 while 循环)中的 !

我以前见过很多类似的案例。我也经历过一次,虽然我不确定原因。现在很难说没有看到更多代码,但我强烈推荐implementskeylistener 并使用那里的方法,与您的代码非常相似,它应该可以毫无问题地工作。 您可能已经阅读过这个post 或这个post,如果没有,也许会有所帮助。

希望对你有用。

【讨论】:

  • 是的,“!”在 if 语句中是一个错字。现在修好了。谢谢您的帮助!稍后将对此进行更多研究。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 2012-01-30
  • 2011-12-12
  • 2015-10-14
  • 2018-04-24
相关资源
最近更新 更多