Beispiel #1
0
        private void FastMoveTween(GameObject mObject, Action completeCallBack)
        {
            PhysStep = true;
            tS       = new TweenSeq();
            Vector3 scale     = transform.localScale;
            float   tweenTime = 0.07f;
            float   distK     = Vector3.Distance(mObject.transform.position, transform.position) / MatchBoard.MaxDragDistance;

            Vector2 dPos   = mObject.transform.position - transform.position;
            bool    isVert = (Mathf.Abs(dPos.y) > Mathf.Abs(dPos.x));

            //move
            tS.Add((callBack) =>
            {
                SimpleTween.Move(mObject, mObject.transform.position, transform.position, tweenTime * distK).AddCompleteCallBack(() =>
                {
                    mObject.transform.position = transform.position;
                    PhysStep = false;
                    completeCallBack?.Invoke();
                    StartCoroutine(EndFill(isVert));
                    callBack();
                });
            });
            tS.Start();
        }
Beispiel #2
0
 internal void MixJump(Vector3 pos, Action completeCallBack)
 {
     PhysStep = true;
     SimpleTween.Move(DynamicObject, transform.position, pos, 0.5f).AddCompleteCallBack(() =>
     {
         PhysStep = false;
         completeCallBack?.Invoke();
     }).SetEase(EaseAnim.EaseInSine);
 }
Beispiel #3
0
        /// <summary>
        /// If matched > = 4 cretate bomb from items
        /// </summary>
        /// <param name="bombCell"></param>
        /// <param name="completeCallBack"></param>
        internal void MoveToBomb(GridCell toCell, float delay, Action completeCallBack)
        {
            // Debug.Log("Move to bomb");

            SetToFront(true);
            //scale
            SimpleTween.Value(gameObject, gameObject.transform.localScale, gameObject.transform.localScale * 1.05f, 0.1f).SetOnUpdate((val) => { gameObject.transform.localScale = val; });

            // move
            SimpleTween.Move(gameObject, transform.position, toCell.transform.position, 0.25f).AddCompleteCallBack(completeCallBack).SetEase(EaseAnim.EaseInBack).SetDelay(delay);
        }
Beispiel #4
0
        /// <summary>
        /// If matched > = 4 cretate bomb from items
        /// </summary>
        /// <param name="bombCell"></param>
        /// <param name="completeCallBack"></param>
        internal void MoveMatchToBomb(GridCell fromCell, GridCell toCell, float delay, bool hitProtection, Action completeCallBack)
        {
            //  Debug.Log("Move to bomb");
            if (hitProtection)
            {
                fromCell.DirectHitUnderlay(null);
                fromCell.DirectHitOverlay(null);
                fromCell.Neighbors.Cells.ForEach((GridCell c) => { c.SideHit(null); });
            }

            SetToFront(true);
            //scale
            SimpleTween.Value(gameObject, gameObject.transform.localScale, gameObject.transform.localScale * 1.05f, 0.1f).SetOnUpdate((val) => { gameObject.transform.localScale = val; });

            // move
            SimpleTween.Move(gameObject, transform.position, toCell.transform.position, 0.25f).AddCompleteCallBack(completeCallBack).SetEase(EaseAnim.EaseInBack).SetDelay(delay);
        }
Beispiel #5
0
 public void InitStart(BubbleGrid grid, GridCell gCell)
 {
     if (grid == null || !gCell)
     {
         return;
     }
     map = new Map(grid);
     gameObject.SetActive(true);
     this.grid            = grid;
     anchored             = gCell;
     target               = gCell;
     topRow               = grid.Rows[0];
     pF                   = new PathFinder();
     transform.localScale = gCell.transform.lossyScale;
     SimpleTween.Move(gameObject, transform.position, target.transform.position, 2.5f).AddCompleteCallBack(() => {
         canUpdate        = true;
         moving           = false;
         transform.parent = gridParent;
         UpdatePath();
     });
 }
