TapTapTap!!!(7)~ゲーム終了の条件をつける~

TapTapTap!!!(6)~点数機能を追加する~ではボタンをタップしたときに点数を追加する処理を加えた。今回は、ゲームが終了する条件を追加する。

良く見かける終了条件はライフポイントみたいなものを用意し、ミスをしたら終了する。最後までやり、高得点を狙うなど様々あると思う。

今回の終了条件は少々特殊な終了条件にしたいと考えている。初期の持ち点を100点としボタンがタップできれば加点、できなければ減点とし持ち点が 0 になったときをゲームオーバーにしたいと思う。

1.ゲームオーバー用のテキストオブジェクトを作成する

テキストオブジェクトの作成方法についてはTapTapTap!!!(5)~ボタン出現時に文字を表示する~に記載しているため省略する。

ゲームオーバーのテキストを用意して Prefabとしてドラッグアンドドロップしておこう。

2.点数の減算処理を加える

今までは、ボタンをクリックした際に点数を加算する処理のみを行って来た。そこで今回は 0 点以下になったときにゲームオーバーとしたいので、以下のプログラム変更を加える。ButtonAction.cs 内でのポイント加算処理を削除。

ButtonAction.cs

[cce_csharp]using UnityEngine;

public class ButtonAction : MonoBehaviour {
    /// <summary>
    /// 生成する「Tap!」テキストオブジェクト
    /// </summary>
    [SerializeField]
    public GameObject text;
    /// <summary>
    /// 「Tap!」テキストオブジェクトの削除時間
    /// </summary>
    public float destroyTime;
   
    /// <summary>
    /// ボタンがタップされたときの処理。「Tap!」テキストの表示位置計算および表示。
    /// 自身のボタン削除を行う。
    /// </summary>
    public void OnClick() {
        // 世界座標系
        Vector3 worldPosition = this.gameObject.transform.position;
        // canvas オブジェクトの取得
        GameObject parent = this.gameObject.transform.root.gameObject;
        Vector3 parentPosition = parent.transform.position;
        Vector3 position = new Vector3(worldPosition.x - parentPosition.x, worldPosition.y - parentPosition.y, 0);
        // 自身が登録されているオブジェクトを削除する
        Destroy(this.gameObject);
        viewTapText(parent, position);

    }

    /// <summary>
    /// 「Tap!」テキストの表示。
    /// </summary>
    /// <param name="parent">「Tap!」テキストを表示するためのキャンバス</param>
    /// <param name="position">「Tap!」の表示位置</param>
    private void viewTapText(GameObject parent,Vector3 position) {
        //指定位置のテキストを表示
        GameObject prefab = (GameObject)Instantiate(text);
        prefab.transform.position = position;
        prefab.transform.SetParent(parent.transform, false);
        Destroy(prefab, destroyTime);
    }
}[/cce_csharp]

ButtonManager.cs の Update 内で コルーチンを呼び出し、その中でポイント加減算処理の追加を加えた。

ButtonManager.cs

[cce_csharp]using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class ButtonManager : MonoBehaviour {
    /// <summary>
    /// 生成するボタンオブジェクト
    /// </summary>
    [SerializeField]
    public GameObject button;
    /// <summary>
    /// ボタンやポイントを表示するためのキャンバス
    /// </summary>
    [SerializeField]
    public GameObject canvas;
    /// <summary>
    /// ボタン出現時間
    /// </summary>
    public float buttonAppearanceTime;
    /// <summary>
    /// ボタン消滅時間
    /// </summary>
    public float buttonExtinctionTime;
    /// <summary>
    /// ポイント表示用テキストオブジェクト
    /// </summary>
    public Text pointText;
    /// <summary>
    /// ボタン表示位置(幅)の上下限値の絶対値
    /// </summary>
    private int screenWidth;
    /// <summary>
    /// ボタン表示位置(高さ)の上下限値の絶対値
    /// </summary>
    private int screenHeight;
    /// <summary>
    /// ボタン出現時のタイムアウト管理
    /// </summary>
    private float timeOut;

    /// <summary>
    /// ゲーム開始時の処理。画面サイズの取得を行う。
    /// </summary>
    void Start() {
        screenWidth = (Screen.width - 100) - (Screen.width - 100) / 2;
        screenHeight = (Screen.height - 100) - (Screen.height - 100) / 2;
    }
    /// <summary>
    /// 逐次更新された際の処理。時間の管理やボタンの生成、ゲームオーバーの判定を逐次行う。
    /// </summary>
    void Update() {
        timeOut += Time.deltaTime;
        // timeOut が buttonAppearanceTime を超えたらボタンを出現させる
        if (buttonAppearanceTime < timeOut) {
            StartCoroutine("execute");
            timeOut = 0;
        }
    }

    /// <summary>
    /// ボタンの生成処理。ボタンの生成を行う。
    /// </summary>
    /// <returns>生成されたボタンオブジェクト</returns>
    private GameObject createButton() {
        GameObject prefab = (GameObject)Instantiate(button);
        Vector3 position = new Vector3(Random.Range(-screenWidth, screenWidth), Random.Range(-screenHeight, screenHeight), 0);
        prefab.transform.position = position;
        prefab.transform.SetParent(canvas.transform, false);
        return prefab;
    }

    /// <summary>
    /// 本ゲームのメイン実行処理。ボタンの生成や点数の加減計算を行う。
    /// </summary>
    /// <returns>IEnumerator オブジェクト</returns>
    private IEnumerator execute() {
        GameObject prefab = createButton();
        yield return new WaitForSeconds(buttonExtinctionTime);
        int count;
        // ボタンタップによってボタンオブジェクtが削除されているときは加点、
        // 削除されていなかったときは減点する
        if (prefab != null) {
            GameObject.Destroy(prefab);
            failure--;
            count = failure;
            succession = 0;
        } else {
            succession++;
            count = succession;
            failure = 0;
        }
        FindObjectOfType<Score>().addPoint(10 * count);
    }
}[/cce_csharp]

 

