4

我有 3D 场景,并且场景中有窗格,它具有 x 轴的旋转变换,我想将此窗格用作战略游戏板,但我有问题。

当我在窗格中输入鼠标时,它给了我错误的光标位置。

例如,当我从窗格内的左上角(红色圆圈)输入鼠标(带黑色边框的旋转窗格)时,它应该显示我(0,0)作为窗格内的光标位置,但它显示类似(200、400)的内容。

带有黑色边框的旋转窗格

我怎么解决这个问题?

或者换句话说,我怎样才能获得节点上相对于节点及其变换的鼠标坐标?

这是一个例子:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.RotateBuilder;
import javafx.stage.Stage;


public class JFXRotationXOrds  extends Application{

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox root = new VBox();
        root.getChildren().add(new Rectangle(20, 20, Color.BLUE));  
        root.getChildren().add(new Circle(20, Color.RED));
        //root.rotateProperty().set(30);
        root.getTransforms().add(RotateBuilder.create().angle(-30).pivotX(0).pivotY(100).axis(new Point3D(1, 0, 0)).build());
        root.setStyle("-fx-border-color: black; -fx-border-width:5; ");

        root.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent arg0) {
                if(arg0.getEventType() == MouseEvent.MOUSE_MOVED){
                    System.out.println(arg0.getX() + "," + arg0.getY());
                }

            }
        });

        Scene scene = new Scene(root, 200, 500);
        primaryStage.setTitle("Rotation Coordinates Example");
        primaryStage.setScene(scene);
        scene.setCamera(PerspectiveCameraBuilder.create().fieldOfView(10).build());
        primaryStage.show();

    }

    public static void main(String[] args){
        Application.launch(args);
    }
}
4

2 回答 2

2

更新

该问题已在JDK8 Early Access Release中得到修复。你可以下载那个版本,或者等它出来。作为这张票的一部分,它已在 2 月修复:RT-28129

已编辑

在 JavaFX Jira 上输入了一张票。您可以关注它以查看状态更新。

我已经更新了演示以反映您的问题。当转换使用 z 轴时它似乎有效(昨天 - 今天对我不同),但当转换在 X 或 Y 轴上时不起作用。

希望这对您有所帮助。

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point3D;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.RotateBuilder;
import javafx.stage.Stage;


public class JFXRotationXOrds  extends Application{

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox root = new VBox();
        final Rotate rotate = RotateBuilder.create().angle(80).pivotX(100).pivotY(100).pivotZ(0).axis(new Point3D(1,0,0)).build();
        root.getTransforms().add(rotate);
        root.setStyle("-fx-border-color: black; -fx-border-width:5; ");

        root.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent arg0) {
                if(arg0.getEventType() == MouseEvent.MOUSE_MOVED){
                    System.out.println(arg0.getSceneX() + "," + arg0.getSceneY());
                }
            }
        });

        Scene scene = new Scene(root, 200, 500);
        PerspectiveCamera camera = new PerspectiveCamera();
        scene.setCamera(camera);
        primaryStage.setTitle("BorderPane Example");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args){
        Application.launch(args);
    }
}
于 2013-08-20T15:23:24.543 回答
0

由于您没有发布任何代码,这听起来很明显,但是您是否将鼠标事件处理程序添加到窗格中?如果是这样(在我尝试重新创建您的问题时), event.getX() 和 event.getY() 方法返回了预期的位置。

(您使用 getSceneX() 和 getSceneY() 吗?在这种情况下更改为 getX() 和 getY())

另一种方法是通过窗格的位置更正您获得的鼠标位置(场景中的位置)。

您可以对 x、y、z 轴执行此操作:

while (node != null){
   shift += node.getLayoutY(); 
   node = node.getParent();
}

然后将这个移位减去你得到的指针的位置

编辑:查看您的代码后,您似乎正在将 MouseEvent 处理程序添加到根对象。因此,当鼠标在根对象上时触发该事件。例如,如果将其添加到矩形中,则鼠标的位置将相对于矩形。

以下代码对我有用(但可能无法很好地重现您的问题)。

公共类 JFXRotationXOrds 扩展应用程序{

@Override
public void start(Stage primaryStage) throws Exception {
    VBox root = new VBox();

    Rectangle rect = new Rectangle(20, 20, Color.BLUE);
    rect.setOnMouseMoved(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent arg0) {
            if(arg0.getEventType() == MouseEvent.MOUSE_MOVED){
                System.out.println("Rect : " + arg0.getX() + "," + arg0.getY());
            }

        }
    });
    root.getChildren().add(rect);  
    root.getChildren().add(new Circle(20, Color.RED));
    //root.rotateProperty().set(30);
    root.getTransforms().add(RotateBuilder.create().angle(30).pivotX(0).pivotY(100).pivotZ(100).build());
    root.setStyle("-fx-border-color: black; -fx-border-width:5; ");

    root.setOnMouseMoved(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent arg0) {
            if(arg0.getEventType() == MouseEvent.MOUSE_MOVED){
                System.out.println(arg0.getX() + "," + arg0.getY());
            }

        }
    });

    Scene scene = new Scene(root, 200, 500);
    primaryStage.setTitle("Rotation Coordinates Example");
    primaryStage.setScene(scene);
    primaryStage.show();

}

public static void main(String[] args){
    Application.launch(args);
}
}
于 2013-08-20T14:38:23.240 回答