Beispiel #6
0
        private void MoveTween(GameObject mObject, Action completeCallBack)
        {
            PhysStep = true;
            tS       = new TweenSeq();
            Vector3        scale      = transform.localScale;
            float          tweenTime  = 0.07f;
            float          distK      = Vector3.Distance(mObject.transform.position, transform.position) / MatchBoard.MaxDragDistance;
            AnimationCurve scaleCurve = MatchBoard.Instance.arcCurve;

            Vector2 dPos   = mObject.transform.position - transform.position;
            bool    isVert = (Mathf.Abs(dPos.y) > Mathf.Abs(dPos.x));

            //move
            tS.Add((callBack) =>
            {
                SimpleTween.Move(mObject.gameObject, mObject.gameObject.transform.position, transform.position, tweenTime * distK).AddCompleteCallBack(() =>
                {
                    mObject.transform.position = transform.position;
                    callBack();
                }).SetEase(EaseAnim.EaseInSine);
            });

            //curve deform
            tS.Add((callBack) =>
            {
                SimpleTween.Value(mObject, 0.0f, 1f, 0.1f).SetEase(EaseAnim.EaseInSine).SetOnUpdate((float val) =>
                {
                    float t_scale = 1.0f + scaleCurve.Evaluate(val) * 0.1f;
                    mObject.transform.localScale = (isVert) ? new Vector3(t_scale, 2.0f - t_scale, 1) : new Vector3(2.0f - t_scale, t_scale, 1);  //  mObject.SetLocalScaleX(t_scale); //  mObject.SetLocalScaleY(2.0f - t_scale);
                }).AddCompleteCallBack(() =>
                {
                    PhysStep = false;
                    completeCallBack?.Invoke();
                    callBack();
                });
            });

            tS.Start();
        }
Beispiel #7
0
        /// <summary>
        /// Collect match object, hit overlays, hit underlays
        /// </summary>
        /// <param name="completeCallBack"></param>
        internal void Collect(float delay, bool showPrefab, bool fly, Action completeCallBack)
        {
            transform.parent = null;
            GameObject animPrefab = OData.collectAnimPrefab;

            TweenSeq cSequence = new TweenSeq();

            if (delay > 0)
            {
                cSequence.Add((callBack) =>
                {
                    SimpleTween.Value(gameObject, 0, 1, delay).AddCompleteCallBack(callBack);
                });
            }

            cSequence.Add((callBack) =>
            {
                if (this)
                {
                    SetToFront(true);
                }
                MSound.PlayClip(0, OData.privateClip);
                callBack();
            });

            // sprite seq animation
            if (showPrefab)
            {
                cSequence.Add((callBack) =>
                {
                    Creator.InstantiateAnimPrefab(animPrefab, transform, transform.position, SortingOrder.MainToFront + 1, false,
                                                  () =>
                    {
                        callBack();
                    });
                });
            }

            //fly
            if (fly)
            {
                cSequence.Add((callBack) =>
                {
                    SimpleTween.Move(gameObject, transform.position, MatchBoard.Instance.FlyTarget, 0.4f).AddCompleteCallBack(() =>
                    {
                        //  callBack();
                    });
                    callBack(); // not wait
                });
                cSequence.Add((callBack) =>
                {
                    SimpleTween.Value(gameObject, 0, 1, 0.15f).AddCompleteCallBack(callBack);
                });
            }
            //finish
            cSequence.Add((callBack) =>
            {
                TargetCollectEvent?.Invoke(OData.ID);
                completeCallBack?.Invoke();
                Destroy(gameObject, (fly) ? 0.6f : 0);
                callBack();
            });

            cSequence.Start();
        }