今まで進めてきた方々には申し訳ないのだが、プログラムの規模も大きくなってきたため、コメントの記載方法も改めたので注意してほしい。内容についてはほぼ変更はない。

3.ゲームオーバーテキストの表示

以下の内容は点数が 0点以下になったときにゲームオーバーテキストを表示するためのものだ。ゲームの状態をフラグで管理し、ゲームオーバーとなったらその状態で終了する。

ButtonManager.cs

[cce_csharp]using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class ButtonManager : MonoBehaviour {
    /// <summary>
    /// 生成するボタンオブジェクト
    /// </summary>
    [SerializeField]
    public GameObject button;
    /// <summary>
    /// ボタンやポイントを表示するためのキャンバス
    /// </summary>
    [SerializeField]
    public GameObject canvas;
    /// <summary>
    /// ゲームオーバーテキストオブジェクト
    /// </summary>
    [SerializeField]
    public GameObject gameOverText;
    /// <summary>
    /// ボタン出現時間
    /// </summary>
    public float buttonAppearanceTime;
    /// <summary>
    /// ボタン消滅時間
    /// </summary>
    public float buttonExtinctionTime;
    /// <summary>
    /// ポイント表示用テキストオブジェクト
    /// </summary>
    public Text pointText;
    /// <summary>
    /// ボタン表示位置(幅)の上下限値の絶対値
    /// </summary>
    private int screenWidth;
    /// <summary>
    /// ボタン表示位置(高さ)の上下限値の絶対値
    /// </summary>
    private int screenHeight;
    /// <summary>
    /// 連続成功回数
    /// </summary>
    private int succession;
    /// <summary>
    /// 連続失敗回数
    /// </summary>
    private int failure;
    /// <summary>
    /// ゲームオーバー判定フラグ
    /// </summary>
    private bool gameOver = false;
    /// <summary>
    /// ボタン出現時のタイムアウト管理
    /// </summary>
    private float timeOut;

    /// <summary>
    /// ゲーム開始時の処理。画面サイズの取得を行う。
    /// </summary>
    void Start() {
        screenWidth = (Screen.width - 100) - (Screen.width - 100) / 2;
        screenHeight = (Screen.height - 100) - (Screen.height - 100) / 2;
    }
    /// <summary>
    /// 逐次更新された際の処理。時間の管理やボタンの生成、ゲームオーバーの判定を逐次行う。
    /// </summary>
    void Update() {
        timeOut += Time.deltaTime;
        // timeOut が buttonAppearanceTime を超えたらボタンを出現させる
        if (!gameOver && buttonAppearanceTime < timeOut) {
            StartCoroutine("execute");
            timeOut = 0;
        }
        // ポイントが 0 以下になったらゲームオーバー
        if (!gameOver && FindObjectOfType<Score>().getPoint() <= 0) {
            GameObject prefab = (GameObject)Instantiate(gameOverText);
            prefab.transform.SetParent(canvas.transform, false);
            gameOver = true;
        }
    }

    /// <summary>
    /// ボタンの生成処理。ボタンの生成を行う。
    /// </summary>
    /// <returns>生成されたボタンオブジェクト</returns>
    private GameObject createButton() {
        GameObject prefab = (GameObject)Instantiate(button);
        Vector3 position = new Vector3(Random.Range(-screenWidth, screenWidth), Random.Range(-screenHeight, screenHeight), 0);
        prefab.transform.position = position;
        prefab.transform.SetParent(canvas.transform, false);
        return prefab;
    }

    /// <summary>
    /// 本ゲームのメイン実行処理。ボタンの生成や点数の加減計算を行う。
    /// </summary>
    /// <returns>IEnumerator オブジェクト</returns>
    private IEnumerator execute() {
        GameObject prefab = createButton();
        yield return new WaitForSeconds(buttonExtinctionTime);
        int count;
        // ボタンタップによってボタンオブジェクtが削除されているときは加点、
        // 削除されていなかったときは減点する
        if (prefab != null) {
            GameObject.Destroy(prefab);
            failure--;
            count = failure;
            succession = 0;
        } else {
            succession++;
            count = succession;
            failure = 0;
        }
        FindObjectOfType<Score>().addPoint(10 * count);
    }
}[/cce_csharp]
%d人のブロガーが「いいね」をつけました。