我正在尝试在JavaFX中实现矩形形状的LEFT RIGHT移动。以下是我的代码:
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();
}
}
});
}
这里当我连续按下LEFT / RIGHT键时(即我没有释放键,我按住它一段时间)矩形移动但不连续。动画开始后,它会暂停一小段时间。暂停后,动画继续顺利进行。
如何摆脱使用KeyEvents暂停动画?
答案 0 :(得分:3)
我会使用AnimationTimer来移动矩形,只需更新一个表示按下键或释放键的速度的属性:
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);
}
}
});
更新:
每次JavaFX机制渲染帧时,AnimationTimer都会执行一次handle方法。传递给handle方法的long是渲染帧的时间戳,以纳秒为单位。
这种方式的工作方式是我们跟踪上次更新时间。 handle(...)方法计算自上次更新以来经过的时间,将其乘以矩形的速度,并以该量更新矩形的translateX。 AnimationTimer始终在运行,但最初速度设置为零,因此矩形不会移动。
keyPressed处理程序只是将速度改变为:如果向右移动则为正值,如果向左移动则为负值。 keyReleased处理程序将速度设置回零。