Java : filling Object Array overflow into other fields

55 Views Asked by At

Tetris Game

My code works as it should at the start but after some time playing it breaks. When a falling piece touches the ground and gets put into the gamefield it gets stretched up into other spaces. the field Object(Block) only holds one variable "filled" and when field[fallingPiece.getY() + y + fieldExtra][fallingPiece.getX() + x].setFilled(true); gets executed it changes the state of multiple Objectses(Blockses) state in the field.

The fieldExtra variable is the non visible space above the game field where the pieces get spawned. Its value is 20. Its interesting to note that the Bug doesn't fill the whole array but only to 19 after which it just stops.
Also interesting is that once the bug started it always occurs unless the piece gets placed under some height.

private static void placePiece() {
    Block[][] pieceField = fallingPiece.getPieceField();
    for(int y=0; y < pieceField.length; y++) {
        for(int x=0; x < pieceField[0].length; x++) {
            if(pieceField[y][x].isFilled()) {
                 field[fallingPiece.getY() + y + fieldExtra][fallingPiece.getX() + x].setFilled(true);
            }
        }
    }
}

If you want to look at the entirety of the code here is my Github repository

I have already looked at it in the debugger and I went step by step through the code and at field[fallingPiece.getY() + y + fieldExtra][fallingPiece.getX() + x].setFilled(true); it filled multiple Objects at the same time when executing. while the for loops are behaving as expected.

I have also found that when commenting out the collision detection with the field the bug doesn't happen anymore, which I don't understand because they don't correlate in any way.

EDIT: The Bug is solved and wasn't caused by the code snippet above.

2

There are 2 best solutions below

0
TJirm On BEST ANSWER

I have found the Cause of the Bug it was the way I cleared lines:

field[y + fieldExtra] = field[y + fieldExtra - 1];

This just sets one line which is an Object[] to the line(Obeject[]) above it. That linked the different Blocks in some way I think, I dont really understand how that works. But I fixed it and now it works with no Problems.

Here's the fix if you're interested:

for(int i=0; i < fieldWidth; i++) {
    field[y + fieldExtra][i].setFilled(field[y + fieldExtra - 1][i].isFilled());
}

Thanks for the help especially to Hovercraft Full Of EelsHovercraft Full Of Eels for the tip to try and reproduce the Bug in a smaller Programm.

1
samgi On

it seems like the bug is happening because the fieldExtra variable is being incremented by more than 1 for each iteration of the for loop. This is causing the field array to be accessed outside of its bounds, which is why multiple blocks are being modified when the setFilled(true) method is called.

To fix this, you can change the way that the fieldExtra variable is incremented. Instead of incrementing it by 1, you can increment it by the number of columns in the pieceField array. This will ensure that the field array is only accessed within its bounds

private static void placePiece() {
    Block[][] pieceField = fallingPiece.getPieceField();
    int fieldExtra = pieceField[0].length;
    for (int y = 0; y < pieceField.length; y++) {
        for (int x = 0; x < pieceField[0].length; x++) {
            if (pieceField[y][x].isFilled()) {
                field[fallingPiece.getY() + y + fieldExtra][fallingPiece.getX() + x].setFilled(true);
            }
        }
    }
}