4주차 FindRtans 구현 및 추가 로직 구현
void Update()
{
if (gameObject.activeSelf && !Waiting)
{
Waiting = true;
Invoke("SetActiveFalse", 1f);
}
}
카드 매치를 성공하면 퍼블릭 변수값으로 게임오브젝트를 SetActive(true) 해주고 해당 스크립트엔 게임오브젝트가 활성화 될시 1초뒤에 비활성화 상태로 변경한다.
이때 텍스트가 카드를 가렸었는데 텍스트 때문에 카드 터치가 잠깐 안된다. 찾아보니 텍스트는 자동으로 Ratcast로 bloking설정해주지 않으면 터치체크가 되는것 같더라.
Canvas의 컴포넌트에서 Canvas Group을 추가하고, Bloks Raycasts 를 해제해주면 된다.
물론 다른 캔버스는 버튼이 있는 오브젝트가 많으니 성공,실패 텍스트를 위한 캔버스를 또 따로 생성해서 컴포넌트를 수정하자. (난 이것 때문에 다시하기 버튼이 왜 안되는지 찾아다녔다)
이번에는 플레이어가 레벨마다 난이도에서 차이점을 느낄 수
있는 스테이지를 만들어보았다.
우선 레벨을 게임 전체에서 관리해야하는데 방법을 찾아보니 gameManager를 씬 전체에 두는 방법도 있던데 나는 익숙하게 강의자료에 있던 PlayerPrefs() 를 사용했다.
우선 플레이어가 현재 하고있는 Level 과 플레이어가 이때까지 클리어했었던 ClearLevel를 PlayerPrefs으로 저장했다.
PlayerPrefs.SetInt("level", 1); //레벨에 따른 난이도 설정
PlayerPrefs.SetInt("ClearLevel", 0); //현재까지 클리어한 레벨
난이도에 대한 대략적인 로직은 아래와 같다
1단계
time = 30
르탄 4*2 = 8
2단계
time = 40
르탄 6*2 = 10
3단계
time 50
르탄 8*2 = 16
4단계
time 75
르탄 12*2 = 24
위의 로직을 swich문으로 현재 플레이어가 선택한 level에 따라 카드 배치나 난이도를 변경했다.
void StageLv()
{
int LV = PlayerPrefs.GetInt("Level");
//르탄 섞기
switch (LV)
{
case 1:
time = 30;
rtans = new int[] { 0, 0, 1, 1, 2, 2, 3, 3 };
rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();
for (int i = 0; i < 8; i++)
{
GameObject newCard = Instantiate(card);
newCard.transform.parent = GameObject.Find("Cards").transform;
float x = (i / 2) * 1.4f - 2.1f;
float y = (i % 2) * 1.4f - 3.0f;
if (i < 4)
{
newCard.transform.position = new Vector3(x, y, 0);
}
else
{
//4개 이상부턴 y값 확 높이기
y += 2 * 1.4f;
newCard.transform.position = new Vector3(x, y, 0);
}
string rtanName = "rtan" + rtans[i].ToString();
newCard.transform.Find("back").transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(rtanName);
}
break;
case 2:
time = 40;
rtans = new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4};
rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();
for (int i = 0; i < 10; i++)
{
GameObject newCard = Instantiate(card);
newCard.transform.parent = GameObject.Find("Cards").transform;
if (i < 5)
{
float x = (i / 4) * 1.4f - 1.4f;
float y = (i % 4) * 1.4f - 3.0f;
newCard.transform.position = new Vector3(x, y, 0);
}
else
{
//중간을 비우기 위해 2개의 배치 부분 없애기
float x = ((i + 2) / 4) * 1.4f - 1.4f;
float y = ((i + 2) % 4) * 1.4f - 3.0f;
newCard.transform.position = new Vector3(x, y, 0);
}
string rtanName = "rtan" + rtans[rtans[i]].ToString();
newCard.transform.Find("back").transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(rtanName);
}
break;
case 3:
time = 50;
rtans = new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };
rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();
for (int i = 0; i < 16; i++)
{
//기본 배치
GameObject newCard = Instantiate(card);
newCard.transform.parent = GameObject.Find("Cards").transform;
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[rtans[i]].ToString();
newCard.transform.Find("back").transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(rtanName);
}
break;
case 4:
time = 80;
rtans = new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0, 0, 2, 2, 4, 4, 5, 5 };
rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();
for (int i = 0; i < 24; i++)
{
//기본 배치
GameObject newCard = Instantiate(card);
newCard.transform.parent = GameObject.Find("Cards").transform;
//카드 크기부터 줄이자
newCard.transform.localScale = new Vector3(1, 1, 1);
float x = (i / 5) * 1.1f - 2.1f;
float y = (i % 5) * 1.1f - 3.0f;
newCard.transform.position = new Vector3(x, y, 0);
string rtanName = "rtan" + rtans[rtans[i]].ToString(); //배열 안의 숫자와 맞춰서 가져오기
newCard.transform.Find("back").transform.Find("front").GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>(rtanName);
}
break;
}
이번에는 챌린지의 예시대로 시간+클릭수를 종합해 점수값을 내었다.
시간 1.00 = 200
클릭 수 = -50
void Score(float time, int Mathed) //*
{
//소수 부분을 내림하고 계산하는 함수
int a = Mathf.FloorToInt(time) * 200;
int b = Mathed * -50;
N_ScoreInt = a + b;
}
public void isMatched()
{
...생략
Score(time,MathNum);
}
이번에도 역시 swich 문으로 LV에 따라 각 점수를 기록한다.
void BestScore() //* 베스트 스코어 갱신
{
int LV = PlayerPrefs.GetInt("Level");
switch(LV)
{
case 1:
B_ScoreInt = PlayerPrefs.GetInt("BestScore1");
if (B_ScoreInt < N_ScoreInt)
{
PlayerPrefs.SetInt("BestScore1", N_ScoreInt);
B_ScoreInt = N_ScoreInt;
}
N_Score.text = N_ScoreInt.ToString();
B_Score.text = B_ScoreInt.ToString();
Bestleave.text = B_ScoreInt.ToString();
break;
case 2:
B_ScoreInt = PlayerPrefs.GetInt("BestScore2");
if (B_ScoreInt < N_ScoreInt)
{
PlayerPrefs.SetInt("BestScore2", N_ScoreInt);
B_ScoreInt = N_ScoreInt;
}
N_Score.text = N_ScoreInt.ToString();
B_Score.text = B_ScoreInt.ToString();
Bestleave.text = B_ScoreInt.ToString();
break;
case 3:
B_ScoreInt = PlayerPrefs.GetInt("BestScore3");
if (B_ScoreInt < N_ScoreInt)
{
PlayerPrefs.SetInt("BestScore3", N_ScoreInt);
B_ScoreInt = N_ScoreInt;
}
N_Score.text = N_ScoreInt.ToString();
B_Score.text = B_ScoreInt.ToString();
Bestleave.text = B_ScoreInt.ToString();
break;
case 4:
B_ScoreInt = PlayerPrefs.GetInt("BestScore4");
if (B_ScoreInt < N_ScoreInt)
{
PlayerPrefs.SetInt("BestScore4", N_ScoreInt);
B_ScoreInt = N_ScoreInt;
}
N_Score.text = N_ScoreInt.ToString();
B_Score.text = B_ScoreInt.ToString();
Bestleave.text = B_ScoreInt.ToString();
break;
}
}
코드 줄은 길지만 로직은 단순하다. 현재 플레이어가 플레이하는 LV을 PlayerPrefs 변수값으로 받아온 후 LV에 따라 다르게 점수를 처리한다. 이때 text오브젝트.text를 초기화 해주어야 하기 때문에 겹치는 로직이있다.
참고로 swich문에서 겹치는 코드부분은 아래와 같다
N_Score.text = N_ScoreInt.ToString();
B_Score.text = B_ScoreInt.ToString();
Bestleave.text = B_ScoreInt.ToString();
그래서 위의 코드 부분은 swich문을 나와 BestScore() 함수 마지막 줄에 작성했으나 작동이 되지 않았다.
swich문에서 break는 swich문에서 빠져나오는 기능인줄 알았는데 아예 함수 밖으로 빠져나오는 것 같다. Debug.Log로 테스트를 했을때 아무래도 swich문 밖에서는 실행이 되지 않았다. 그래서 조금 더럽지만 case 마다 같은 로직이 써져있다.