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<Candy>(), 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:
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.
Interesante el curso, muy desafiante el nivel del código escrito
Desafiante no, lo siguiente!
me da un derrame cerebral cada de acabar una clase
Este bug lo tenemos TODOS
Video
Yo nada mas agregué este código en Candy.cs para lo que hicimos en esta clase:
voidFixedUpdate(){FindAllMatches();}
En el anterior vídeo se quedaron en generar los caramelos aleatorios, en este se saltaron la explicación de los métodos "FindNullCandies","MakeCandiesFall", etc. Al parecer olvidaron subir un capitulo.
Hola Fer! Hay un bugcito causando esto, lo resolveremos ASAP
que significa ASAP? al parecer más de 3 días.
¡Awwñññish!
Para aquellos que, los nuevos caramelos cuando los juntan con otro caramelo del mismo tipo, no se destruye, es porque (en mi caso) no se actualiza el ID del caramelo una vez que se coloca un nuevo sprite al llamar al metodo "GetNewCandy(int x, int y)"
lo que hice fue:
private int GetCandyId(Sprite sprite){/* Ciclo para recorrer los prefabs, seria mejor aplicar LINQ*/for(int i =0; i < prefabs.Count; i++){if(sprite == prefabs[i])return i;//retornamos id}return-1;// por seguridad retuornamos -1 si no encontro nada}
estemetodo lo llamo justo antes de asignar el nuevo sprite al candy de la siguiente forma..
// dentro del bucle for de MakeCandiesFallSprite spriteCandy =GetNewCandy(x, ySize -1);int idCandy =GetCandyId(spriteCandy);//1. asignas el sprite al candy//agregas esta logica listCandies[x +1].GetComponent<Candy>().id= idCandy;
Voy a tener que haccer un mapa mental gigante del funcionamiento del codigo para entender mejor
Que inteligente es el profe!
Genial
puede ser que el DNI o cedula o identificador o id que se creo para el Candy que se dijo al principio que era importante se dejo sin ser utilizado?
porque la determinacion del match se hace en base a los sprites y no en base al id.
gracias
no se maquinola. yo tambien pensaba q con eso se iba a comparar. Segui tal cual pero tengi un bug en la primera fila