오늘은 게임 부트 캠프의 사전 캠프 4주차에 진행한 프로젝트를 다시 한번 복습했다.
카드 두 장을 뒤집어 같은 카드를 찾는 카드 맞추기 게임.
- MainScene 생성 및 타이머 만들기
- 카드 만들기
👉 카드를 16개 만들어서 4 * 4로 정렬하기
👉 카드 애니메이션 만들기- 카드끼리 서로 비교해서 같으면 사라지고 다르면 다시 뒤집기
- 카드 다 뒤집으면 게임 종료
- 끝! 버튼 누르면 게임 재시작
transform.Find("front").SetActive(true); transform.Find("back").SetActive(false);
게임이 실행되자마자 카드가 생성되어야 하므로 Start()에 코드를 작성한다.
카드에 임의의 이미지 넣기???
사용할 이미지 수 만큼 반복되는 for문을 사용하자.
이미지들의 이름을 나타낼 배열을 만들어두자.
in[] rtans = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
만든 배열을 무작위로 섞기!!!
rtans 리스트를 랜덤하게 무작위로 선정해준다.
rtans = rtans.OrderBy(item => Random.Range.ToString();
Resource의 이미지 적용시키기
🤔 모든 짝을 찾았는 지 어떻게 확인?
✨ cards 밑에 card가 몇 개나 남았는 지 확인!!!
public static gameManager I; void Awake() { I = this; }
int[] rtans = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 }; // rtans 리스트를 랜덤하게 정렬하기 rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();
OrderBy를 통해 배열을 오름차순 혹은 내림차순으로 정렬할 수 있다.
public Animator anim; anim.SetBool("조건", true 혹은 false);
오늘은 게임 개발 부트캠프가 본격적으로 시작하는 날이었다. 설렘인지 긴장인지 모르겠지만 잠을 못 잤다. 때문에 TIL을 쓰면서 비몽사몽 해서 정말 힘들었다...
미니 프로젝트 팀원들을 만나 함께 얘기 해보고 팀 노션도 꾸며보았는데, 주도적이신 두 분이 계셔서 든든했다. 옆에서 뭔가를 말할 틈도 없이 일이 척척 진행되는 것을 보고 적극적인 소통이 정말 중요하다 느꼈다. 나도 더욱 적극적으로 참여할 수 있도록 해야겠다.
- 카드 매칭 횟수를 카운팅하기 위한 변수 counter가 필요할 것이다.
- counter를 증가시킬 타이밍? → 두 개의 카드를 뒤집고 서로 비교를 하기 위해 isMatched() 함수가 호출될 때 counter를 증가시키면 될 것이다.
- 결과창??? 결과창을 새로 만들어야 하는 걸까? 내일 팀원들과 회의할 때 물어봐야 함!!!
일단 완료!
public class gameManager : MonoBehaviour { public static gameManager I; public GameObject card; public GameObject firstCard; public GameObject secondCard; public GameObject endPanel; public Text timeTxt; public Text count; public float time = 60.0f; public int counter = 0; // gameManager 싱글톤 private void Awake() { I = this; } // Start is called before the first frame update void Start() { Time.timeScale= 1.0f; int[] rtans = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 }; // rtans 리스트를 랜덤하게 정렬하기 rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray(); for(int i = 0; i < 16; i++) { // card를 cards의 자식으로 넣기 GameObject newCard = Instantiate(card); newCard.transform.parent = GameObject.Find("cards").transform; // 카드 X, Y좌표 배치하기 float x = (i % 4) * 1.4f - 2.1f; float y = (i / 4) * 1.4f - 3.0f; newCard.transform.position = new Vector3(x, y, 0); // 카드 이미지 넣기 string rtanName = "rtan" + rtans[i].ToString(); newCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(rtanName); } } // Update is called once per frame void Update() { // 시간 흐르게 하기 time -= Time.deltaTime; // 30초 되면 게임 멈추기 if(time <= 0.0f) { time = 0.0f; // 시간 감소로 0보다 작아지는 것을 방지! ////////////////////////////////////////////////////////////////// // 결과창 띄우기 endPanel.gameObject.SetActive(true); count.text = counter.ToString(); Time.timeScale = 0.0f; } timeTxt.text = time.ToString("N2"); } public void isMatched() { counter++; // 시도 횟수 증가 // 첫 번째, 두 번째 카드의 이미지 이름을 가져와 비교하기 string firstCardImage = firstCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name; string secondCardImage = secondCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name; if (firstCardImage == secondCardImage) { // 두 카드의 이미지 이름이 같을 경우 destroy firstCard.GetComponent<card>().destroyCard(); secondCard.GetComponent<card>().destroyCard(); // 카드 다 맞추면 게임 멈추기 int cardsLeft = GameObject.Find("cards").transform.childCount; if(cardsLeft == 2) { // 결과창 띄우기 endPanel.gameObject.SetActive(true); count.text = counter.ToString(); Time.timeScale = 0.0f; } } else { // 카드 다시 뒤집기 firstCard.GetComponent<card>().closeCard(); secondCard.GetComponent<card>().closeCard(); // 실패할 때마다 시간 감소! time -= 3.0f; } // 다시 null로 초기화 시켜서 카드 두 장을 선택할 수 있도록 만들어 주기 firstCard = null; secondCard = null; } }
시간제한을 두는 것은 어렵지 않다. Game Mode 1, 2, 3을 두어 관리하면 될 것 같다.
난이도를 해금하는 방식? : 쉬운 난이도를 깨면 새로운 난이도가 열리도록 만들기?
👉 Scene을 여러 개 만들면 어떨까?
isMatched() 함수에서 else 부분의 카드 다시 뒤집기에서 변수 time을 줄이면 됨.
해내긴 했는데 내가 봐도 너무 별로인 코드... 알고리즘 및 클린 코드 공부를 필수적으로 해야겠다...
// card.cs void Update() { // gameManager.I.time은 실시간으로 줄어들고 있는 게임 내 시간이다. // 때문에 timeSpan에 저장했을 때보다 time이 5초만큼 더 작아지면 firstCard 다시 뒤집기 if(timeSpan - gameManager.I.time >= 5.0f) { timeSpan = 0.0f; gameManager.I.firstCard.GetComponent<card>().closeCard(); gameManager.I.firstCard = null; } } // 카드 뒤집기 public void openCard() { // 카드 뒤집는 애니메이션 활성화 anim.SetBool("isOpen", true); // 카드 뒤집기 transform.Find("front").gameObject.SetActive(true); transform.Find("back").gameObject.SetActive(false); if(gameManager.I.firstCard == null) { // firstCard가 null이면 firstCard로 넣어버리기 gameManager.I.firstCard = gameObject; // firstCard가 뒤집힌 시간을 timeSpan에 저장하기 timeSpan = gameManager.I.time; } else { timeSpan = 0.0f; gameManager.I.secondCard= gameObject; gameManager.I.isMatched(); } }