簡體   English   中英

如何在javafx中更改按鍵的旋轉方向

[英]how to change the rotation direction on keypress in javafx

我有兩個圓,如果要按右鍵,則要順時針旋轉它們,如果要按左鍵,則要逆時針旋轉,但是我的代碼不起作用。

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;
    }
}

它幾乎可以正常工作,但是當我按下一個鍵並釋放它時,圓圈並沒有停止。 它們只是開始向后旋轉直到最后一個旋轉變化點,並不斷重復,所以當我再次按下該鍵時,它有時也會跳躍。(因為向后旋轉已經到達終點並從頭開始)(很難解釋!您必須自己看看!)有人知道如何解決或實現此目標嗎?

在動畫進行過程中,我不會嘗試操作關鍵幀。 相反,您可以暫停/播放動畫並更改速率。 這里唯一的“陷阱”是,似乎動畫在暫停時會忽略速率變化,因此您需要 setRate(...) 之前調用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;
    }
}

順便說一句,在此代碼中,您實際上不需要兩個單獨的旋轉,因為它們是相同的。 只需創建一個旋轉並將其添加到兩個圓的變換列表中即可。 當然,您的實際代碼可能有所不同...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM