如何获得流畅的动画与JavaFX的重点preSS事件? [英] How to get smooth animation with KeyPress event in javaFX?

查看:246
本文介绍了如何获得流畅的动画与JavaFX的重点preSS事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现在JavaFX中一个矩形的左右运动。下面是我的code:

I am trying to implement LEFT RIGHT movement of a rectangle shape in JavaFX. Below is my code:

public void start(Stage primaryStage) throws Exception {
    AnchorPane ancPane = new AnchorPane();      
    final Rectangle rect = new Rectangle();
    rect.setHeight(50);
    rect.setWidth(50);
    ancPane.getChildren().add(rect);
    Scene scene = new Scene(ancPane, 400, 200, Color.GREEN); 
    primaryStage.setScene(scene);
    primaryStage.show();


    scene.setOnKeyPressed(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent keyEvent) {
            System.out.println("hello");

            if(keyEvent.getCode().toString() == "RIGHT"){
                System.out.println("Move Right");
                TranslateTransition translateTransitionRight = new TranslateTransition();
                translateTransitionRight.setDuration(Duration.millis(200));
                translateTransitionRight.setNode(rect);
                translateTransitionRight.setFromX(rect.getTranslateX());
                translateTransitionRight.setToX(rect.getTranslateX()+30);
                translateTransitionRight.play();
            }

            if(keyEvent.getCode().toString() == "LEFT"){
                System.out.println("Move Left");
                TranslateTransition translateTransitionRight = new TranslateTransition();
                translateTransitionRight.setDuration(Duration.millis(200));
                translateTransitionRight.setNode(rect);
                translateTransitionRight.setFromX(rect.getTranslateX());
                translateTransitionRight.setToX(rect.getTranslateX()-30);
                translateTransitionRight.play();
            }               
        }
    });

}

下面当我preSS是左/右方向键连续(即我不释放的键,我认为它的一些次)矩形移动,但不会持续。它暂停时间一小部分的动画刚开始之后。暂停之后,动画继续顺利进行。

Here when I press either LEFT/RIGHT key continuously (i.e. I don't released the key, I hold it for some times) the rectangle moves but not continuously. It pauses for a small fraction of time just after animation started. After the pause the animation continues smoothly.

我怎样才能使用的KeyEvent摆脱这种暂停动画的?

How can I get rid of this pausing of animation with KeyEvents?

推荐答案

我会用一个AnimationTimer用于移动矩形,只是更新属性重新presenting上pssed或释放键键$ P $速度:

I would use an AnimationTimer for moving the rectangle, and just update a property representing the velocity on key pressed or key released:

final Rectangle rect = ... ;

final double rectangleSpeed = 100 ; // pixels per second
final double minX = 0 ;
final double maxX = 800 ; // whatever the max value should be.. can use a property and bind to scene width if needed...
final DoubleProperty rectangleVelocity = new SimpleDoubleProperty();
final LongProperty lastUpdateTime = new SimpleLongProperty();
final AnimationTimer rectangleAnimation = new AnimationTimer() {
  @Override
  public void handle(long timestamp) {
    if (lastUpdateTime.get() > 0) {
      final double elapsedSeconds = (timestamp - lastUpdateTime.get()) / 1_000_000_000.0 ;
      final double deltaX = elapsedSeconds * rectangleVelocity.get();
      final double oldX = rect.getTranslateX();
      final double newX = Math.max(minX, Math.min(maxX, oldX + deltaX));
      rect.setTranslateX(newX);
    }
    lastUpdateTime.set(timestamp);
  }
};
rectangleAnimation.start();

scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
  @Override
  public void handle(KeyEvent event) {
    if (event.getCode()==KeyCode.RIGHT) { // don't use toString here!!!
      rectangleVelocity.set(rectangleSpeed);
    } else if (event.getCode() == KeyCode.LEFT) {
      rectangleVelocity.set(-rectangleSpeed);
    }
  }
});

scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
  @Override
  public void handle(KeyEvent event) {
    if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT) {
      rectangleVelocity.set(0);
    }
  }
});

更新:

借助 AnimationTimer 每一次执行它的处理方法时间一帧由JavaFX的机构呈现。长传递到处理方法是渲染帧的时间戳,以纳秒。

The AnimationTimer executes its handle method once each time a frame is rendered by the JavaFX mechanism. The long passed into the handle method is a timestamp of the render frame, in nanoseconds.

这工作的方式是,我们跟踪的最后更新时间。所述手柄(...)方法计算所经过的时间自上次更新,由矩形的速度相乘,并通过该金额更新矩形的设置translateX。该AnimationTimer总是处于运行状态,但最初速度被设置为零,因此矩形不动。

The way this works is that we keep track of the last update time. The handle(...) method computes the elapsed time since the last update, multiplies it by the rectangle's velocity, and updates the translateX of the rectangle by that amount. The AnimationTimer is always running, but initially the velocity is set to zero so the rectangle doesn't move.

关键pressed处理程序仅改变速度。上调用keyReleased处理程序设定速度回零。

The keyPressed handler simply changes the velocity: to a positive value if moving right and a negative value if moving left. The keyReleased handler sets the velocity back to zero.

这篇关于如何获得流畅的动画与JavaFX的重点preSS事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