Beispiel #8
0
        public override void ApplyToGrid(GridCell gCell, BoosterObjectData bData, Action completeCallBack)
        {
            if (!gCell.IsMatchable)
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                return;
            }

            Booster b = Booster.ActiveBooster;

            b.AddCount(-1);

            ParallelTween par0 = new ParallelTween();
            ParallelTween par1 = new ParallelTween();
            TweenSeq      bTS  = new TweenSeq();
            CellsGroup    area = GetArea(gCell);

            float             dist     = Vector3.Distance(transform.position, gCell.transform.position);
            List <GameObject> dupBoost = new List <GameObject>();

            dupBoost.Add(b.SceneObject);

            //move activeBooster
            bTS.Add((callBack) =>
            {
                SetToFront(true);
                SimpleTween.Move(gameObject, transform.position, gCell.transform.position, dist / speed).AddCompleteCallBack(() =>
                {
                    MSound.PlayClip(0, bData.privateClip);
                    callBack();
                }).SetEase(EaseAnim.EaseInSine);
            });

            // duplicate and move
            foreach (var c in area.Cells)
            {
                if (c != gCell)
                {
                    par0.Add((callBack) =>
                    {
                        GameObject boost = Instantiate(b.SceneObject);
                        dupBoost.Add(boost);
                        SimpleTween.Move(boost.gameObject, gCell.transform.position, c.transform.position, Vector3.Distance(c.transform.position, gCell.transform.position) / speed).AddCompleteCallBack(() =>
                        {
                            ValuesTween(boost.gameObject, new float[] { 1, 1.3f, 1 }, 0.3f, (val) => { boost.transform.localScale = gCell.transform.lossyScale * val; }, callBack);
                        }).SetEase(EaseAnim.EaseInSine);
                    });
                }
            }

            //apply effect for each cell parallel
            float delay = 0.0f;

            foreach (var c in area.Cells)
            {
                delay += 0.05f;
                float d = delay;
                par1.Add((callBack) =>
                {
                    delayAction(gameObject, d,
                                () =>
                    {
                        Creator.InstantiateAnimPrefab(bData.animPrefab, c.transform, c.transform.position, SortingOrder.BoosterToFront + 2, true, callBack);
                    }
                                );
                });
            }

            // disable boosters
            foreach (var db in dupBoost)
            {
                delay += 0.05f;
                float d = delay;
                par1.Add((callBack) =>
                {
                    delayAction(gameObject, d,
                                () =>
                    {
                        db.SetActive(false);
                    }
                                );
                    callBack();
                });
            }

            // collect match objects
            delay = 0.05f;
            foreach (var c in area.Cells)
            {
                delay += 0.05f;
                float d = delay;
                par1.Add((callBack) =>
                {
                    c.CollectMatch(d, true, false, true, true, callBack);
                });
            }

            bTS.Add((callback) =>
            {
                par0.Start(() =>
                {
                    callback();
                });
            });

            bTS.Add((callback) =>
            {
                par1.Start(() =>
                {
                    callback();
                });
            });

            bTS.Add((callback) =>
            {
                // destroy boosters
                foreach (var db in dupBoost)
                {
                    Destroy(db);
                }

                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                callback();
            });

            bTS.Start();
        }
Beispiel #9
0
        internal override void PlayExplodeAnimation(GridCell gCell, float delay, Action completeCallBack)
        {
            if (!gCell || OData == null)
            {
                completeCallBack?.Invoke();
            }

            Row <GridCell>    r = gCell.GRow;
            Column <GridCell> c = gCell.GColumn;
            // Debug.Log(gCell);

            TweenSeq   anim = new TweenSeq();
            GameObject g    = null;

            anim.Add((callBack) => { delayAction(gameObject, delay, callBack); });

            anim.Add((callBack) => // explode wave
            {
                MBoard.ExplodeWave(0, transform.position, 5, null);
                callBack();
            });

            anim.Add((callBack) =>  //sound
            {
                MSound.PlayClip(0, OData.privateClip);
                callBack();
            });

            if (OData.bombType == BombDir.Horizontal || OData.bombType == BombDir.Vertical)
            {
                anim.Add((callBack) =>
                {
                    g = Instantiate(OData.explodeAnimPrefab);
                    g.transform.position   = transform.position;
                    g.transform.localScale = transform.localScale * 1.2f;
                    callBack();
                });
            }
            else if (OData.bombType == BombDir.Radial)
            {
                anim.Add((callBack) =>
                {
                    g = Instantiate(OData.explodeAnimPrefab);
                    g.transform.position   = transform.position;
                    g.transform.localScale = transform.localScale * 1.0f;
                    callBack();
                });
            }

            else if (OData.bombType == BombDir.Color)
            {
                anim.Add((callBack) => // scale out
                {
                    SetToFront(true);
                    SimpleTween.Value(gameObject, 1, 1.5f, 0.15f).SetOnUpdate((float val) => { transform.localScale = gCell.transform.lossyScale * val; }).AddCompleteCallBack(callBack);
                });
                anim.Add((callBack) => // scale in
                {
                    SimpleTween.Value(gameObject, 1.5f, 1.0f, 0.15f).SetOnUpdate((float val) => { transform.localScale = gCell.transform.lossyScale * val; }).AddCompleteCallBack(callBack);
                    g = Instantiate(OData.explodeAnimPrefab);
                    g.transform.position   = transform.position;
                    g.transform.localScale = transform.localScale * 1.0f;
                });

                CellsGroup    eArea    = GetArea(gCell);
                ParallelTween pT       = new ParallelTween();
                float         incDelay = 0f;
                foreach (var item in eArea.Cells)
                {
                    incDelay += 0.05f;
                    float t = incDelay;
                    pT.Add((cB) =>
                    {
                        delayAction(item.gameObject, t, () =>  // delay tween
                        {
                            Vector2 relativePos     = (item.transform.position - gCell.transform.position).normalized;
                            Quaternion rotation     = Quaternion.FromToRotation(new Vector2(-1, 0), relativePos); // Debug.Log("Dir: " +(item.transform.position - gCell.transform.position) + " : " + rotation.eulerAngles );
                            GameObject cb           = Instantiate(OData.additAnimPrefab, transform.position, rotation);
                            cb.transform.localScale = transform.lossyScale * 1.0f;
                            SimpleTween.Move(cb, cb.transform.position, item.transform.position, 0.2f).AddCompleteCallBack(cB).SetEase(EaseAnim.EaseOutSine);
                        });
                    });
                }

                anim.Add((callBack) =>
                {
                    pT.Start(callBack);
                });
            }

            anim.Add((callBack) =>
            {
                //  Debug.Log("anim complete");
                TargetCollectEvent?.Invoke(GetID());
                completeCallBack?.Invoke();
                callBack();
            });

            anim.Start();
        }
