如何在 GridPane 中获取 Rectangle 的 screen/scene 中心 x,y?

How to get screen/scene center x,y of Rectangle within a GridPane?

我正在使用 JavaFX8 实现一个简单的棋盘游戏。

对于游戏板,我的决定是使用 10x10 GridPane 并在表单的初始化方法中用矩形填充它的单元格。

private void drawBoard() {
    gridpaneBoard.getChildren().clear();
    for (int y = 0; y < gridpaneBoard.getRowConstraints().size(); y++)
        for (int x = 0; x < gridpaneBoard.getColumnConstraints().size(); x++) {
            Rectangle rect = new Rectangle(55,55);
            rect.setStroke(Color.BLACK);

            Tile tile = GameController.getInstance().getBoard().getTile(x, y);
            if (tile.hasBranch())
                rect.setFill(QuestionDifficulty.values()[tile.getBranch()
                                                         .getQuestion().getQuestion()
                                                         .getLevel()].getColor());
            else
                rect.setFill(Color.WHITE);

            gridpaneBoard.add(rect, x, y);
            gridpaneBoard.add(new Label(String.valueOf(tile.getNumber())), x, y);
        }
}

为了在掷骰子后制作玩家令牌移动动画,我想我需要知道每个方块的中心 x 和中心 y(以创建从源方块到目标方块的路径转换)。

我试过对其他人的问题给出的各种答案,但对我来说一切都返回 0,0。

这是这个场景中的容器层级:

这是目前输出的样子:

如果 GridPane 适合我要实现的目标,我如何获得 child(在本例中为矩形)屏幕/场景中心 x、y?

如果 GridPane 不好,你能给我指出替代方案以及我如何才能实现我想要的结果吗..

谢谢!

您可以使用:

-GridPane.getColumnIndex(Node) 获取列索引。

-GridPane.getRowIndex(Node)获取行索引。

-既然你知道 child (Rectangle) 的 WidthHeight (55,55) 你可以计算它的 centerXcenterY,这是相对于它在容器中的位置的,但是由于您使用的是 GridPane,我认为这是不可能的,因为这个有约束。您可以通过更改 object 的容器或在另一个 raw/column 中完全重绘它来修复它,这是一个示例 Replace a node at (row,col).

您只需调用 getBoundsInParent 即可获取 Node 在其父项中的尺寸。

下面的示例有点简化,但它仍然应该演示该方法:

@Override
public void start(Stage primaryStage) {
    GridPane gridpaneBoard = new GridPane();
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 10; x++) {
            Rectangle rect = new Rectangle(55, 55);
            rect.setStroke(Color.BLACK);

            rect.setFill((x + y) % 2 == 0 ? Color.WHITE : Color.DARKGRAY);

            gridpaneBoard.add(rect, x, y);
        }
    }

    gridpaneBoard.setOnMouseClicked(evt -> {
        Node target = evt.getPickResult().getIntersectedNode();

        if (target != gridpaneBoard) {
            // in your case you'd need to make sure this is not the Label
            Bounds bounds = target.getBoundsInParent();
            System.out.println("bounds = " +bounds);
            System.out.println("centerX = " +(bounds.getMinX() + bounds.getWidth()/2));
            System.out.println("centerY = " +(bounds.getMinY() + bounds.getHeight()/2));
        }
    });

    Scene scene = new Scene(gridpaneBoard);

    primaryStage.setScene(scene);
    primaryStage.show();
}

如果需要不同于 GridPane 坐标的坐标,您可以将 getBoundsInLocallocalTo... 结合使用:

Bounds bounds = target.localToScene(target.getBoundsInLocal());

用于场景边界或

Bounds bounds = target.localToScreen(target.getBoundsInLocal());

用于屏幕边界。

注意: 这独立于修改 GridPane 其子项布局方式的任何属性。