Search code examples
javalibgdxcollision-detection

Java libGDX tetris collisions


I´m working on a Tetris game and I´ve started with the collision part. Currently the first line works fine, the collision does what it´s supposed to. When i get the the second line it stops working.. I´m still adding the rectangles to the array and nothing seems wrong in the code. I´ve been using the debugger a lot but i can´t find the problem. This is my first programming project i´ve ever done. Been learning java for about 3 months now so this is surely a noob problem. Here is my create and render method. Thank you for reading.

@Override
public void create () {
    camera = new OrthographicCamera();
    camera.setToOrtho(false, WIDTH, HEIGHT);
    blocks = new Array<Blocks>();
    boxes = new Array<Rectangle>();


    block = new Block();
}


@Override
public void render () {
    Gdx.gl.glClearColor(0, 0, .2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    block.getRenderer().setProjectionMatrix(camera.combined);

    block.draw();



    // Update
    block.drop(Gdx.graphics.getDeltaTime());
    isFalling = true;


    Rectangle box = block.getBox();

    // Collision
    for(Rectangle r: boxes) {
        if(box.overlaps(r)) {
            isFalling = false;
            System.out.println("collision");
            block.setY(r.height);
            boxes.add(box);
            blocks.add(block);
            System.out.println("Block added. creating new block..");
            block = new Block();
            break;
        }
    }


    // Borders
    if(box.x < 0) box.x = 0;
    if(box.x > WIDTH - box.width) box.x = WIDTH - box.width;
    if(box.y < 0) {
        isFalling = false;
        System.out.println("not falling");
        box.y = 0;
        boxes.add(box);
        blocks.add(block);
        System.out.println("Block added. creating new block..");
        block = new Block();
    }


    // Controls
    if(Gdx.input.isKeyJustPressed(Keys.LEFT) && isFalling)
        block.stepLeft();
    if(Gdx.input.isKeyJustPressed(Keys.RIGHT) && isFalling)
        block.stepRight();
    if(Gdx.input.isKeyJustPressed(Keys.DOWN))
        block.setDown();

    for(Blocks b: blocks) {
        b.draw();
    }

}

Solution

  • Tetris blocks have discreet positions. Its game area is 20 rows high and 10 columns wide. There is probably no need for standard collision detection.

    You can for example use a 2D array with boolean or integer values that represent presence of a square on a location:

    int[][] squares = new int[20][10];
    

    You can then use this information to determine if there is a collision:

    • Rotation or movement should only be allowed if the resulting position from that action does not cause any of the squares to overlap with already present squares on game area and are inside the game area bounds (20 rows and 10 columns).
    • If any square on a currently active block reaches bottom row or is in the same column and one row above a square already filled, then the block has reached its end destination.
    • If when a block first appears on the screen some of its squares are already in occupied positions then it is game over.
    • Etc.

    I made a Tetris clone using libgdx a few years ago, check it out if you think it might help you. You can see some images here and get the source from here.

    Clarification: When I say block I mean a tetromino, the entire object that falls from the top. Each Tetris block contains four squares in various arrangements.