Java:使用滑块更改矩形沿路径的速度

问题描述 投票:0回答:2

在我正在研究的程序中,我试图将其放置在滑块控制正方形沿着线的路径移动速度的位置。滑块可以工作,但问题在于,滑块仅在完成跟踪路径的正方形时才更改速度。我正在尝试使滑块在正方形运动时改变速度。我的代码在下面列出,我需要帮助。谢谢


package endofyearproject;

import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Slider;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Endofyearproject extends Application {
// public static void main(String[] args)
//{
//
// launch(args);
//
//}
   private boolean doAnother;
   private ColorPicker picker;
   private Rectangle rect;
   private Slider speed;

   @Override
   public void start(Stage stage) throws Exception {
       setSpeed(new Slider(0,96,12));
       speed.setTranslateX(50);
       speed.setTranslateY(450);
       speed.setPrefSize(360,20);
      // speed.setShowTickLabels(true);
       picker = new ColorPicker(Color.BLACK);
       picker.setOnAction(this::processpick);

       Text mytext = new Text(35, 100, "");
       rect = new Rectangle(30, 100, 30, 30);
       Group rectText = new Group(rect, mytext);

       Line myline1 = new Line(30, 360, 50, 50);
       Line myline2 = new Line(50, 50, 70, 80);
       Line myline3 = new Line(70, 80, 100, 150);
       Line myline4 = new Line(100, 150, 130, 20);
       Line myline5 = new Line(130, 20, 150, 360);
       Line myline6 = new Line(150, 360, 180, 280);
       Line myline7 = new Line(180, 280, 200, 330);
       Line myline8 = new Line(200, 330, 250, 70);
       Line myline9 = new Line(250, 70, 320, 360);
       Line myline10 = new Line(320, 360, 360, 360);
       Line myline11 = new Line(360, 360, 380, 390);
       Line myline12 = new Line(380, 390, 430, 25);
       Line myline13 = new Line(430, 25, 460, 370);

       Path path = new Path();
       path.getElements().add(new MoveTo(30, 360));
       path.getElements().add(new LineTo(50, 50));
       path.getElements().add(new LineTo(70, 80));
       path.getElements().add(new LineTo(100, 150));
       path.getElements().add(new LineTo(130, 20));
       path.getElements().add(new LineTo(150, 360));
       path.getElements().add(new LineTo(180, 280));
       path.getElements().add(new LineTo(200, 330));
       path.getElements().add(new LineTo(250, 70));
       path.getElements().add(new LineTo(320, 360));
       path.getElements().add(new LineTo(360, 360));
       path.getElements().add(new LineTo(380, 390));
       path.getElements().add(new LineTo(430, 25));
       path.getElements().add(new LineTo(460, 370));

       PathTransition pathTransition = new PathTransition();

       pathTransition.setNode(rectText);
       pathTransition.setPath(path);

       pathTransition.setAutoReverse(false);
       getSpeed().setValue(pathTransition.getCurrentRate());
       Button play = new Button("Play");
       play.setTranslateX(110);
       play.setTranslateY(400);

       play.setOnAction(new EventHandler<ActionEvent>() {
           public void handle(ActionEvent event) {
               pathTransition.stop();

               pathTransition.setDuration(Duration.seconds(getSpeed().getValue()));
               pathTransition.setCycleCount(1);
               pathTransition.play();
           }
       });
       Button pause = new Button("Pause");
       pause.setTranslateX(200);
       pause.setTranslateY(400);
       pause.setOnAction(new EventHandler<ActionEvent>() {
           public void handle(ActionEvent arg0) {
               pathTransition.pause();
           }
       });
       Button resume = new Button("Resume");
       resume.setTranslateX(300);
       resume.setTranslateY(400);
       resume.setOnAction(new EventHandler<ActionEvent>() {

           public void handle(ActionEvent arg0) {

               if (pathTransition.getStatus() == PathTransition.Status.PAUSED) {
                   pathTransition.play();
               }

           }
       });

       Group root = new Group(picker, rectText, myline1, myline2, myline3, myline4, myline5, myline6, myline7, myline8,
               myline9, myline10, myline11, myline12, myline13, getSpeed(), play, pause, resume);
       Scene scene = new Scene(root, 500, 500);
       stage.setTitle("Ride at Amusement Park");
       stage.setScene(scene);
       stage.show();

   }

   public void processpick(ActionEvent event) {
       rect.setFill(picker.getValue());
   }

   /**
   * @return the speed
   */
   public Slider getSpeed() {
       return speed;
   }


   public void setSpeed(Slider aSpeed) {
       speed = aSpeed;
   }

}
java javafx slider javafx-8
2个回答
2
投票

您可以将动画的rate属性绑定到Slider的值:

setSpeed(new Slider(0, 96, 1));

...

pathTransition.rateProperty().bind(speed.valueProperty());

注意,这种方式不能使用setter来分配rate属性。

((您当前的代码仅在按下按钮时更新值。)


0
投票

您可以尝试以下代码吗?在初始化PathTransition之后将其放置。我希望内嵌注释可以解释。

speed.valueProperty().addListener((obs, old, val) -> {
    if (pathTransition.getStatus() == Animation.Status.RUNNING) {
        // Get the current point in the duration
        double point = pathTransition.getCurrentTime().toMillis() / pathTransition.getDuration().toMillis();
        // Stop the animation
        pathTransition.stop();
        // Set new duration
        pathTransition.setDuration(Duration.seconds(speed.getValue()));
        // Compute the time to the current point.
        double jumpTo = Duration.seconds(speed.getValue()).toMillis() * point;
        // Jump to the current point
        pathTransition.jumpTo(Duration.millis(jumpTo));
        // And start the animation again
        pathTransition.play();
    }
});

此外,与实际问题无关,请尝试使用JavaFX提供的布局。比将所有节点包装在一个组中并放置它们要简单得多。

© www.soinside.com 2019 - 2024. All rights reserved.