// ブロック落下処理 #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); } } }