반응형

카드를 Touch 및 클릭하여 카드를 뒤집고 카드를 리소스의 순번대로 나오는 것을 랜덤으로 섞는 프로그램을 만들어 보겠습니다

먼저 CardCtrl 스크립트를 열고 수정합니다

 

 

 

 

CardCtrl 스크립트 수정

Update()와 CheckCard() 함수 부분을 수정 및 추가합니다

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

public class CardCtrl : MonoBehaviour
{
    //이미지 번호
    int imgNum = 1;

    //카드 뒷면 이미지 번호
    int backNum = 1;

    // 오픈된 카드의 판별여부 
    bool isOpen = false;

    Animator anim;


    // Start is called before the first frame update
    void Start()
    {
        anim = GetComponent<Animator>();
    }

    void Update()
    {
        //왼쪽 마우스버튼 클릭 모바일에선 터치 
        if (Input.GetButtonDown("Fire1") )
        {
            CheckCard();
        }
    }

    //카드체크
    void CheckCard()
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        //터치한 카드 식별
        if (Physics.Raycast(ray, out hit, Mathf.Infinity))
        {
            string tag = hit.transform.tag;
            if (tag.Substring(0, 4) == "card")
            {
                //터치한 카드의 OpenCard()함수 실행
                hit.transform.SendMessage("OpenCard", SendMessageOptions.DontRequireReceiver);
            }
        }
    }
    void OpenCard()
    {
        if (isOpen) return;
        isOpen = true;

        // 카드 번호 Substring() 문자열의 일부분을 추출하는 함수 , 카드 번호(tag)는 card0~card32 있으므로 문자4번째부터(card~) 끝까지 추출한다
        int cardNum = int.Parse(transform.tag.Substring(4));

        //이미지 번호 카드 두장에 하나씩 같은 이미지를 할당하므로 이미지 번호는 (카드번호 +1)/2 로 구한다 정수 /정수 = 정수 이므로 소수 이하는 자동으로 잘림
        imgNum = (cardNum + 1) / 2;
        //카드 애니메이션 실행
        anim.Play("aniOpen");

       //GameManager.cardNum = cardNum;
        //GameManager.state = GameManager.STATE.HIT;

    }
    void CloseCard()
    {
        anim.Play("aniClose");
        isOpen = false;
    }
    //카드 앞면을 이미지을 가지고 온다
    void ShowImage()
    {
        transform.GetComponent<Renderer>().material.mainTexture = Resources.Load("card" + imgNum) as Texture2D;
    }


    //카드 뒷면 이미지을 가지고 온다
    void HideImage()
    {
        transform.GetComponent<Renderer>().material.mainTexture = Resources.Load("back" + backNum) as Texture2D;
    }
}

 

 

 

 

아래 동영상과 카드를 터치하였을 때 카드가 열립니다 그런데 카드가 섞이지 않고 순번대로 열립니다 

 

 

 

 

GameManager 스크립트 수정합니다

 

 

 

GameManager 스크립트 수정

카드를 섞는 함수를 작성

ShuffleCard() 함수 작성 및 카드 태그 인식 부분 수정

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

public class GameManager : MonoBehaviour
{
    //클릭한 카드 번호
    static public int cardNum;

    //직전의 카드 번호
    int lastNum = 0;

    //스테이지의 전체 카드수
    int cardCnt;

    //카드 클릭 횟수
    int hitCnt = 0;

    //스테이지 번호
    static public int stageNum = 1;

    //스테이지 수
    int stageCnt = 6;

    //카드 배열 카드 섞기용
    int[] arCards = new int[50];

    //게임 시작 시간
    float startTime;

    // 스테이지 경과 시간
    float stageTime;


    // Start is called before the first frame update
    void Start()
    {
        //시간초기화
        startTime = stageTime = Time.time;
        //스테이지 만들기
         StartCoroutine(MakeStage());
    }

    void Update()
    {

    }

