private IEnumerable <GridBubble> FindSeparatedBubbles(GridBubble mainlandOrigin) { ResetGridPropagationStatus(); List <GridBubble> activeBubbles = new List <GridBubble>(); for (int i = 0; i < bubbleGrid.Length; i++) { if (bubbleGrid[i].IsActive) { activeBubbles.Add(bubbleGrid[i]); } } //* condition is true because we just want to collect all the neigbours //* who have connection to the first "mainland" bubble List <GridBubble> mainlandNeighbours = CollectMatchingNeighbours( originBubble: mainlandOrigin, matchCondition: (gridBubble, index) => { return(true); } ); var separatedBubbles = activeBubbles.Except(mainlandNeighbours); return(separatedBubbles); }
List <GridBubble> CollectMatchingNeighbours(GridBubble originBubble, Func <GridBubble, int, bool> matchCondition) { if (originBubble is null) { throw new ArgumentNullException("originBubble"); } List <GridBubble> bubbleCluster = new List <GridBubble>(bubbleGrid.Length); originBubble.HasBeenPropagatedTo = true; bubbleCluster.Add(originBubble); for (int i = 0; i < bubbleGrid.Length; i++) { if (bubbleGrid[i].HasBeenPropagatedTo) { continue; } if (bubbleGrid[i].IsActive == true && matchCondition(originBubble, i)) { float d = (bubbleGrid[i].Bubble.GetBubblePosition() - originBubble.Bubble.GetBubblePosition()).magnitude; if (d < BUBBLE_DIAMETER + 2 * GRID_SPACING) { bubbleCluster.AddRange(CollectMatchingNeighbours(bubbleGrid[i], matchCondition)); } } } return(bubbleCluster); }
IEnumerator TweenBubbleGathering(List <GridBubble> bubbleCluster, GridBubble collapseBubble, Action onBubblesGathered = null) { Sequence mySequence = DOTween.Sequence(); foreach (var b in bubbleCluster) { if (b == collapseBubble) { continue; } Vector3 bubbleStartingPos = b.Bubble.transform.position; mySequence.Insert(0f, b.Bubble.transform .DOMove( collapseBubble.Bubble.GetBubblePosition(), 0.3f ) .SetEase(Ease.OutBack) .OnComplete(() => { b.ActivateBubble(false); b.Bubble.transform.position = bubbleStartingPos; })); } yield return(mySequence.WaitForCompletion()); onBubblesGathered?.Invoke(); }
IEnumerator ExplodeCluster(List <GridBubble> bubbleCluster) { if (bubbleCluster.Count == 1) { Debug.LogError("what"); yield break; } //* Exploding the topmost bubble is more fun GridBubble topMostBubble = bubbleCluster[0]; for (int i = 1; i < bubbleCluster.Count; i++) { if (bubbleCluster[i].Bubble.GetBubblePosition().z > topMostBubble.Bubble.GetBubblePosition().z) { topMostBubble = bubbleCluster[i]; } } //* Gather cluster into the top mostbubble yield return(playLoop.StartCoroutine(TweenBubbleGathering(bubbleCluster, topMostBubble))); List <GridBubble> neighbours = GetAllActiveNeighbours(topMostBubble); yield return(playLoop.StartCoroutine(TweenBubbleGathering(neighbours, topMostBubble))); // ! add explosion anim Camera.main.DOShakePosition(0.3f, 0.03f, 20, 90, false); topMostBubble.ActivateBubble(false); propagationComplete.Invoke(); }
void PropagateCollapse(GridBubble bubbleToPropagateFrom) { ResetGridPropagationStatus(); List <GridBubble> bubbleCluster = CollectMatchingNeighbours( originBubble: bubbleToPropagateFrom, matchCondition: (gridBubble, index) => FilterByMatchingValue(bubbleToPropagateFrom, index)); AnalyzeClusterScore(bubbleCluster); }
bool CheckIfHasNeighbourMatchingValue(GridBubble gridBubble, int value) { for (int i = 0; i < bubbleGrid.Length; i++) { if (bubbleGrid[i].IsActive == true && bubbleGrid[i].Bubble.Value == value) { float d = (bubbleGrid[i].Bubble.GetBubblePosition() - gridBubble.Bubble.GetBubblePosition()).magnitude; if (d < BUBBLE_DIAMETER + 2 * GRID_SPACING) { return(true); } } } return(false); }
IEnumerator SeekoutSeparatedBubbles(Action onSeparatedIslandsFound) { GridBubble mainlandOrigin = null; mainlandOrigin = gridSpawner.ToplineBubbles.Find(b => b.IsActive == true); if (mainlandOrigin == null) { onSeparatedIslandsFound.Invoke(); yield break; } IEnumerable <GridBubble> separatedBubbles = FindSeparatedBubbles(mainlandOrigin); float gridY = gridSpawner.transform.position.y; Sequence mySequence = DOTween.Sequence(); for (int i = 0; i < separatedBubbles.Count(); i++) { Bubble bubble = separatedBubbles.ElementAt(i).Bubble; Vector3 originalPosition = bubble.transform.localPosition; mySequence.Insert(0f, bubble.transform .DOLocalMoveY( bubble.transform.localPosition.y - gridY, 0.5f) .SetEase(Ease.OutBounce) .OnComplete(() => { bubble.ActivateBubble(false); bubble.transform.localPosition = originalPosition; })); mySequence.Insert(0f, bubble.transform .DOScale( 0.2f, 0.5f) .SetEase(Ease.OutBounce)) .OnComplete(() => { bubble.transform.localScale = Vector3.one; }); } mySequence.AppendCallback(() => onSeparatedIslandsFound.Invoke()); }
List <GridBubble> GetAllActiveNeighbours(GridBubble originBubble) { List <GridBubble> neighbours = new List <GridBubble>(6); for (int i = 0; i < bubbleGrid.Length; i++) { if (bubbleGrid[i].IsActive == true) { float d = (bubbleGrid[i].Bubble.GetBubblePosition() - originBubble.Bubble.GetBubblePosition()).magnitude; if (d < BUBBLE_DIAMETER + 2 * GRID_SPACING) { neighbours.Add(bubbleGrid[i]); } } } return(neighbours); }
public override void Begin(object pastStateResult) { bubbleGrid = gridSpawner.BubbleGrid; GridBubble gridBubble = gridSpawner.PutPlayerBubbleInAGrid(player.PlayerBubble); propagationComplete = () => { playLoop.StartCoroutine( SeekoutSeparatedBubbles( onSeparatedIslandsFound: () => { playLoop.SwitchState(PlayLoopState.NewRound); })); }; PropagateCollapse(bubbleToPropagateFrom: gridBubble); }
IEnumerator SpawnRowRoutine(OnRowSpawnResult onRowSpawnResult) { bool isGameOver = false; float oddRowOffset = isOddRow ? bubbleRadius : 0f; isOddRow = !isOddRow; ToplineBubbles.Clear(); for (int i = 0; i < GRID_WIDTH; i++) { yield return(new WaitForSeconds(0.1f)); GridBubble lastSlot = bubbleGrid.Dequeue(); // todo change gmeover condition, it will not work for the player added bubbles if (lastSlot.IsActive) { //* Add a call to a dequeued Bubble, if it exists it could run some game over destruction anim isGameOver = true; Debug.Log("game over"); } //* activate new slot float xPosition = horizontalStep * i + oddRowOffset; lastSlot.ActivateBubble(new Vector3(xPosition, 0f, verticalStep)); lastSlot.Bubble.ResetBubbleScale(); bubbleGrid.Enqueue(lastSlot); ToplineBubbles.Add(lastSlot); } // * dirtyyy if (!isGameOver) { foreach (var bubble in bubbleGrid) { bubble.OffsetBubble(-verticalStep); } } onRowSpawnResult(isGameOver); }
IEnumerator CreateFirstRowsRoutine(Action onCompleted) { isOddRow = GRID_HEIGHT % 2 == 0 ? true : false; GenerateInactiveGrid(); for (int j = 0; j < STARTING_ROWS; j++) { float oddRowOffset = isOddRow ? bubbleRadius : 0f; isOddRow = !isOddRow; for (int i = 0; i < GRID_WIDTH; i++) { yield return(new WaitForSeconds(0.1f)); GridBubble newSlot = bubbleGrid.Dequeue(); float xPosition = horizontalStep * i + oddRowOffset; newSlot.Bubble.ResetBubbleScale(); newSlot.ActivateBubble(new Vector3(xPosition, 0f, verticalStep)); bubbleGrid.Enqueue(newSlot); if (j == STARTING_ROWS - 1) { ToplineBubbles.Clear(); ToplineBubbles.Add(newSlot); } } foreach (var bubble in bubbleGrid) { bubble.OffsetBubble(-verticalStep); } } onCompleted?.Invoke(); }
private bool FilterByMatchingValue(GridBubble collapseBubble, int index) { return(bubbleGrid[index].Bubble.Value == collapseBubble.Bubble.Value); }
bool IsThereBubbleThatCanPropagateCollapse(List <GridBubble> bubbleCluster, int soughtCollapseValue, out GridBubble collapseBubble) { collapseBubble = null ; foreach (var bubble in bubbleCluster) { if (collapseBubble == null && CheckIfHasNeighbourMatchingValue(bubble, soughtCollapseValue)) { // Debug.Log("found bubble 2 collapse", b.Bubble.transform); collapseBubble = bubble; return(true); } } return(false); }