TapTapTap!!!(6)~点数機能を追加する~ではボタンをタップしたときに点数を追加する処理を加えた。今回は、ゲームが終了する条件を追加する。
良く見かける終了条件はライフポイントみたいなものを用意し、ミスをしたら終了する。最後までやり、高得点を狙うなど様々あると思う。
今回の終了条件は少々特殊な終了条件にしたいと考えている。初期の持ち点を100点としボタンがタップできれば加点、できなければ減点とし持ち点が 0 になったときをゲームオーバーにしたいと思う。
1.ゲームオーバー用のテキストオブジェクトを作成する
テキストオブジェクトの作成方法についてはTapTapTap!!!(5)~ボタン出現時に文字を表示する~に記載しているため省略する。
TapTapTap!!!(4)~ボタンをランダムに出現させる~ではボタンが出現する際にランダムな位置に出現する処理を加えた。今回はタップしたときにという文字を表示する処理を加える。 TapTapTap!!!(5)~ボタン出現時に文字を表示する~ | StudioFun - StudioFun |
ゲームオーバーのテキストを用意して 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]