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);
    }
Exemple #10
0
    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);
    }
Exemple #11
0
    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();
    }
Exemple #12
0
 private bool FilterByMatchingValue(GridBubble collapseBubble, int index)
 {
     return(bubbleGrid[index].Bubble.Value == collapseBubble.Bubble.Value);
 }
Exemple #13
0
    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);
    }