我正在尝试在JavaFX中实现矩形的左右移动。下面是我的代码:
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();
}
}
});
}
在这里,当我连续按任一向左/向右键(即,我没有松开键,但按住了几次)时,矩形移动但不连续。动画开始后,它会暂停一小部分时间。暂停后,动画将继续流畅。
如何摆脱使用KeyEvents进行的动画暂停?
我将使用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处理程序将速度设置回零。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句