Último bug visual: rebotes y recálculos

Clase 21 de 31Curso de Desarrollo de Videojuegos para Móviles con Unity

Resumen

Un flujo sólido de destrucción y reposición es clave para un gameplay sin trampas. Aquí verás cómo cerrar el último bug visual en un clon de Candy Crush en Unity: recalcular coincidencias tras cada caída, usar corutinas y aplicar un bucle exhaustivo sobre la matriz para garantizar que no queden alineaciones colaterales.

¿Cómo asegurar el tablero tras las destrucciones en cascada?

Para impedir que el usuario explote coincidencias indirectas, se fuerza un rechequeo global solo cuando todos los caramelos han caído y se han recolocado. La idea: recorrer toda la matriz y pedir a cada caramelo que busque nuevas coincidencias. Es pesado, sí, pero se ejecuta puntualmente tras recomponer, por lo que el impacto en móviles es asumible.

  • Recalcular tras destruir y reposicionar objetos.
  • Comprobar alineaciones con elementos adyacentes en toda la matriz.
  • Usar un doble bucle con límites de tablero: xSize y ySize.
  • Optimizar para móvil: el bucle corre solo cuando termina la recomposición.

Ejemplo del bucle que invoca a cada caramelo su búsqueda de matches:

for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++) {
        candies[x, y].GetComponent<Candy>().FindAllMatches();
    }
}

Conceptos clave que intervienen aquí: la matriz candies, el acceso con GetComponent(), y la llamada a FindAllMatches de cada caramelo.

¿Qué hace findAllMatches y cómo encadena clearMatch y getNewCandy?

En el script de Candy, FindAllMatches valida si el caramelo existe y, si procede, busca coincidencias horizontales o verticales de tres o más. Si hay match, se anula el sprite del actual y, mediante ClearMatch, también el de los vecinos. Esto deja nulos que activan la corutina que encuentra nulos, hace caer piezas y genera nuevas con getNewCandy.

  • Validación de caramelo nulo: si es nulo, no actúa.
  • Búsqueda en horizontal o vertical de 3 o más.
  • Anulación gráfica con sprite = null para actual y vecinos en ClearMatch.
  • Caída por rebote: la corutina vuelve a detectar nulos y rellena.
  • Repetición recursiva hasta que no haya coincidencias pendientes.

Tras detectar una destrucción, es obligatorio disparar la búsqueda de nulos desde el gestor del tablero para completar la cadena de caídas y relleno:

if (matchHorizontal || matchVertical) {
    BoardManager.sharedInstance.FindNullCandies();
}

Así se garantiza que el ciclo continúa: anulación gráfica, detección de nulos, caída, generación con getNewCandy y nueva llamada a FindAllMatches hasta estabilizar el tablero sin tríos ni más alineaciones.

¿Qué cambio realizar en on mousedown y en la corutina para estabilidad?

El gesto de swipe vivía en OnMouseDown y allí se arrancaba la corutina para encontrar nulos. El ajuste final es mover esa lógica al propio FindAllMatches: cuando haya una combinación válida, se detienen comprobaciones anteriores y se inicia una nueva búsqueda de nulos. Esto reinicia el ciclo con cada match, incluso si ocurre a mitad de una cadena de caídas, y asegura un tablero coherente tras los rebotes.

  • Mover la invocación de la corutina desde OnMouseDown hacia FindAllMatches.
  • Reiniciar la búsqueda cada vez que hay una combinación válida.
  • Permitir que los rebotes recalculen toda la matriz.
  • Evitar que queden tríos residuales o que el jugador fuerce trampas.

Ilustración de la reasignación de responsabilidades:

// Antes (en OnMouseDown):
// ... detectar swipe, intercambiar, destruir ...
// BoardManager.sharedInstance.FindNullCandies(); // se invocaba aquí

// Ahora (en FindAllMatches, solo si hay match válido):
if (matchHorizontal || matchVertical) {
    // anular sprites del actual y vecinos mediante ClearMatch
    BoardManager.sharedInstance.FindNullCandies(); // reinicia la búsqueda de nulos
}

Este ciclo produce caídas encadenadas fiables, incluidas formas como una T, y múltiples rebotes consecutivos hasta ver el resultado final limpio para que el jugador siga moviendo caramelos con normalidad.

¿Te funcionó esta estrategia o harías otro ajuste al flujo de corutinas y bucles? Comparte tus dudas o mejoras en comentarios.