前回作った3Matchパズル(ロジックのみ)ですが、ピースが消える部分や、補充される部分があまりにも味気ないので、ちょっとそれっぽくします。
■前回の内容
Unityでパズドラ風3Matchパズルを作る_その1_ロジック編 - スマゲ
■本編の完成イメージ
■コード確認用リポジトリ
github.com
■環境
Mac OS Sierra 10.12.4
Unity 5.6.0 f3
言語 C#
■実装
ここからは[その1]のつづきです。
まだ見てない方はここから確認してみてください。
■削除とピースの補充のタイミングで一定時間処理を止める
[Board.cs]の[DeleteMatchPiece]と[FillPiece]を以下のように書き換えます
// マッチングしているピースを削除する public IEnumerator DeleteMatchPiece(Action endCallBadk) { // マッチしているピースの削除フラグを立てる foreach (var piece in board) { piece.deleteFlag = IsMatchPiece(piece); } // 削除フラグが立っているオブジェクトを削除する foreach (var piece in board) { if (piece != null && piece.deleteFlag) { Destroy(piece.gameObject); } } yield return new WaitForSeconds(1f); endCallBadk(); } // ピースが消えている場所を詰めて、新しいピースを生成する public IEnumerator FillPiece(Action endCallBack) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { FillPiece(new Vector2(i, j)); } } yield return new WaitForSeconds(1f); endCallBack(); }
変更点は返り値にIEnumeratorを指定したこと、引数にActionを取るようにしたこと、最後に一秒待ってから引数に取ったActionを実行するようにしたことです。
次は[GameManager.cs] の [DeletePiece]と[FillPiece]を以下のように書き換えます
// マッチングしているピースを削除する private void DeletePiece() { currentState = GameState.Wait; StartCoroutine(board.DeleteMatchPiece(() => currentState = GameState.FillPiece)); } // 盤面上のかけている部分にピースを補充する private void FillPiece() { currentState = GameState.Wait; StartCoroutine(board.FillPiece(() => currentState = GameState.MatchCheck)); }
変更点は[StartCoroutine]により[Board.cs]のコルーチンを実行していること、終了時のコールバックをメソッドの引数にしていることです。
■実行
ちょっとだけ処理が見やすくなりました。
■ピースが順番に消されるようにする
今のままだと、マッチングしているピースが一斉に消えてしまうので順番に消えるようにしてみます
■ピース削除の処理を変える
[Board.cs]の[DeleteMatchPiece]を以下のように編集します
// マッチングしているピースを削除する public IEnumerator DeleteMatchPiece(Action endCallBadk) { foreach (var piece in board) { if (piece != null && IsMatchPiece(piece)) { var pos = GetPieceBoardPos(piece); DestroyMatchPiece(pos, piece.GetKind()); yield return new WaitForSeconds(0.5f); } } endCallBadk(); }
そしてクラスの一番下に以下のメソッドを付け足します。
// 特定のピースがマッチしている場合、ほかのマッチしたピースとともに削除する private void DestroyMatchPiece(Vector2 pos, PieceKind kind) { // ピースの場所が盤面以外だったら何もしない if (!IsInBoard(pos)) { return; } // ピースが無効であったり削除フラグが立っていたりそもそも、種別がちがうならば何もしない var piece = board[(int)pos.x, (int)pos.y]; if (piece == null || piece.deleteFlag || piece.GetKind() != kind) { return; } // ピースが同じ種類でもマッチングしてなければ何もしない if (!IsMatchPiece(piece)) { return; } // 削除フラグをたてて、周り4方のピースを判定する piece.deleteFlag = true; foreach (var dir in directions) { DestroyMatchPiece(pos + dir, kind); } // ピースを削除する Destroy(piece.gameObject); }
やっている内容は盤面を走査し、マッチングしているピースがあれば、そのピースに隣接するピースを参照します。
そのピースがマッチングしているピースでかつ同じ種類のものであれば、削除フラグを立て、さらに走査をすすめるという方法です。
■実行
■その3_演出編2
次はピースが補充される演出を組み込もうと思いましたが、少し長くなりそうなのでその3でやってみようとおもいます。
Unityでパズドラ風3Matchパズルを作る_その3_演出編2 - スマゲ
■関連リンク
Unityでパズドラ風3Matchパズルを作る_その1_ロジック編 - スマゲ
Unityでパズドラ風3Matchパズルを作る_その3_演出編2 - スマゲ
Unityでパズドラ風3Matchパズルを作る_その4_演出編3 - スマゲ
Unityでパズドラ風3Matchパズルを作る_その5_演出編4 - スマゲ
Unityでパズドラ風3Matchパズルを作る_その6_ステータス表示編 - スマゲ