Unityでぷよぷよを作ってみた 3
スポンサードリンク
ぷよの消去
毎フレーム、状態がVanishのとき以下の処理を行う。
- 隣接した同色ぷよを取得する(同色リスト)。
- 同色リストのぷよが4つ以上のものを消去可能リストに追加する。
- 消去可能リストの中のぷよを全て消去する。
隣接した同色ぷよの取得
迷路を深さ優先探索で解くかんじで、隣接する同色ぷよを取得する。
private readonly int[,] dirs = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; private readonly Puyo[,] field; private readonly int width; private readonly int height; //隣接した同色ぷよを取得 private List<Puyo> PickSameColor(Puyo puyo) { //同色リスト var same = new List<Puyo>(); puyo.Checked = true; //ぷよの上下左右を調べる for (int i = 0; i < dirs.GetLength(0); i++) { int nx = puyo.IntX + dirs[i, 0]; int ny = puyo.IntY + dirs[i, 1]; if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; var np = field[nx, ny]; if (np == null || np.Checked || puyo.Color != np.Color) continue; var s = PickSameColor(np); same.AddRange(s); } same.Add(puyo); return same; }
消去可能なぷよの取得
全てのぷよで以下の処理を行う。
- 隣接した同色ぷよを取得する(同色リスト)。
- 同色リストのぷよが4つ以上のものを消去可能リストに追加する。
private readonly Puyo[,] field; private readonly int width; private readonly int height; //消去できるぷよを取得 public List<Puyo> GetVanishablePuyoes(Puyo[,] field) { //消去可能リスト var vanishable = new List<Puyo>(); ClearCheckedFlag(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { var p = field[x, y]; if (p == null || p.Checked) continue; var same = PickSameColor(p); //同色リストの中身が4以上なら消去可能リストに追加 if (same.Count >= 4) { vanishable.AddRange(same); } } } return vanishable; } //全てのCheckedフラグを消す private void ClearCheckedFlag() { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { var p = field[x, y]; if (p != null) p.Checked = false; } } }
ぷよの消去、連鎖
ぷよを消去した後、ぷよの落下→消去を繰り返すことで連鎖になる。
private static readonly Vanisher vanisher = new Vanisher(field); public List<Puyo> GetVanishablePuyoes() { return vanisher.GetVanishablePuyoes(); }
private static List<Puyo> droppablePuyoes = new List<Puyo>(); private enum State { Normal, FreeFall, Vanish, Wait } private int chainCount; private void Update() { switch (state) { case State.Normal: //落下、移動、回転、固定などの処理 break; case State.FreeFall: //落下可能なぷよを下にあるものから順に落下させる droppablePuyoes.OrderBy(p => p.IntY).ToList<Puyo>() .ForEach(p => p.FreeFall()); //落下できなくなったぷよは全てリストから消す droppablePuyoes.RemoveAll(p => !p.Droppable); if (droppablePuyoes.Count == 0) { //連鎖へ遷移 state = State.Vanish; } break; case State.Vanish: //消去可能ぷよを取得 var vanishable = field.GetVanishablePuyoes(); if (vanishable.Count > 0) { chainCount++; //ぷよを消去 vanishable.ForEach(p => p.Vanish()); //落下可能ぷよを取得 droppablePuyoes = field.GetDroppablePuyoes(); if (droppablePuyoes.Count > 0) state = State.FreeFall; else { //通常へ遷移 state = State.Normal; //この組ぷよ自身の消去と新しい組ぷよの作成 OnFalled(); } } else { //通常へ遷移 state = State.Normal; ////この組ぷよ自身の消去と新しい組ぷよの作成 OnFalled(); } break; case State.Wait: break; } }