Example #1
0
    // ブロック落下処理
    #region
    // 下のマスが空の箇所を探し、ブロックを落下させる
    IEnumerator CheckFallBlocks()
    {
        // ブロックの補充が必要な列を記録する配列
        bool[] ignoreSupply = new bool[StageSize];
        Block  target;

        // 落下中のブロック
        Block[] falling = new Block[0];
        // 左の列から調べる
        for (int j = 0; j < StageSize; j++)
        {
            // 下の行から調べる
            for (int i = StageSize - 2; i + 1 > 0; i--)
            {
                // 下のマス目が空のブロックを探す
                if (stage[i, j] != null && stage[i + 1, j] == null)
                {
                    target = stage[i, j].GetComponent <Block>();
                    if (target.BlockStatus == BlockStatus.NORMAL)
                    {
                        target.BlockStatus = BlockStatus.FALLING;
                        // 配列の大きさを調整,落下対象のブロックを格納
                        Array.Resize <Block>(ref falling, falling.Length + 1);
                        falling[falling.Length - 1] = target;
                        // 下のブロックが空で無くなるか配列の一番下まで
                        for (int x = i; x + 1 < StageSize; x++)
                        {
                            if (stage[x + 1, j] == null)
                            {
                                stage[x + 1, j]      = stage[x, j];
                                stage[x, j]          = null;
                                target.BlockPosition = new BlockPosition(x + 1, j);
                            }
                        }
                    }
                    // ブロックの状態がNORMALでないものが見つかったら次の列を探索する
                    else
                    {
                        // この列にはブロックを補充しない
                        ignoreSupply[j] = true;
                        break;
                    }
                }
            }
        }


        // 次にブロックの補充が必要な位置にブロックを補充する
        CheckEmptyBlocks(ignoreSupply, ref falling);

        // 落下対象のブロックを落下させる
        for (int i = 0; i < falling.Length; i++)
        {
            // 移動先の座標と落下時間を計算
            float   nextPosY = spawner.GetInitPos.y - spawner.GetBlockSize.y * falling[i].BlockPosition.X;
            Vector2 dest     = new Vector2(falling[i].BlockTransform.anchoredPosition.x, nextPosY);
            int     distance = (int)(Mathf.Abs(nextPosY - falling[i].BlockTransform.anchoredPosition.y) / spawner.GetBlockSize.y);
            // 指定した座標と時間で落下
            StartCoroutine(falling[i].MoveBlock(dest, FallTime * distance));
        }
        //全ての落下中のブロックの移動が完了するまで待機
        for (int i = 0; i < falling.Length;)
        {
            // 落下中のブロックを見つけたら待機
            while (falling[i].BlockStatus == BlockStatus.FALLING)
            {
                yield return(new WaitForEndOfFrame());
            }
            i++;
        }


        // 落下終了後,もし削除するブロックが存在するなら削除
        if (TraceBlocks())
        {
            CheckDeleteBlocks();
        }
        // 削除するブロックが存在しない場合,詰み判定を行う
        else
        {
            // 詰みなら盤面をリセットする
            if (IsMating())
            {
                DestroyAll(ref stage);
                // ボーナス得点を加算
                scoreManager.AddBonusScore();
                // ブロックの数を初期化し盤面を再生成
                spawner.BlockInfoProp.InitBlockInfo();
                spawner.InitStage(ref stage);
            }
        }
    }