
本文介绍了如何在JavaFX游戏中获取时间轴动画中移动对象的实时坐标。通过getBoundsInParent()方法,可以获取节点相对于其父节点的边界信息,从而提取到考虑了所有变换(包括时间轴动画产生的位移)后的中心点坐标,方便实现激光射击等精确瞄准效果。
在JavaFX应用中,尤其是游戏开发中,经常需要获取动画对象的实时坐标,以便进行碰撞检测、目标跟踪或精确的视觉效果控制。当对象的位置由Timeline动画驱动时,直接从Timeline中获取坐标可能比较困难。本文将介绍一种简便的方法,通过Node类的getBoundsInParent()方法获取对象的实时坐标。
使用 getBoundsInParent() 获取坐标
getBoundsInParent()方法返回节点在其父坐标系中的边界(Bounds)。这个边界对象包含了节点的位置和尺寸信息,并且已经考虑了节点的所有变换,包括平移(translate)、旋转(rotate)、缩放(scale)等。因此,即使节点的位置是由Timeline动画改变的,getBoundsInParent()也能返回其当前的准确位置。
以下是如何使用getBoundsInParent()获取对象中心点坐标的示例代码:
立即学习“Java免费学习笔记(深入)”;
import javafx.scene.Node;
import javafx.geometry.Bounds;
public class CoordinateGetter {
public static void main(String[] args) {
// 假设 word.getWordBox() 返回一个 JavaFX Node 对象
Node wordBox = // ... 获取你的 wordBox 对象
// 获取 wordBox 在父容器中的边界
Bounds bounds = wordBox.getBoundsInParent();
// 从边界中提取中心点坐标
double x = bounds.getCenterX();
double y = bounds.getCenterY();
System.out.println("WordBox 的中心点坐标:x = " + x + ", y = " + y);
}
}代码解释:
- wordBox.getBoundsInParent(): 这一步获取wordBox节点在其父节点坐标系中的边界。返回的Bounds对象包含了wordBox的最小包围矩形,其坐标是相对于wordBox的父节点的。
- bounds.getCenterX() 和 bounds.getCenterY(): 这两个方法分别返回边界矩形的中心点X坐标和Y坐标。由于bounds是相对于父节点的,因此这两个坐标也是wordBox中心点相对于父节点的坐标。
示例:结合时间轴动画
假设你有一个Timeline动画,用于改变一个Rectangle的位置,你可以这样获取它的实时坐标:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.geometry.Bounds;
import java.util.Random;
public class TimelineCoordinateExample extends Application {
@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Rectangle rect = new Rectangle(50, 50, Color.RED);
root.getChildren().add(rect);
Random rand = new Random();
int wordTime = 1000; // 动画持续时间
Timeline timeline = new Timeline();
timeline.getKeyFrames().addAll(
new KeyFrame(Duration.millis(wordTime),
new KeyValue(rect.translateXProperty(), rand.nextInt(100, 500))),
new KeyFrame(Duration.millis(wordTime),
new KeyValue(rect.translateYProperty(), rand.nextInt(0, 150)))
);
timeline.setCycleCount(Timeline.INDEFINITE); // 无限循环
timeline.play();
// 定时获取坐标 (例如每秒一次)
Timeline coordinateUpdateTimeline = new Timeline(
new KeyFrame(Duration.seconds(1), event -> {
Bounds bounds = rect.getBoundsInParent();
double x = bounds.getCenterX();
double y = bounds.getCenterY();
System.out.println("Rectangle 的中心点坐标:x = " + x + ", y = " + y);
})
);
coordinateUpdateTimeline.setCycleCount(Timeline.INDEFINITE);
coordinateUpdateTimeline.play();
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Timeline Coordinate Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}在这个例子中,Rectangle的位置由Timeline动画控制。另一个Timeline (coordinateUpdateTimeline) 每秒钟获取一次Rectangle的中心点坐标并打印到控制台。 你会发现打印的坐标随着动画的进行而变化。
注意事项
- 确保在JavaFX应用程序线程中调用getBoundsInParent(),以避免线程安全问题。
- getBoundsInParent()返回的坐标是相对于节点的父节点的。如果需要相对于场景的坐标,可以使用localToScene()方法进行转换。
- 如果节点没有添加到场景图中,getBoundsInParent()可能返回不正确的结果。
总结
getBoundsInParent()方法提供了一种简单而有效的方式来获取JavaFX节点在时间轴动画中的实时坐标。通过获取节点的边界信息,可以轻松地提取到节点的中心点坐标,从而方便地实现各种复杂的动画效果和交互逻辑。在开发JavaFX游戏或需要精确控制对象位置的应用中,这是一个非常有用的技巧。










