在JavaFX中翻译过渡重置位置。

huangapple go评论81阅读模式
英文:

Translate transition reset position in javaFX

问题

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    final double lambda = 0.1; // 每毫秒的像素
    double posX = 100;
    double posY = 200;
    double time = 0;
    double velocityX = 1 * lambda;
    double velocityY = 0 * lambda;
    Circle circle = new Circle(posX, posY, 20, Color.AQUA);
    Circle ref1 = new Circle(100, 200, 5, Color.CADETBLUE);
    Circle ref2 = new Circle(400, 200, 5, Color.CADETBLUE);
    Circle ref3 = new Circle(100, 100, 5, Color.CADETBLUE);

    @Override
    public void start(Stage stage) throws Exception {
        Pane pane = new Pane();
        pane.getChildren().addAll(circle, ref1, ref2, ref3);

        BorderPane root = new BorderPane();
        root.setCenter(pane);
        root.setStyle("-fx-background-color: #29353B");
        double WIDTH = 800;
        double HEIGHT = 600;
        Scene scene = new Scene(root, WIDTH, HEIGHT);
        stage.setScene(scene);
        stage.show();

        move(3000);
    }

    public void move(double dt) // dt以毫秒为单位
    {
        System.out.println(circle.getCenterX() + ", " + circle.getCenterY());
        TranslateTransition translateTransition = new TranslateTransition(Duration.millis(dt), circle);
        //translateTransition.setInterpolator(Interpolator.LINEAR);
        translateTransition.setByX(this.velocityX * dt);
        translateTransition.setByY(this.velocityY * dt);
        translateTransition.setCycleCount(1);
        translateTransition.play();
        translateTransition.setOnFinished(actionEvent -> {
            updatePos(dt);
            move(2000);
        });
    }

    public void updatePos(double dt) {
        //this.posX += this.velocityX*dt;
        //this.posY += this.velocityY*dt;
        this.posX = 100;
        this.posY = 100;
        circle.setCenterX(this.posX);
        circle.setCenterY(this.posY);
    }
}
英文:

I'm trying to move a circle from (100,200) to (400,200) and after one cycle the circle should start moving from (100,100) to (200,100) and keep repeating that motion. After the first cycle I reset the position of the circle using circle.setCenterX(100) and circle.setCenterY(100). However, this is not reflected in the animation. The circle resets to (400,100) and keeps moving forward in the X direction instead of repeating the motion. I'm new to javaFX. Any help would be appreciated.

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Test extends Application
{
public static void main(String[] args)
{
launch(args);
}
final double lambda = 0.1; // pixel per millisecond
double posX = 100;
double posY = 200;
double time = 0;
double velocityX = 1*lambda;
double velocityY = 0*lambda;
Circle circle = new Circle(posX, posY, 20, Color.AQUA);
Circle ref1 = new Circle(100, 200, 5, Color.CADETBLUE);
Circle ref2 = new Circle(400, 200, 5, Color.CADETBLUE);
Circle ref3 = new Circle(100, 100, 5, Color.CADETBLUE);
@Override
public void start(Stage stage) throws Exception
{
Pane pane = new Pane();
pane.getChildren().addAll(circle, ref1, ref2, ref3);
BorderPane root = new BorderPane();
root.setCenter(pane);
root.setStyle("-fx-background-color: #29353B");
double WIDTH = 800;
double HEIGHT = 600;
Scene scene = new Scene(root, WIDTH, HEIGHT);
stage.setScene(scene);
stage.show();
move(3000);
}
public void move(double dt) // dt in milliseconds
{
System.out.println(circle.getCenterX()+", "+circle.getCenterY());
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(dt), circle);
//translateTransition.setInterpolator(Interpolator.LINEAR);
translateTransition.setByX(this.velocityX*dt);
translateTransition.setByY(this.velocityY*dt);
translateTransition.setCycleCount(1);
translateTransition.play();
translateTransition.setOnFinished(actionEvent -> { updatePos(dt); move(2000); });
}
public void updatePos(double dt)
{
//this.posX += this.velocityX*dt;
//this.posY += this.velocityY*dt;
this.posX = 100;
this.posY = 100;
circle.setCenterX(this.posX);
circle.setCenterY(this.posY);
}
}

答案1

得分: 3

TranslateTransition会修改translateXtranslateY属性,而不是centerXcenterY属性。如果你在动画完成后修改centerXcenterY属性,还应该将translateXtranslateY重置为0,以便圆圈出现在这些坐标处:

public void updatePos(double dt) {
    //this.posX += this.velocityX*dt;
    //this.posY += this.velocityY*dt;
    this.posX = 100;
    this.posY = 100;
    circle.setCenterX(this.posX);
    circle.setCenterY(this.posY);
    circle.setTranslateX(0);
    circle.setTranslateY(0);
}

或者,你可以使用Timeline而不是TranslateTransition直接在动画中操作centerXcenterY属性:

public void move(double dt) /* dt in milliseconds */ {
    System.out.println(circle.getCenterX() + ", " + circle.getCenterY());
    double targetX = circle.getCenterX() + this.velocityX * dt;
    double targetY = circle.getCenterY() + this.velocityY * dt;
    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(dt),
            new KeyValue(circle.centerXProperty(), targetX),
            new KeyValue(circle.centerYProperty(), targetY)));

    timeline.setOnFinished(actionEvent -> {
        updatePos(dt);
        move(2000);
    });
    timeline.play();
}

public void updatePos(double dt) {
    this.posX = 100;
    this.posY = 100;
    circle.setCenterX(this.posX);
    circle.setCenterY(this.posY);
}
英文:

The TranslateTransition modifies the translateX and translateY properties, not the centerX and centerY properties. If you modify the centerX and centerY properties when the animation is complete, you should also reset translateX and translateY to 0 for the circle to appear at those coordinates:

  public void updatePos(double dt) {
//this.posX += this.velocityX*dt;
//this.posY += this.velocityY*dt;
this.posX = 100;
this.posY = 100;
circle.setCenterX(this.posX);
circle.setCenterY(this.posY);
circle.setTranslateX(0);
circle.setTranslateY(0);
}

Alternatively, you could use a Timeline instead of a TranslateTransition to directly manipulate the centerX and centerY properties in the animation:

public void move(double dt) /* dt in milliseconds */ {
System.out.println(circle.getCenterX() + ", " + circle.getCenterY());
double targetX = circle.getCenterX() + this.velocityX * dt;
double targetY = circle.getCenterY() + this.velocityY * dt;
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(dt),
new KeyValue(circle.centerXProperty(), targetX),
new KeyValue(circle.centerYProperty(), targetY)));
timeline.setOnFinished(actionEvent -> {
updatePos(dt);
move(2000);
});
timeline.play();
}
public void updatePos(double dt) {
this.posX = 100;
this.posY = 100;
circle.setCenterX(this.posX);
circle.setCenterY(this.posY);
}

huangapple
  • 本文由 发表于 2020年8月17日 19:51:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63450221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定