[Unity] ブロック崩しをあのアプリ風にする #11 クリアしたら次のステージへ

1ステージだけやってても飽きるのでステージを増やして、クリアしたら自動で次のステージへ移るようにします。


次のステージ』で探したらこんな画像が出てきました。

ステージ管理

あらかじめ適当なステージを複数作っておいてBlockManagerのWavesに追加しておきます。



簡単なステージ管理を実装します。この辺りは適当に作るとあとあと混乱するのでわかりやすい構造を心がけていきたいと思います。

クリア判定

考えられるタイミングは2つあります。
  • 画面上のブロックがなくなったら
  • ボールが手元に戻った時点で画面にブロックがなければ

本家では後者を採用しているようなのでそっちを採用します。
そしてそのタイミングに都合がいいのはBlockManagerのMoveメソッドなのでそこを起点に拡張していきます。
ゲームの進行状態はGameManagerに管理してもらいたいので、BlockManagerは『1ステージクリアしたよ』というコールだけしてもらうことにします。

BlockManagerの編集



//現在のwave
    int currentWave;
//〜中略〜

    public void Init(int stage){
        BlockSet(stage);
        currentWave = stage;
        GameObject obj = GameObject.Find ("Bwall");
        gameOverLine = obj.transform.position.z + obj.transform.lossyScale.z/2 + 0.4f;
        dengerLine = gameOverLine + 0.8f;
    }
//〜中略〜

public void MoveBlock(){
//次のwaveをセット
    if (wave.transform.childCount == 0) {
        GameObject.Find ("GameManager").GetComponent<GameManager>().NextStage(currentWave);
        return;
    }
    Vector3 pos = wave.transform.position;
    pos.z -= 0.8f;
    StartCoroutine("Move",pos);
}

初期化処理であるinit()でステージ番号を受け取るようにします。それを現在のステージとして保持しておきます。
MoveBlock()ではオブジェクト.transform.childCountで子要素の数を取得します。transformに子要素がぶら下がってるというのはあまり感覚的ではないですが,そういうものらしいです。
そしてブロックがなければ現在のステージが終了したことをGameManagerに通知します。


GameMangerの編集



//〜中略〜
private int currentStage;

void Start () {
    currentStage = 0;
    Init (currentStage);
}

public void Init(int stage){
    GameObject Bwall = GameObject.Find ("Bwall");
    float _z = Bwall.transform.position.z + Bwall.transform.lossyScale.z/2 + 0.4f;
    ballBornPoint.transform.position = transform.position= new Vector3 (0, 0, _z);;
    gameOverText.enabled = false;
    reBtn.SetActive(false);
    blockMgr.Init (stage);
    ballMgr.Init ();
    Invoke ("InputSet", 0.5f);
}
//〜中略〜

//BlockManagerが呼ぶ
public void NextStage(int clearStg){
    currentStage = clearStg + 1;
    Init (currentStage);
}

やっていることはステージ情報の受け渡しです。BlockManagerから渡ってきた番号に+1してInit()を呼び出しそのままBlockManagerのInit()に渡します。
GameManagerを仲介するのは進行を通知するためです。


BallManagerの編集


ballManagerでやることはボールを初期位置に戻すだけですが、その際init()内で一旦Ballを破棄しています。破棄されたタイミングで集合コルーチンが処理中だとエラーが出るのでNullチェックを挟みます。

//〜中略〜
//集合コルーチン
IEnumerator setPos(GameObject ball){
    while (ball != null) {
//集合ポイントより離れていれば
        if (Mathf.Abs (ball.transform.position.x - ballBornPoint.position.x) > 1) {
            int dir = ball.transform.position.x < ballBornPoint.position.x ? 1 : -1;
            ball.transform.position += new Vector3 (dir, 0, 0);
        } else {
// 離れてなければ座標を合わせてループを抜ける
            ball.transform.position = ballBornPoint.position;
            break;
        }
        yield return null;
    }
}
//〜中略〜

全て破壊すると次のステージが現れる。


コメント