    IEnumerator MakeStage()
    {
        //시작카드의 x좌표
        float sx = 0;

        //시작카드의 z좌표
        float sz = 0;

        
        SetCardPos(out sx, out sz);

        //카드섞기
        ShuffleCard();


        //시작카드의 번호
        int n = 1;

        //카드배열 읽기 배열의 1행을 읽고 변수 t에 할당한다
        string[] str = StageSet.stage[stageNum - 1];

        //배열의 행의 수만큼 반복
        foreach (string t in str)
        {
            // 각행의 문자열을 단일 문자 배열로 변환(문자열 좌우의 공백 제거) , 변수t의 자우 공백을 제거(Trim)하고 단일 문자배열로 변환
            char[] ch = t.Trim().ToCharArray();

            //카드의 x축 좌표
            float x = sx;

            //1행의 문자열 길이만큼 반복
            //배열의 ch의 한문자를 읽고 변수 c에 할당한다
            foreach (char c in ch)
            {
                switch (c)
                {

                    //맵의 내용이 * 이면 그위치에 카드 만들어서 배치
                    case '*':
                        //카드 만들기
                        GameObject card = Instantiate(Resources.Load("Prefab/Card")) as GameObject;

                        //카드 좌표설정
                        card.transform.position = new Vector3(x, 0, sz);

                        //태그 달기
                        //card.tag = "card" + n++;

                        
                        //섞인카드
                        card.tag = "card" + arCards[n++];
                        x++;
                        break;

                        //빈칸 처리
                    case '.':
                        x++;
                        break;


                        //반 칸 공백처리
                    case '>':
                        x += 0.5f;
                        break;


                        //반 줄 행간 처리
                    case '^':
                        sz += 0.5f;
                        break;


                }

                //카드를 표시한 후에는 지연 시간을 두어 카드가 배치되는 과정이 보이도록함
                if (c == '*')
                {
                    yield return new WaitForSeconds(0.03f);

                }
            }

            //한줄 아래로 이동
            sz--;
        }

    }

    //카드의 시작 위치 계산
    void SetCardPos(out float sx, out float sz)
    {
        //가로 카드수 반 칸 공백 포함
        float x = 0;

        //세로 행수 반줄 행간 포함
        float z = 0;

        //가로 카드 최대수
        float maxX = 0;

        //스테이지 전체 카드수
        cardCnt = 0;

        //카드 배열 조사 맵 배열 을 읽음
        string[] str = StageSet.stage[stageNum - 1];

        //행의 수만큼 반복
        for (int i = 0; i < str.Length; i++)
        {
            //1행읽기
            string t = str[i].Trim();

            //각행의 카드수
            x = 0;

            //각행의 글자 수만큼 반복
            for (int j = 0; j < t.Length; j++)
            {
                //문자열(string)은 단일 문자(char)의 배열로 취급할수 있음
                switch (t[j])
                {
                    case '.':
                    case '*':

                        //카드배치에 필요한 공간
                        x++;
                        if (t[j] == '*')
                        {
                            //전체 카드수
                            cardCnt++;
                        }
                        break;
                    case '>':
                        x += 0.5f;
                        break;
                    case '^':
                        z -= 0.5f;
                        break;

                }
            }

            //각 행의 최대 카드수 계산
            if (x > maxX)
            {
                maxX = x;
            }
            //전체 행의 수
            z++;
        }
        //카드 가로 시작 위치
        sx = -maxX / 2;
        sz = (z - 1) / 2;

        //  StartCoroutine(CardOpen(cardCnt));
    }

    void ShuffleCard()
    {
        for (int i = 1; i <= cardCnt; i++)
        {
            arCards[i] = i;
        }
        //return;

        //카드섞기 15회정도 반복
        for (int i = 1; i <= 15; i++)
        {
            //임의의 난수를 두개 만든다
            int n1 = Random.Range(1, cardCnt + 1);
            int n2 = Random.Range(1, cardCnt + 1);

            //교환
            int t = arCards[n1];//배열의 값을 바꾼다
            arCards[n1] = arCards[n2];
            arCards[n2] = t;

            //StartCoroutine(CardOpen(arCards[n1]));
        }
    }
}

 

 

 

 

아래 동영상과 같이 카드가 일렬 배열대로 안 나오고 섞어서 나옵니다

 

반응형

+ Recent posts