
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!");
}
}
}