我通过尝试构建一个(非常)小型的平台游戏来学习 JavaFX。我认为沿着弧形使用 PathTransition 来模拟跳跃可能是个好主意。像这样:
import javafx.util.Duration;
import javafx.animation.PathTransition;
import javafx.scene.shape.Arc;
public void jump() {
PathTransition jump = new PathTransition();
Arc path = new Arc(
figure().getX() + 20, //figure is a custom shape
figure().getY() + figure().getHeight() / 2,
20, 80, 360, 180);
jump.setPath(path);
jump.setNode(figure);
jump.setAutoReverse(false);
jump.setDuration(Duration.millis(3000));
jump.setCycleCount(1);
jump.play();
}
事件处理程序:
figure.setOnKeyPressed((e) -> {
if (e.getCode() == KeyCode.SPACE) {
jump();
}
});
我发现这样做实际上会让我的人物向后跳跃,因为动画从弧线的右端开始,在左端结束。我尝试查看 Arc 的文档和 PathTransition但找不到任何东西可以帮助我解决问题。我在这里缺少什么?
最佳答案
您提供给 Arc
构造函数的最后两个值是弧的起始角度和角长度(以度为单位)。角度是相对于正 x 轴逆时针方向测量的。因此,您从 360 度(当然相当于 0 度:即 (centerX + radiusX, centerY)
)开始,逆时针(向上和向左)旋转半圈。要向右跳转,我认为您希望起始角度为 180
,角长度为 -180
(负值表示顺时针旋转,a半椭圆)。
请注意,PathTransition
通过更改其 translateX
和 translateY
属性,沿路径移动节点的中心。因此,要从负 x 轴到正 x 轴顺时针旋转半圈,您需要将 centerX
作为形状的初始水平中心,加上 radiusX
> 和 centerY
作为形状的初始垂直中心。
这是一个按照您想要的方式跳转的 SSCCE(我认为...)。我在 Arc 上使用了 set 方法而不是构造函数,只是为了清楚地了解每个值的作用。如果您愿意,您可以使用构造函数实现相同的目的。
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ArcTransitionTest extends Application {
private final double xJumpRadius = 20 ;
private final double yJumpRadius = 80 ;
@Override
public void start(Stage primaryStage) {
Rectangle rect = new Rectangle(50, 200, 50, 100);
rect.setFill(Color.CORNFLOWERBLUE);
Button left = new Button("<");
left.setOnAction(e -> jumpLeft(rect));
Button right = new Button(">");
right.setOnAction(e -> jumpRight(rect));
HBox controls = new HBox(5, left, right);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
Pane pane = new Pane(rect);
BorderPane root = new BorderPane(pane, null, null, controls, null);
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
private void jumpRight(Rectangle rect) {
jump(rect, 180, -180, getHorizontalCenter(rect) + xJumpRadius, getVerticalCenter(rect));
}
private void jumpLeft(Rectangle rect) {
jump(rect, 0, 180, getHorizontalCenter(rect) - xJumpRadius, getVerticalCenter(rect));
}
private void jump(Rectangle rect, double startAngle, double angularLength, double centerX, double centerY) {
Arc arc = new Arc();
arc.setCenterX(centerX);
arc.setCenterY(centerY);
arc.setRadiusX(xJumpRadius);
arc.setRadiusY(yJumpRadius);
arc.setStartAngle(startAngle);
arc.setLength(angularLength);
PathTransition transition = new PathTransition(Duration.seconds(1), arc, rect);
transition.playFromStart();
}
private double getHorizontalCenter(Rectangle rect) {
return rect.getX() + rect.getTranslateX() + rect.getWidth() / 2 ;
// Alternatively:
// Bounds b = rect.getBoundsInParent();
// return (b.getMinX() + b.getMaxX()) / 2 ;
}
private double getVerticalCenter(Rectangle rect) {
return rect.getY() + rect.getTranslateY() + rect.getHeight() / 2 ;
// Alternatively:
// Bounds b = rect.getBoundsInParent();
// return (b.getMinY() + b.getMaxY()) / 2 ;
}
public static void main(String[] args) {
launch(args);
}
}
关于java - 如何更改 JavaFX 中 PathTransition 上节点的起始位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30327580/