我有两个圆,如果要按右键,则要顺时针旋转它们,如果要按左键,则要逆时针旋转,但是我的代码不起作用。
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.*;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.text.Font;
import javafx.scene.transform.Rotate;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.util.Duration;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
public class Main extends Application {
public static final double CIRCLES_CENTER_X = 600;
public static final double CIRCLES_CENTER_Y = 450;
public static final double CIRCLES_RADIUS = 15;
public static final double CIRCLES_DISTANCE = 300;
public static final double GAME_HEIGHT = 700;
public static final double GAME_WIDTH = 1200;
private Stage primaryStage;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
primaryStage.setMinWidth(GAME_WIDTH);
primaryStage.setMinHeight(GAME_HEIGHT);
final Scene scene;
BorderPane root = new BorderPane();
scene = new Scene(root, Main.GAME_WIDTH, Main.GAME_HEIGHT);
Circle orangeCircle = new Circle(Main.CIRCLES_CENTER_X + Main.CIRCLES_DISTANCE / 2 * cos(0),
Main.CIRCLES_CENTER_Y + Main.CIRCLES_DISTANCE / 2 * sin(0),
Main.CIRCLES_RADIUS, Color.ORANGE);
Circle yellowCircle = new Circle(Main.CIRCLES_CENTER_X - Main.CIRCLES_DISTANCE / 2 * cos(0),
Main.CIRCLES_CENTER_Y - Main.CIRCLES_DISTANCE / 2 * sin(0),
Main.CIRCLES_RADIUS, Color.YELLOW);
Pane game = new Pane(orangeCircle, yellowCircle);
root.setCenter(game);
SimpleIntegerProperty angle = new SimpleIntegerProperty(0);
root.setOnKeyPressed(ke -> {
if (ke.getCode().toString().equals("RIGHT")) {
angle.set(360);
}
if (ke.getCode().toString().equals("LEFT")) {
angle.set(-360);
}
});
root.setOnKeyReleased(ke -> {
if (ke.getCode().toString().equals("RIGHT")) {
angle.set(0);
}
if (ke.getCode().toString().equals("LEFT")) {
angle.set(0);
}
});
Rotate orangeCircleRotation = new Rotate(0, Main.CIRCLES_CENTER_X, Main.CIRCLES_CENTER_Y);
orangeCircle.getTransforms().add(orangeCircleRotation);
Rotate yellowCircleRotation = new Rotate(0, Main.CIRCLES_CENTER_X, Main.CIRCLES_CENTER_Y);
yellowCircle.getTransforms().add(yellowCircleRotation);
Timeline rotationAnimation = new Timeline();
rotationAnimation.setCycleCount(Timeline.INDEFINITE);
angle.addListener((ov, old_val, new_val) -> {
System.out.println("fk");
rotationAnimation.stop();
while (rotationAnimation.getKeyFrames().size() > 0) {
rotationAnimation.getKeyFrames().remove(0);
}
rotationAnimation.getKeyFrames().add(
new KeyFrame(Duration.millis(2000),
new KeyValue(orangeCircleRotation.angleProperty(), angle.getValue())));
rotationAnimation.getKeyFrames().add(
new KeyFrame(Duration.millis(2000),
new KeyValue(yellowCircleRotation.angleProperty(), angle.getValue())));
rotationAnimation.play();
}
);
primaryStage.setScene(scene);
primaryStage.show();
}
public Stage getPrimaryStage() {
return primaryStage;
}
}
它几乎可以正常工作,但是当我按下一个键并释放它时,圆圈并没有停止。它们只是开始向后旋转直到最后一个旋转变化点,并不断重复,所以当我再次按下该键时,它有时也会跳跃。(因为向后旋转已经到达终点并从头开始)(很难解释!您必须自己看看!)
有谁知道如何解决或实现这一目标?
最佳答案
在动画进行过程中,我不会尝试操作关键帧。相反,您可以暂停/播放动画并更改速率。这里唯一的“陷阱”是,似乎动画在暂停时会忽略速率变化,因此您需要在play()
之前调用setRate(...)
。
这是修改后的SSCCE:
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class RotatingCircles extends Application {
public static final double CIRCLES_CENTER_X = 600;
public static final double CIRCLES_CENTER_Y = 450;
public static final double CIRCLES_RADIUS = 15;
public static final double CIRCLES_DISTANCE = 300;
public static final double GAME_HEIGHT = 700;
public static final double GAME_WIDTH = 1200;
private Stage primaryStage;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
primaryStage.setMinWidth(GAME_WIDTH);
primaryStage.setMinHeight(GAME_HEIGHT);
final Scene scene;
BorderPane root = new BorderPane();
scene = new Scene(root, GAME_WIDTH, GAME_HEIGHT);
Circle orangeCircle = new Circle(CIRCLES_CENTER_X + CIRCLES_DISTANCE / 2 * cos(0),
CIRCLES_CENTER_Y + CIRCLES_DISTANCE / 2 * sin(0),
CIRCLES_RADIUS, Color.ORANGE);
Circle yellowCircle = new Circle(CIRCLES_CENTER_X - CIRCLES_DISTANCE / 2 * cos(0),
CIRCLES_CENTER_Y - CIRCLES_DISTANCE / 2 * sin(0),
CIRCLES_RADIUS, Color.YELLOW);
Pane game = new Pane(orangeCircle, yellowCircle);
root.setCenter(game);
Rotate orangeCircleRotation = new Rotate(0, CIRCLES_CENTER_X, CIRCLES_CENTER_Y);
orangeCircle.getTransforms().add(orangeCircleRotation);
Rotate yellowCircleRotation = new Rotate(0, CIRCLES_CENTER_X, CIRCLES_CENTER_Y);
yellowCircle.getTransforms().add(yellowCircleRotation);
Timeline rotationAnimation = new Timeline();
rotationAnimation.setCycleCount(Timeline.INDEFINITE);
rotationAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(2), new KeyValue(orangeCircleRotation.angleProperty(), 360)));
rotationAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(2), new KeyValue(yellowCircleRotation.angleProperty(), 360)));
root.setOnKeyPressed(ke -> {
if (ke.getCode() == KeyCode.RIGHT) {
rotationAnimation.play();
rotationAnimation.setRate(1);
} else if (ke.getCode() == KeyCode.LEFT) {
rotationAnimation.play();
rotationAnimation.setRate(-1);
}
});
root.setOnKeyReleased(ke -> {
rotationAnimation.pause();
});
primaryStage.setScene(scene);
primaryStage.show();
root.requestFocus();
}
public Stage getPrimaryStage() {
return primaryStage;
}
}
顺便说一句,在此代码中,您实际上不需要两个单独的旋转,因为它们是相同的。只需创建一个旋转并将其添加到两个圆的变换列表中即可。当然,您的实际代码可能有所不同...
关于java - 如何在javafx中更改按键的旋转方向,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37728542/