Contenido del curso

Mecánica Principal

Colapso de columnas en un Match 3

Resumen

Cuando trabajas en un juego tipo Match 3, eliminar piezas no basta: necesitas que las fichas superiores caigan para llenar los huecos. Aquí aprendes a programar el colapso de columnas en Unity con C#, paso a paso, refactorizando la función swapTiles y creando dos nuevos métodos: getColumns y collapseColumns.

Esta lógica es clave para cualquier desarrollador de videojuegos que quiera dominar mecánicas de tablero, optimizar su código con listas y for loops anidados, y entender cómo coordinar referencias en una cuadrícula 2D.

Por qué refactorizar swapTiles antes de colapsar

Antes de mover piezas hacia abajo, conviene unificar cómo detectas y eliminas los matches. El código original usaba dos foreach separados para startMatches y endMatches, lo que duplicaba lógica.

La nueva estrategia es unir ambos resultados en una sola lista llamada allMatches usando el método Union, que devuelve un array; por eso lo conviertes de vuelta a lista con ToList [02:00].

csharp var allMatches = startMatches.Union(endMatches).ToList();

Con esa lista en mano, eliminas el booleano foundMatch y validas directamente con allMatches.Count. Si el conteo es cero, devuelves las piezas a su lugar original. Si es mayor a cero, llamas a una nueva función llamada clearPieces que recibe la lista completa.

¿Qué hace el método Union en C#? Combina dos colecciones eliminando duplicados y devuelve un array. Para seguir trabajando con métodos de lista, lo conviertes con ToList().

Cómo funciona clearPieces y getColumns

La función clearPieces recibe una lista de piezas llamada piecesToClear e itera con un foreach llamando a clearPieceAt(piece.x, piece.y) para cada una [04:30]. Hasta ahí, solo eliminas. Lo interesante viene después.

Necesitas saber en qué columnas eliminaste piezas, porque solo esas columnas requieren colapsar las fichas superiores. Para eso creas getColumns, que recibe la lista de piezas y devuelve una lista de enteros con las columnas únicas.

Construyendo la lista de columnas sin duplicados

Dentro de getColumns inicializas var result = new List<int>(); y recorres cada pieza. Si la columna piece.x no está ya en result, la agregas. Esto evita que un match vertical de tres piezas en la misma columna se registre tres veces.

csharp foreach (var piece in piecesToClear) { if (!result.Contains(piece.x)) { result.Add(piece.x); } } return result;

Esa lista limpia se la pasas a collapseColumns junto con un tiempo de ejecución de 0.3 segundos [07:15].

Cómo implementar collapseColumns paso a paso

Aquí está el corazón de la mecánica. La idea es recorrer cada columna afectada desde la fila inferior hacia arriba, detectar espacios vacíos y mover hacia abajo la siguiente pieza válida que encuentres por encima.

La lógica visual del colapso

Imagina que eliminaste tres piezas en distintas columnas. En cada columna empiezas en y = 0 y subes. Cuando encuentras una posición nula, lanzas un segundo for loop que busca hacia arriba (yPlus = y + 1) la primera pieza no nula. La encuentras, la mueves a la posición vacía, actualizas el sistema de coordenadas, limpias la referencia anterior y haces break para volver al loop exterior.

¿Por qué se usan dos for loops anidados? Uno recorre la columna desde abajo buscando huecos; el otro busca arriba la próxima pieza válida para llenar ese hueco. Sin esa combinación no podrías colapsar correctamente.

El código completo del colapso

Dentro de collapseColumns declaras una lista movingPieces que guardará todas las piezas que se desplazaron, útil para la siguiente clase [11:40].

csharp List<Piece> movingPieces = new List<Piece>();

for (int i = 0; i < columns.Count; i++) { var column = columns[i]; for (int y = 0; y < height; y++) { if (pieces[column, y] == null) { for (int yPlus = y + 1; yPlus < height; yPlus++) { if (pieces[column, yPlus] != null) { pieces[column, yPlus].Move(column, y); pieces[column, y] = pieces[column, yPlus]; if (!movingPieces.Contains(pieces[column, y])) { movingPieces.Add(pieces[column, y]); } pieces[column, yPlus] = null; break; } } } } } return movingPieces;

La función Move ya existía en la clase Piece y recibe las nuevas coordenadas. Después de mover, actualizas pieces[column, y] con la referencia nueva y dejas en null la posición original.

Qué conceptos de C# refuerzas con esta mecánica

Al construir esta funcionalidad practicas varias habilidades técnicas que se aplican más allá de un Match 3:

  • Uso de List<T> y métodos como Contains, Add, Count y Union para manipular colecciones dinámicas.
  • Diferencia entre un array de tamaño fijo y una List de tamaño variable, decisión que tomas explícitamente al cambiar el tipo de retorno de getColumns [08:50].
  • For loops anidados con variables de control independientes (i, y, yPlus) para recorrer estructuras 2D.
  • Uso del atajo de Visual Studio para generar métodos automáticamente desde una llamada, manteniendo signatures coherentes.
  • Limpieza de referencias en arreglos bidimensionales para evitar piezas fantasma.

Ahora tu juego ya tiene cuadrícula, detección de Match 3, eliminación de piezas y colapso de columnas. ¿Cuál crees que es el siguiente paso lógico para completar la mecánica? Cuéntamelo en los comentarios.