2

I am writing a game similar to Bejeweled, and after running the application for some time the blocks fail to be exactly at the right place visually but logically they are at the right place. The situation is as the picture below.

enter image description here

I don't know the cause of the bug.

here are the codes for the method erase and descend. Logically these methods do well.

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();

        });

}

}

Andy Lee
  • 33
  • 4

2 Answers2

0

You didn't paste your codes for your layout, so I'm going to make a guess.

There is a potential problem when you do translate and your layout depends on boundsInParent. This is an abstract from the 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

When your TranslateTransition animates, it is changing the block's translateY value, and if your layout is called at this time, this translate value is going to affect how the block's is going to be positioned. If your layout is managed by some kind of layout manager (i.e. pane), you need to check how they position their children.

Jai
  • 8,165
  • 2
  • 21
  • 52
  • I guess I understand what you mean but I wonder how can I make the gridpane not to change its children's layoutX after the transition? Thank you! – Andy Lee May 12 '17 at 07:10
  • @AndyLee It would be good if you could answer your own question and share with others exactly how it could be solved. All I did was simply to give you a direction for which you can zoom down and explore. :) – Jai May 15 '17 at 00:34
0

I use gridpane to position my blocks, there are 10 rows and 10 columns initially and the gridpane automatically adds one row after the blocks have descended, (because the block is not exactly translated to the position that it is supposed to and I still do not know the reason of it). I change the html document to avoid the growth of the columns. And it works.

Andy Lee
  • 33
  • 4