56.#6

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SameGamePuzzleSceneDirector : MonoBehaviour
{
    // アイテムのプレハブ
    [SerializeField] List<GameObject> prefabBubbles;
    // ゲーム時間
    [SerializeField] float gameTimer;
    // フィールドのアイテム総数
    [SerializeField] int fieldItemCountMax;
    // 削除できるアイテム数
    [SerializeField] int deleteCount;

    // UI
    [SerializeField] TextMeshProUGUI textGameScore;
    [SerializeField] TextMeshProUGUI textGameTimer;
    [SerializeField] GameObject panelGameResult;
    // Audio
    [SerializeField] AudioClip seBubble;
    [SerializeField] AudioClip seSpecial;

    // フィールド上のアイテム
    List<GameObject> bubbles;
    // スコア
    int gameScore;
    // 再生装置
    AudioSource audioSource;


    // Start is called before the first frame update
    void Start()
    {
        // Audio
        audioSource = GetComponent<AudioSource>();

        // 全アイテム
        bubbles = new List<GameObject>();

        // リザルト画面非表示
        panelGameResult.SetActive(false);

        // アイテム生成
        SpawnItem(fieldItemCountMax);
    }

    // Update is called once per frame
    void Update()
    {
        // ゲームタイマー更新
        gameTimer -= Time.deltaTime;
        textGameTimer.text = "" + (int)gameTimer;

        // ゲーム終了
        if (0 > gameTimer)
        {
            // リザルト画面表示
            panelGameResult.SetActive(true);
            // Updateに入らないようにする
            enabled = false;
            // この時点でUpdateから抜ける
            return;
        }

        // タッチ処理
        if(Input.GetMouseButtonUp(0))
        {
            // スクリーン座標からワールド座標に変換
            Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            RaycastHit2D hit2d = Physics2D.Raycast(worldPoint, Vector2.zero);

            // 削除されたアイテムをクリア
            bubbles.RemoveAll(item => item == null);

            // なにか当たり判定があれば
            if(hit2d)
            {
                // 当たり判定があったオブジェクト
                GameObject obj = hit2d.collider.gameObject;
                CheckItems(obj);
            }
        }
    }

    // アイテム生成
    void SpawnItem(int count)
    {
        for (int i = 0; i < count; i++)
        {
            // 色ランダム
            int rnd = Random.Range(0, prefabBubbles.Count);
            // 場所ランダム
            float x = Random.Range(-2.0f, 2.0f);
            float y = Random.Range(-2.0f, 2.0f);

            // アイテム生成
            GameObject bubble =
                Instantiate(prefabBubbles[rnd], new Vector3(x, 7 + y, 0), Quaternion.identity);

            // 内部データ追加
            bubbles.Add(bubble);
        }
    }

    // 引数と同じ色のアイテムを削除する
    void DeleteItems(List<GameObject> checkItems)
    {
        // 削除可能数に達していなかったらなにもしない
        if (checkItems.Count < deleteCount) return;

        // ボーナスとしてオーバーしたカウント*5個削除
        int overCount = checkItems.Count - deleteCount;
        overCount *= 5;

        // ランダムなアイテムを削除リストに追加(かぶりの可能性あり)
        while(overCount > 0)
        {
            int rnd = Random.Range(0, bubbles.Count);
            checkItems.Add(bubbles[rnd]);
            overCount--;

            // 最後の1個でSE再生
            if(overCount == 0)
            {
                audioSource.PlayOneShot(seSpecial);
            }
        }


        // 削除してスコア加算
        List<GameObject> destroyItems = new List<GameObject>();
        foreach (var item in checkItems)
        {
            // かぶりなしの削除したアイテムをカウント
            if(!destroyItems.Contains(item))
            {
                destroyItems.Add(item);
            }

            //削除
            Destroy(item);
        }

        // 実際に削除した分生成してスコア加算
        SpawnItem(destroyItems.Count);
        gameScore += destroyItems.Count * 100;

        // スコア表示更新
        textGameScore.text = "" + gameScore;

        // SE再生
        audioSource.PlayOneShot(seBubble);
    }

    // 同じ色のアイテムを返す
    List<GameObject> GetSameItems(GameObject target)
    {
        List<GameObject> ret = new List<GameObject>();

        foreach (var item in bubbles)
        {
            // アイテムがない、同じアイテム、違う色、距離が遠い場合はスキップ
            if (!item || target == item) continue;

            if(item.GetComponent<SpriteRenderer>().sprite
                != target.GetComponent<SpriteRenderer>().sprite)
            {
                continue;
            }

            float distance
                = Vector2.Distance(target.transform.position, item.transform.position);

            if (distance > 1.1f) continue;

            // ここまできたらアイテム追加
            ret.Add(item);
        }

        return ret;
    }

    // 引数と同じ色のアイテムを探す
    void CheckItems(GameObject target)
    {
        // このアイテムと同じ色を追加する
        List<GameObject> checkItems = new List<GameObject>();
        // 自分を追加
        checkItems.Add(target);

        // チェック済のインデックス
        int checkIndex = 0;

        // checkItemsの最大値までループ
        while (checkIndex < checkItems.Count)
        {
            // 隣接する同じ色を取得
            List<GameObject> sameItems = GetSameItems(checkItems[checkIndex]);
            // チェック済のインデックスを進める
            checkIndex++;

            // まだ追加されていないアイテムを追加する
            foreach (var item in sameItems)
            {
                if (checkItems.Contains(item)) continue;
                checkItems.Add(item);
            }
        }

        // 削除
        DeleteItems(checkItems);
    }

    // リトライボタン
    public void OnClickRetry()
    {
        SceneManager.LoadScene("SameGamePuzzleScene");
    }
}
つむつむ

前の記事

55.#5
つむつむ

次の記事

57.#7