Beispiel #10
0
        public override void ApplyToGrid(GridCell gCell, BoosterObjectData bData, Action completeCallBack)
        {
            if (!gCell.IsMatchable)
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                return;
            }

            Booster b = Booster.ActiveBooster;

            b.AddCount(-1);

            ParallelTween par0 = new ParallelTween();
            TweenSeq      bTS  = new TweenSeq();
            CellsGroup    area = GetArea(gCell);
            // ScoreCollectHandler?.Invoke(area);

            //move activeBooster
            float dist = Vector3.Distance(transform.position, gCell.transform.position);

            bTS.Add((callBack) =>
            {
                SimpleTween.Move(gameObject, transform.position, gCell.transform.position, dist / speed).AddCompleteCallBack(() =>
                {
                    MSound.PlayClip(0, bData.privateClip);
                    Destroy(b.SceneObject, 0.25f);
                    callBack();
                }).SetEase(EaseAnim.EaseInSine);
            });

            //apply effect for each cell parallel
            float delay = 0.0f;

            foreach (var c in area.Cells)
            {
                delay += 0.15f;
                float d = delay;
                par0.Add((callBack) =>
                {
                    delayAction(gameObject, d,
                                () =>
                    {
                        Creator.InstantiateAnimPrefab(bData.animPrefab, c.transform, c.transform.position, SortingOrder.Booster + 1, true, callBack);
                    }
                                );
                });
            }

            delay = 0.15f;
            foreach (var c in area.Cells)
            {
                delay += 0.15f;
                float d = delay;
                par0.Add((callBack) =>
                {
                    c.CollectMatch(d, true, false, true, true, callBack);
                });
            }

            bTS.Add((callback) =>
            {
                par0.Start(() =>
                {
                    callback();
                });
            });

            bTS.Add((callback) =>
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                callback();
            });

            bTS.Start();
        }
Beispiel #11
0
        /// <summary>
        /// Collect match object, hit overlays, hit underlays
        /// </summary>
        /// <param name="completeCallBack"></param>
        internal void Collect(GridCell gCell, float delay, bool showPrefab, bool fly, bool hitProtection, bool sideHitProtection, Action completeCallBack)
        {
            this.gCell       = gCell;
            transform.parent = null;

            GameObject animPrefab = OData.collectAnimPrefab;

            collectSequence = new TweenSeq();
            if (delay > 0)
            {
                collectSequence.Add((callBack) => {
                    SimpleTween.Value(gameObject, 0, 1, delay).AddCompleteCallBack(callBack);
                });
            }

            // play sound
            collectSequence.Add((callBack) =>
            {
                MSound.PlayClip(0, OData.privateClip);
                callBack();
            });

            // sprite seq animation
            if (showPrefab)
            {
                collectSequence.Add((callBack) =>
                {
                    if (this && !fly)
                    {
                        GetComponent <SpriteRenderer>().enabled = false;
                    }
                    GameObject aG = Creator.InstantiateAnimPrefab(animPrefab, transform, transform.position, SortingOrder.Main, false,
                                                                  () =>
                    {
                        if (this && fly)
                        {
                            SetToFront(true);
                        }
                        callBack();
                    });
                    aG.transform.parent = null; // unparent for play full animation
                });
            }

            // hit protection
            collectSequence.Add((callBack) =>
            {
                if (hitProtection)
                {
                    gCell.DirectHitUnderlay(null);
                    gCell.DirectHitOverlay(null);
                }
                if (sideHitProtection)
                {
                    gCell.Neighbors.Cells.ForEach((GridCell c) => { c.SideHit(null); });
                }
                callBack();
            });

            //fly
            if (fly)
            {
                collectSequence.Add((callBack) =>
                {
                    SimpleTween.Move(gameObject, transform.position, MatchBoard.Instance.FlyTarget, 0.4f).AddCompleteCallBack(() =>
                    {
                        //  callBack();
                    });
                    callBack(); // not wait
                });
                collectSequence.Add((callBack) => {
                    SimpleTween.Value(gameObject, 0, 1, 0.15f).AddCompleteCallBack(callBack);
                });
            }
            // finish
            collectSequence.Add((callBack) =>
            {
                // Debug.Log(ToString()+  " collected");
                ScoreCollectEvent?.Invoke();
                TargetCollectEvent?.Invoke(OData.ID);
                completeCallBack?.Invoke();
                Destroy(gameObject, (fly) ? 0.4f: 0);
            });

            collectSequence.Start();
        }
