❤❤新課程需要你的寶貴意見❤❤

2017年8月6日 星期日

Unity 2017 小遊戲 教學 記憶翻牌 水果配對

步驟:
1.可點擊的一張牌
2.可配對的2張牌
3.不能重複翻牌
4.最多只能同時翻兩張牌
5.自動產生1張固定的牌
6.自動亂數產生1張牌
7.亂數產生1張牌 並且放到指定的位置
8.亂數產生16張牌 並且放到指定的位置
9.全部配對成功的話要自動重新洗牌

素材下載
https://drive.google.com/file/d/0B9pF8Hbq-lgVUkphT1BZYXByRWM/view?usp=sharing

完整可執行遊戲的專案下載(約台幣30元)
https://gumroad.com/l/gmNMQ


Card.cs

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

public class Card : MonoBehaviour {
    public CardState cardState;
    public CardPattern cardPattern;
    public GameManager gameManager;

    void Start () {
        cardState = CardState.未翻牌;
        gameManager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManager>();
    }

    private void OnMouseUp()
    {
        if (cardState.Equals(CardState.已翻牌))
        {
            return;
        }

        if (gameManager.ReadyToCompareCards)
        {
            return;
        }

        OpenCard();
        gameManager.AddCardInCardComparison(this);
        gameManager.CompareCardsInList();
    }
    void OpenCard()
    {
        transform.eulerAngles = new Vector3(0, 180, 0);
        cardState = CardState.已翻牌;
    }
}

public enum CardState
{
未翻牌, 已翻牌, 配對成功
}

public enum CardPattern
{
    無,奇異果,柳橙,橘子,水蜜桃,芭樂,葡萄,蘋果,西瓜
}
GameManager.cs

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

public class GameManager : MonoBehaviour
{
    [Header("比對卡牌的清單")]
    public List<Card> cardComparison;

    [Header("卡牌種類清單")]
    public List<CardPattern> cardsToBePutIn;

    public Transform[] positions;

    [Header("已配對的卡牌數量")]
    public int matchedCardsCount = 0;

    void Start()
    {
        //SetupCardsToBePutIn();
        //AddNewCard(CardPattern.水蜜桃);
        GenerateRandomCards();
    }

    void SetupCardsToBePutIn()//Enum轉List
    {
        Array array = Enum.GetValues(typeof(CardPattern));
        foreach (var item in array)
        {
            cardsToBePutIn.Add((CardPattern)item);
        }
        cardsToBePutIn.RemoveAt(0);//刪掉Cardpattern.無
    }

    void GenerateRandomCards()//發牌
    {
        int positionIndex = 0;

        for (int i = 0; i < 2; i++)
        {
            SetupCardsToBePutIn();//準備卡牌
            int maxRandomNumber = cardsToBePutIn.Count;//最大亂數不超過8
            for (int j = 0; j < maxRandomNumber; maxRandomNumber--)
            {
                int randomNumber = UnityEngine.Random.Range(0, maxRandomNumber);//0到8之間產生亂數 最小是0 最大是7
                AddNewCard(cardsToBePutIn[randomNumber], positionIndex);//抽牌
                cardsToBePutIn.RemoveAt(randomNumber);
                positionIndex++;
            }
        }
    }

    void AddNewCard(CardPattern cardPattern, int positionIndex)
    {
        GameObject card = Instantiate(Resources.Load<GameObject>("Prefabs/牌"));
        card.GetComponent<Card>().cardPattern = cardPattern;
        card.name = "牌_" + cardPattern.ToString();
        card.transform.position = positions[positionIndex].position;

        GameObject graphic = Instantiate(Resources.Load<GameObject>("Prefabs/圖"));
        graphic.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("Graphics/" + cardPattern.ToString());
        graphic.transform.SetParent(card.transform);//變成牌的子物件
        graphic.transform.localPosition = new Vector3(0, 0, 0.1f);//設定座標
        graphic.transform.eulerAngles = new Vector3(0, 180, 0);//順著Y軸轉180度 翻牌時不會左右顛倒
    }

    public void AddCardInCardComparison(Card card)
    {
        cardComparison.Add(card);
    }

    public bool ReadyToCompareCards
    {
        get
        {
            if (cardComparison.Count == 2)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public void CompareCardsInList()
    {
        if (ReadyToCompareCards)
        {
            //Debug.Log("可以比對卡牌了");
            if (cardComparison[0].cardPattern == cardComparison[1].cardPattern)
            {
                Debug.Log("兩張牌一樣");
                foreach (var card in cardComparison)
                {
                    card.cardState = CardState.配對成功;
                }

                ClearCardComparison();
                matchedCardsCount = matchedCardsCount + 2;
                if (matchedCardsCount >= positions.Length)
                {
                    StartCoroutine(ReloadScene());
                }
            }
            else
            {
                Debug.Log("兩張牌不一樣");
                StartCoroutine(MissMatchCards());
                //TurnBackCards();
                //ClearCardComparison();
            }
        }
    }

    void ClearCardComparison()
    {
        cardComparison.Clear();
    }

    void TurnBackCards()
    {
        foreach (var card in cardComparison)
        {
            card.gameObject.transform.eulerAngles = Vector3.zero;
            //card.gameObject.transform.eulerAngles = new Vector3(0, 0, 0);
            card.cardState = CardState.未翻牌;
        }
    }

    IEnumerator MissMatchCards()
    {
        yield return new WaitForSeconds(1.5f);
        TurnBackCards();
        ClearCardComparison();
    }

    IEnumerator ReloadScene()
    {
        yield return new WaitForSeconds(3);
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}

2 則留言:

  1. 老師!謝謝您的分享,真的很有收穫,而且講得很清楚!!
    想詢問老師,如果想要配對的不是同一張圖片,該怎麼去更改程式呢?
    像是我想要水蜜桃配對芭樂,這樣的概念
    謝謝

    回覆刪除
    回覆
    1. 不好意思這麼晚回你,最近的留言都跳不出通知。
      大致上原理是需要另外開一個配對的表格清單,比方Dictionary
      然後把選擇的兩個牌丟到裡面去一一比對,一樣的話就代表配對成功

      刪除

留言給作者加油打氣