IEnumerator ClearAndProcessRoutine(List <Bubble> bubblesToClear) { // List of Bubbles to move List <Bubble> movingBubbles = new List <Bubble>(); // List of Bubbles that form matches List <Bubble> matches = new List <Bubble>(); //HighlightBubbles(bubbles); bool isFinished = false; while (!isFinished) { // Trigger all bombs int oldCount; List <Bubble> bombedBubbles = new List <Bubble>(); do { // Keep track of number of Bubbles affected before bomb triggers oldCount = bubblesToClear.Count; // Find Bubbles affected by bombs... bombedBubbles = boardQuery.GetBombedBubbles(bubblesToClear); // ...and add to list of Bubbles to clear bubblesToClear = bubblesToClear.Union(bombedBubbles).ToList(); }while (oldCount < bubblesToClear.Count); // Add any heavy blockers that hit bottom of Board to list of bubbles to clear List <Blocker> bottomBlockers = boardQuery.FindBlockersAt(0, true); // Get list of blockers to be cleared List <Blocker> allBlockers = boardQuery.FindAllBlockers(); List <Blocker> blockersToClear = allBlockers.Intersect(bubblesToClear).Cast <Blocker>().ToList(); blockersToClear = blockersToClear.Union(bottomBlockers).ToList(); blockerCount -= blockersToClear.Count; bubblesToClear = bubblesToClear.Union(blockersToClear).ToList(); List <int> columnsToCollapse = boardQuery.GetColumns(bubblesToClear); // Clear the Bubbles boardClearer.ClearBubbleAt(bubblesToClear, bombedBubbles); // Break any Tiles under the cleared Bubbles boardTiles.BreakTileAt(bubblesToClear); // Activate any previously generated bombs if (m_clickedTileBomb != null) { boardBomber.ActivateBomb(m_clickedTileBomb); m_clickedTileBomb = null; } if (m_targetTileBomb != null) { boardBomber.ActivateBomb(m_targetTileBomb); m_targetTileBomb = null; } yield return(new WaitForSeconds(m_delay)); // Collapse any columns with empty spaces and keep track of what Bubbles moved as a result movingBubbles = boardCollapser.CollapseColumn(columnsToCollapse, collapseMoveTime); // Wait while these Bubbles fill in the gaps while (!boardQuery.IsCollapsed(movingBubbles)) { yield return(null); } // Find any matches that form from collapsing matches = boardMatcher.FindMatchesAt(movingBubbles); // Check if any blockers fell to bottom blockersToClear = boardQuery.FindBlockersAt(0, true); matches = matches.Union(blockersToClear).ToList(); // If no matches are formed from the collapse, then finish if (matches.Count == 0) { isFinished = true; } // Otherwise, repeat this process again else { scoreMultiplier++; if (scoreMultiplier >= 3) { if (SoundManager.Instance != null) { SoundManager.Instance.PlayBonusSound(); } } yield return(StartCoroutine(ClearAndProcessRoutine(matches))); } } }
// coroutine to clear GamePieces from the Board and collapse any empty spaces IEnumerator ClearAndCollapseRoutine(List <GamePiece> gamePieces) { // list of GamePieces that will be moved List <GamePiece> movingPieces = new List <GamePiece>(); // list of GamePieces that form matches List <GamePiece> matches = new List <GamePiece>(); // slight delay before clearing anything yield return(new WaitForSeconds(delay)); bool isFinished = false; while (!isFinished) { // check the original list for bombs and append any pieces affected by these bombs List <GamePiece> bombedPieces = boardQuery.GetBombedPieces(gamePieces); // combine that with our original list gamePieces = gamePieces.Union(bombedPieces).ToList(); // repeat this check once to see if we hit any more bombs bombedPieces = boardQuery.GetBombedPieces(gamePieces); gamePieces = gamePieces.Union(bombedPieces).ToList(); // store any collectibles that need to be cleared List <GamePiece> collectedPieces = boardQuery.GetCollectedPieces(gamePieces); // store what columns need to be collapsed List <int> columnsToCollapse = boardQuery.GetColumns(gamePieces); columnsToCollapse = columnsToCollapse.Union(boardClearer.unblockedColumns).ToList(); // clear the GamePieces, pass in the list of GamePieces affected by bombs as a separate list boardClearer.ClearPieceAt(gamePieces, bombedPieces); // clear any blockers directly underneath bombed pieces boardClearer.ClearBlockers(bombedPieces); // break any tiles under the cleared GamePieces boardTiles.BreakTileAt(gamePieces); // if we create a bomb on the clicked or target tiles, add it to our active GamePieces boardBomber.InitAllBombs(); // short delay yield return(new WaitForSeconds(delay)); // collapse any columns with empty spaces and keep track of what pieces moved as a result movingPieces = boardCollapser.CollapseColumn(columnsToCollapse); // wait while these pieces fill in the gaps while (!boardQuery.IsCollapsed(movingPieces)) { yield return(null); } // extra delay after collapsing is finished yield return(new WaitForSeconds(delay)); // find any matches that form from collapsing... matches = boardMatcher.FindMatchesAt(movingPieces); //...and any collectibles that hit the bottom row... collectedPieces = boardQuery.FindCollectiblesAt(0, true); //... and add them to our list of GamePieces to clear matches = matches.Union(collectedPieces).ToList(); // if we didn't make any matches from the collapse, then we're done if (matches.Count == 0) { isFinished = true; // reset any unblocked columns boardClearer.ResetUnblockedColumns(); break; } // otherwise, increase our score multiplier for the chair reaction... else { scoreMultiplier++; // ...play a bonus sound for making a chain reaction... if (SoundManager.Instance != null) { SoundManager.Instance.PlayBonusSound(); } // ...and run ClearAndCollapse again yield return(StartCoroutine(ClearAndCollapseRoutine(matches))); } } yield return(null); }