Beispiel #12
0
        private void SetStars(int count)
        {
            if (!starLeftSet)
            {
                starLeftFull.SetActive(count >= 1);
            }
            if (!starMiddleSet)
            {
                starMiddleFull.SetActive(count >= 2);
            }
            if (!starRightSet)
            {
                starRightFull.SetActive(count >= 3);
            }

            ts = new TweenSeq();
            if (count >= 1 && !starLeftSet)
            {
                starLeftSet = true;

                ts.Add((callBack) =>
                {
                    if (curveLeft)
                    {
                        float time = curveLeft.Length / speed;
                        curveLeft.MoveAlongPath(starLeftFull.gameObject, starLeftEmpty.transform, time, 0f, EaseAnim.EaseInOutSine, callBack);
                    }
                    else
                    {
                        SimpleTween.Move(starLeftFull.gameObject, starLeftFull.transform.position, starLeftEmpty.transform.position, 0.5f).AddCompleteCallBack(() =>
                        {
                            callBack();
                        });
                    }
                });
            }
            if (count >= 2 && !starMiddleSet)
            {
                starMiddleSet = true;
                ts.Add((callBack) =>
                {
                    if (curveMiddle)
                    {
                        float time = curveMiddle.Length / speed;
                        curveMiddle.MoveAlongPath(starMiddleFull.gameObject, starMiddleEmpty.transform, time, 0f, EaseAnim.EaseInOutSine, callBack);
                    }
                    else
                    {
                        SimpleTween.Move(starMiddleFull.gameObject, starMiddleFull.transform.position, starMiddleEmpty.transform.position, 0.5f).AddCompleteCallBack(() =>
                        {
                            callBack();
                        });
                    }
                });
            }
            if (count >= 3 && !starRightSet)
            {
                starRightSet = true;
                ts.Add((callBack) =>
                {
                    if (curveRight)
                    {
                        float time = curveRight.Length / speed;
                        curveRight.MoveAlongPath(starRightFull.gameObject, starRightEmpty.transform, time, 0f, EaseAnim.EaseInOutSine, callBack);
                    }
                    else
                    {
                        SimpleTween.Move(starRightFull.gameObject, starRightFull.transform.position, starRightEmpty.transform.position, 0.5f).AddCompleteCallBack(() =>
                        {
                            callBack();
                        });
                    }
                });
            }
            ts.Start();
        }
