2D grid based game merging boxes

Basically what i have at the moment is a tile based game with a grid containing a number of colored cells.

this is what i've done so far

The prinipal idea of the game is that the user has to connect all the shapes with the same color. but when two (or more) cells of the same color join they cannot be separated.

for example:

• the player cannot go from image 1 to image 2 because the blue cells are attached, it should become what is in image 3

i need help how to make the attached cells move as a unit not separately one by one (like in image 2 which is what i have right now).

each cell is a Cell object and they are held in an array like this:

private Cell[][] grid;


and this is the code i'm using to move the cells around.

public void move(int dx, int dy) {
// if (dx == -1) ==> move left
// if (dx == 1) ==> move right
// if (dy == -1) ==> move down
// if (dy == -1) ==> move up
if (clickedCell == null) {
return;
}
if (dx > 0) {
if (clickedCol < numCols - 1) {
Cell temp = grid[clickedRow][clickedCol];
grid[clickedRow][clickedCol] = grid[clickedRow][clickedCol + 1];
grid[clickedRow][clickedCol + 1] = temp;
grid[clickedRow][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
grid[clickedRow][clickedCol + 1].setPosition(x + (clickedCol + 1) * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
clickedCell = null;
}
} else if (dx < 0) {
if (clickedCol > 0) {
Cell temp = grid[clickedRow][clickedCol];
grid[clickedRow][clickedCol] = grid[clickedRow][clickedCol - 1];
grid[clickedRow][clickedCol - 1] = temp;
grid[clickedRow][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
grid[clickedRow][clickedCol - 1].setPosition(x + (clickedCol - 1) * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
clickedCell = null;
}
} else if (dy > 0) {
if (clickedRow > 0) {
Cell temp = grid[clickedRow][clickedCol];
grid[clickedRow][clickedCol] = grid[clickedRow - 1][clickedCol];
grid[clickedRow - 1][clickedCol] = temp;
grid[clickedRow][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
grid[clickedRow - 1][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 0) * Cell.SIZE);
clickedCell = null;
}
} else if (dy < 0) {
if (clickedRow < numRows - 1) {
Cell temp = grid[clickedRow][clickedCol];
grid[clickedRow][clickedCol] = grid[clickedRow + 1][clickedCol];
grid[clickedRow + 1][clickedCol] = temp;
grid[clickedRow][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 1) * Cell.SIZE);
grid[clickedRow + 1][clickedCol].setPosition(x + clickedCol * Cell.SIZE,
y + (numRows - clickedRow - 2) * Cell.SIZE);
clickedCell = null;
}
}
}


thanks in advance and by the way this game is built using LibGDX.

First, you need to find which blocks should move move, given a particular clicked cell. You'll probably want to use a floodfill algorithm of some sort for that. Once you have your list of tiles, move them all one after the other before doing anything else.

The way I would do that would be to change the move function so that it takes another parameter indicating which tile to move, instead of moving the clicked one then call the function on each of the tiles in the list.

List<Cell> movingCells = floodfill(clickedCell, /*maybe more parameters*/);
for(Cell cell : movingCells) {
move(cell, dx, dy);
}


Also, you could move Cell temp = grid[clickedRow][clickedCol]; out of all the inner if blocks and put it just above the large if block (the one with if (dx > 0) {) and save some code duplication.

• Thank you so much it helped me a lot, and thanks for the code duplication advice. Commented Aug 26, 2015 at 15:47