JavaFX 过渡动画无法将网格窗格的子元素放置在正确的位置

JavaFX transition animation fail to place the children of gridpane at the right place

我正在编写一个类似于宝石迷阵的游戏,在 运行 应用程序一段时间后,块在视觉上无法准确地位于正确的位置,但逻辑上它们位于正确的位置.情况如下图

enter image description here

我不知道错误的原因。

这里是 erase 和 descend 方法的代码。从逻辑上讲,这些方法效果很好。

public void erase()
{
    for (int i = 0; i < BlockManager.length; i++)
    {
        Block block = BlockManager.blocks[BlockManager.erased[i][0]][BlockManager.erased[i][1]];
        BlockManager.blocks[BlockManager.erased[i][0]][BlockManager.erased[i][1]] = null;

        FadeTransition transition = new FadeTransition(Duration.seconds(1), block);
        transition.setFromValue(1);
        transition.setToValue(0);

        transition.setOnFinished(e ->
        {

            blockGridPan.getChildren().remove(block);

            descend();

            BlockManager.resetArrays();

        });

        transition.play();

    }

}

int[][] descend = new int[HEIGHT * WIDE][2];
int descendLength = 0;


public void descend()
{
    int[] columnX = new int[10];
    int[] theUpperOne = new int[10];

    Arrays.fill(theUpperOne, 10);
    Arrays.fill(columnX, 0);

    for (int j = 0; j < BlockManager.length; j++)
    {
        columnX[BlockManager.erased[j][0]]++;
        if (BlockManager.erased[j][1] < theUpperOne[BlockManager.erased[j][0]])
        {
            theUpperOne[BlockManager.erased[j][0]] = BlockManager.erased[j][1];
        }
    }

    TranslateTransition transition = null;

    for (int i = 0; i < 10; i++)
    { 
        if (columnX[i] == 0)
            continue;

        for (int j = WIDE - 1; j >= 0; j--)
        {
            if (BlockManager.blocks[i][j] == null)
                continue;
            int dY = 0;
            for (int k = j + 1; k < WIDE; k++)
            {
                if (BlockManager.blocks[i][k] == null)
                    dY++;
            }
            if (dY != 0)
            {
                int deltaY = dY * 60;

                transition = new TranslateTransition(Duration.seconds(1), BlockManager.blocks[i][j]);
                transition.setByY(deltaY);

                BlockManager.blocks[i][j + dY] = BlockManager.blocks[i][j];
                BlockManager.blocks[i][j + dY].setPosition(i, j + dY);
                BlockManager.blocks[i][j] = null;

                BlockManager.blocks[i][j + dY].setDescended(true);
                transition.play();
            }
        }


        for (int j = columnX[i] - 1; j >= 0; j--)
        {

            int deltYJ = j * 60;
            createOneBlock(i, j);
            BlockManager.setBlockColorWithoutCheck(BlockManager.blocks[i][j]);
            blockGridPane.add(BlockManager.blocks[i][j], i, 0);
            System.out.println("show it");

            BlockManager.blocks[i][j].setDescended(true);

            transition = new TranslateTransition(Duration.seconds(1), BlockManager.blocks[i][j]);
            transition.setByY(deltYJ);
            transition.play();

        }

    }

    if (transition != null)
        transition.setOnFinished(e ->
        {

            BlockManager.resetArrays();
            if (BlockManager.check())
                erase();

        });

}

}

您没有为您的布局粘贴代码,所以我要猜测一下。

当您执行 translate 并且您的布局取决于 boundsInParent 时,可能会出现问题。这是 JavaDoc 的摘要:

The rectangular bounds of this Node which include its transforms. boundsInParent is calculated by taking the local bounds (defined by boundsInLocal) and applying the transform created by setting the following additional variables

  1. transforms ObservableList
  2. scaleX, scaleY
  3. rotate
  4. layoutX, layoutY
  5. translateX, translateY

当你的 TranslateTransition 动画时,它正在改变块的 translateY 值,如果此时调用你的布局,这个转换值将影响块的方式定位。如果您的布局由某种布局管理器(即窗格)管理,您需要检查它们如何定位 children.

我使用 gridpane 来定位我的块,最初有 10 行和 10 列,并且 gridpane 在块下降后自动添加一行,(因为块没有准确地平移到它应该的位置我仍然不知道它的原因)。我更改了 html 文档以避免列的增长。并且有效。