Beispiel #13
0
        public override void ApplyToGrid(GridCell gCell, BoosterObjectData bData, Action completeCallBack)
        {
            if (!gCell.Overlay)
            {
                if (!gCell.Match && !gCell.StaticBlocker && !gCell.DynamicBlocker)
                {
                    Booster.ActiveBooster.DeActivateBooster();
                    completeCallBack?.Invoke();
                    return;
                }
            }

            Booster b = Booster.ActiveBooster;

            b.AddCount(-1);

            ParallelTween par0 = new ParallelTween();
            TweenSeq      bTS  = new TweenSeq();

            //move activeBooster
            Vector3 pos      = transform.position;
            float   dist     = Vector3.Distance(transform.position, gCell.transform.position);
            Vector3 rotPivot = Vector3.zero;
            float   rotRad   = 6f;

            bTS.Add((callBack) =>
            {
                SetToFront(true);
                SimpleTween.Move(b.SceneObject, b.SceneObject.transform.position, gCell.transform.position, dist / speed).AddCompleteCallBack(() =>
                {
                    rotPivot = transform.position - new Vector3(0, rotRad, 0);
                    callBack();
                }).SetEase(EaseAnim.EaseInSine);
            });


            // back move
            bTS.Add((callBack) =>
            {
                SimpleTween.Value(gameObject, Mathf.Deg2Rad * 90f, Mathf.Deg2Rad * 180f, 0.25f).SetEase(EaseAnim.EaseInCubic). //
                SetOnUpdate((float val) => { transform.position = new Vector3(rotRad * Mathf.Cos(val), rotRad * Mathf.Sin(val), 0) + rotPivot; }).
                AddCompleteCallBack(() => { callBack(); });
            });
            //forward move
            bTS.Add((callBack) =>
            {
                SimpleTween.Value(gameObject, Mathf.Deg2Rad * 180f, Mathf.Deg2Rad * 100f, 0.2f).SetEase(EaseAnim.EaseOutBounce).
                SetOnUpdate((float val) =>
                {
                    transform.position = new Vector3(rotRad * Mathf.Cos(val), rotRad * Mathf.Sin(val), 0) + rotPivot;
                }).
                AddCompleteCallBack(() =>
                {
                    MSound.PlayClip(0, bData.privateClip);
                    Destroy(gameObject, 0.25f);
                    Creator.InstantiateAnimPrefab(bData.animPrefab, gCell.transform, gCell.transform.position, SortingOrder.BoosterToFront + 2, true, callBack);
                });
            });

            //  if (gCell.IsMatchable)
            {
                bTS.Add((callBack) =>
                {
                    GridCell.ExplodeCell(gCell, 0, true, false, true, callBack);
                    // gCell.CollectMatch(0, true, false, true, true, callBack);
                });
            }


            bTS.Add((callback) =>
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                callback();
            });

            bTS.Start();
        }
Beispiel #14
0
        public override void ApplyToGrid(GridCell gCell, BoosterObjectData bData, Action completeCallBack)
        {
            if (!gCell.IsMatchable)
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                return;
            }

            Booster b = Booster.ActiveBooster;

            b.AddCount(-1);

            ParallelTween par0 = new ParallelTween();
            TweenSeq      bTS  = new TweenSeq();
            CellsGroup    area = GetArea(gCell);

            //move activeBooster
            float dist = Vector3.Distance(transform.position, gCell.transform.position);

            bTS.Add((callBack) =>
            {
                SetToFront(true);
                SimpleTween.Move(gameObject, transform.position, gCell.transform.position, dist / speed).AddCompleteCallBack(() =>
                {
                    ValuesTween(gameObject, new float[] { 1, 1.3f, 1 }, 0.3f, (val) => { transform.localScale = gCell.transform.lossyScale * val; }, callBack);
                    MSound.PlayClip(0, bData.privateClip);
                }).SetEase(EaseAnim.EaseInSine);
            });

            bTS.Add((callBack) => // explode wave
            {
                MBoard.ExplodeWave(0, transform.position, 5, null);
                callBack();
            });

            bTS.Add((callBack) =>
            {
                GameObject g           = Instantiate(explodePrefab);
                g.transform.position   = transform.position;
                g.transform.localScale = transform.localScale * 1.0f;
                callBack();
            });

            bTS.Add((callBack) =>
            {
                Destroy(b.SceneObject, 0.1f);
                callBack();
            });

            //apply effect for each cell parallel
            float delay = 0.0f;

            foreach (var c in area.Cells)
            {
                if (!c.IsDisabled && !c.Blocked)
                {
                    float d        = delay;
                    float distance = Vector2.Distance(c.transform.position, gCell.transform.position);
                    d = distance / 15f + delay;
                    par0.Add((callBack) =>
                    {
                        delayAction(gameObject, d,
                                    () =>
                        {
                            Creator.InstantiateAnimPrefab(bData.animPrefab, c.transform, c.transform.position, SortingOrder.BoosterToFront + 2, true, null);
                            callBack();
                        }
                                    );
                    });
                }
            }

            delay = 0.15f;
            foreach (GridCell mc in area.Cells) //parallel explode all cells
            {
                float t        = 0;
                float distance = Vector2.Distance(mc.transform.position, gCell.transform.position);
                t = distance / 15f;
                par0.Add((callBack) =>
                {
                    GridCell.ExplodeCell(mc, t, false, false, true, callBack);
                });
            }

            bTS.Add((callback) =>
            {
                par0.Start(() =>
                {
                    callback();
                });
            });

            bTS.Add((callback) =>
            {
                Booster.ActiveBooster.DeActivateBooster();
                completeCallBack?.Invoke();
                callback();
            });

            bTS.Start();
        }