unityで、簡単な神経衰弱ゲームを作ってみたいと思います。
前回、4枚カードがあって、カードの並びが固定で それをめくって「一致するかしないか」という簡単な神経衰弱のプログラムを作りました。 今回はそれを使った応用編です。 今回は、カードの並びをシャッフルして ランダムに並んだ状態で、一致するカードを選んでいく、というプログラムを 作っていきたいと思います。

動画

▼動画内で使用した画像です。ご自由にお使いください

コード

▼CardScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardScript : MonoBehaviour
{
    //1)変数関連
    private GameManager gm;// GameManager
    private Sprite imgBack;// 裏
    private Sprite imgFront;// 表
    public int pairId; // ペアID(同じ番号がペア)

    //2)準備
    private SpriteRenderer sr; //画像表示に関する
    private bool isFront = false; //裏表判定(false=裏, true=表)

    // 3)実行開始
    //SetUp()が呼ばれた時、Start()はまだ準備出来ていない。
    //順番的には、Awake() → SetUp() → Start() の順番で呼ばれます。
    //void Start()
    void Awake()
    {
        sr = GetComponent<SpriteRenderer>();
    }

    //4)ゲームの初期化
    public void SetUp(GameManager manager, Sprite back, Sprite front, int id)
    {
        gm = manager;// 管理人へのアクセス
        imgBack = back;// 裏の絵
        imgFront = front;// 表の絵
        pairId = id;// ペアの番号
        ShowBack(); //裏向きにセット。中身は5へ
    }

    //5)裏向きにセット
    public void ShowBack()
    {
        sr.sprite = imgBack;
        isFront = false;//「今、裏向きですよ」という状態を保持
    }

    //6)表向きにセット
    public void ShowFront()
    {
        sr.sprite = imgFront;
        isFront = true;//「今、表向きですよ」という状態を保持
    }

    //7)ボタンが押されたら
    private void OnMouseDown()
    {
        //もし表向きなら、終了
        if (isFront) return;

        //それ以外なら「このカードがクリックされて表になったよ」と GameManagerに報告する。
        ShowFront(); // 自分を表にする
        gm.OnCardOpened(this);
    }
}

▼GameManager

using System.Collections; // ← 8)これを確認(なければ追加)
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    //1)ゲームに必要な変数
    public CardScript cardPrefab; //プレハブ化したカードオブジェクト
    public Sprite backSprite; //裏面のカード(画像データ)
    public Sprite[] frontSprite = new Sprite[2]; //カードの表面の絵をまとめた配列(2つの画像)

    //2)カードの配置やゲームの進行状況
    public Vector3[] cardPos = new Vector3[4]; //4枚のカードを並べる(位置のリスト)
    private CardScript first, second; //1枚目と2枚目
    private int matchedPairs = 0; //揃ったペア数
    private int totalPairs = 2; //全ペア数(今回は4枚なので2ペア)
    private bool gameClear = false; //ゲームクリアしたらtrue

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("ゲームスタート!");

        //3)ゲーム開始
        first = null; second = null; matchedPairs = 0; gameClear = false;

        //4)デッキ(カードの束)作成 [0,0,1,1] をシャッフル
        //List<型> 変数名 = new List<型>() { "要素0", "要素1", "要素2" };
        List<int> deck = new List<int>() { 0,0,1,1 };

        //4つの要素(0,0,1,1)をシャッフル
        //for文:回数を指定して、同じ処理を繰り返し行いたい時に使う呪文
        //for(初期値; 繰り返す回数; 更新式)
        for (int i = 0; i<4 ; i++)
        {
            //Random.Range(min, max)
            int r = Random.Range(0, 4);//→ 0,1,2,3 の範囲でランダム
            (deck[i], deck[r]) = (deck[r], deck[i]);//i枚目のカードと、ランダム枚目のカードを入れ替える

        }

        //5)カードを生成して配置
        for (int x =0; x < 4 ; x++)
        {
            //Instantiate(何を, 位置, 回転);
            CardScript card = Instantiate(cardPrefab, cardPos[x], Quaternion.identity);
            //カードPrefab(空っぽ)に、情報をセット
            card.SetUp(this, backSprite, frontSprite[deck[x]], deck[x]);
        }

    }

    //6)OnCardOpened関数
    public void OnCardOpened(CardScript cs)
    {
        //1枚目がめくられる
        if(first == null)
        {
            first = cs;//1枚目にめくったカードを記録
            return;// ここで関数を終わりにする
        }

        //もし2枚目だったら
        if(second == null)
        {
            second = cs;//2枚目にめくったカードを記録
            //7)判定処理へ...
            //コルーチンは 作業を途中で止めたり、待ったりしながら進められる特別な関数
            StartCoroutine(Judgement());
        }
    }

    //9)判定の関数
    private IEnumerator Judgement()
    {
        //コルーチンの処理を 0.3 秒だけ中断して、時間が経ったら続きから再開する
        yield return new WaitForSeconds(0.3f);

        //ペアが成立した場合
        if(first.pairId == second.pairId)
        {
            matchedPairs++;//1加算
        }
        else
        {
            //さらに0.5秒中断
            yield return new WaitForSeconds(0.5f);
            first.ShowBack();//裏返す
            second.ShowBack();//裏返す
        }
        first = null;  second = null;

        //ゲームクリア
        if(!gameClear && matchedPairs == totalPairs)
        {
            gameClear = true;
            Debug.Log("GAME CLEAR!");
        }

    }
}

コメントを残す