워리어 콤보 모작 개발일지

워리어콤보 모작 개발일지 - 블럭 되돌아갈 때 선그리기, 되돌아갈 때 블럭 2개 이하면 삭제 안되게하기, 되돌아갈 때 prev 위치 정해줘서 블럭 3개 이상이면 삭제시키기

다모아 2023. 9. 20. 12:20

할 일

할 일.txt
0.01MB


목표 : "일치함"상태일 때 stack.Pop() 해주기, 빼준 후에 데이터로 선 그리기

 

Prev, Curr, Next 를 이용해서 해준 결과

1. 오류 : Prev가 이전 꺼 "한개의 위치"만 찾아주고 그 다음부터는 다시 그 마우스 지점의 "이전" 위치가 동기화 되고있다.

 

1. 오류 해결 결과

 

1. 오류 해결 방법 : "일치함" 상태일 때 Pop() 해준 스택을 배열로 바꿔준 후 Prev 값에 그 배열에서 나온 필요한 Prev

위치를 할당해주었다.

this.prevLocation 에다가 info[idx] 값을 할당해줘서 위치를 할당해주었다.


2. 오류 : 위에 영상을 보면 마지막에 오류가 나는데 그 오류 내용이

처음 지점으로 돌아갔을 때 스택을 배열로 바꿔준 후 그 값을 prev 값에다가 넣어주고 있는데

마지막으로 가면 그 값이 없어져서 IndexOutOfRange 오류가 나타난다.

 

idx의 1번 즉, info[1] 정보가 없는 상태

idx의 1번 즉, info[1] 정보가 있는 상태

 

2. 오류 해결 결과

2. 오류 해결 방법

아직 블럭 삭제는 안됐지만 console 창에 보면 처음 시작했던 자리로 다시 돌아오면 그 자리의 위치값을 prev에 넣어줬다.

배열로 info의 마지막에서 -1 번째의 위치값과 비교해서 같으면 prev한테 그 위치 값을 주었다.


3-1. 오류 : 블럭 제거 오류

 

3-1. 오류 해결 결과

 

3-1 해결 방법

[2. 오류]에서 되돌아갈 때 블럭이 이상한게 삭제가 되는데

이 부분에서 DeleteBlock의 위치를 curr 위치로 해줬다 . [ next 는 this.location이다]

그리고 블럭이 prev와 next가 같을 때 curr 위치에다가 next 위치를 넣어줬다.

 

3-2. 오류 : 되돌아갈 때 2번째 이하에서는 삭제 안되게 만들기

 

3-2. 오류 해결 결과

3-2. 오류 해결 방법

listCount라는 리스트로 블럭에서 블럭으로 넘어갈 때 Count.Add 해주고 있는데

되돌아갈 때는 Remove를 해주고있다.

 

Remove를 2번씩 해주는 이유는 

스택의 마지막 타입과 지금 내 마우스가 클릭한 gameObject의 타입이 같을 때 일단 listCount.Add로 추가해줘서

Remove를 2번씩 해주고있다.

 

2번째 블럭 이상 , 미만인 경우 이건

되돌아갈 때 내 마우스 위치가 되돌아갈 때 2번째 블럭 이상에 마우스가 있냐

아니면 2번째 블럭 미만에 마우스가 있냐 이 뜻이다.

 

4. 선 그리기

Play 메소드를 오버로딩 해줘서

TestSaveLocation[] 배열 target 값이 들어오면 아래에 있는 Play를 실행시키게 하였다.

TestSaveLocation을 받는 Play 메소드는 마우스가 뒤로가지않고 쭉 가는 경우 실행시키고

뒤로가는 경우 아래에 있는 Play 메소드를 실행시키라고 하였다.

 

아래에 있는 Play 메소드는 target 값을 받아오는데 target 값이 stack을 배열로 한 값을 넣어준 것이라서

맨 뒤의 target 값이 마우스로 드래그한 첫번째 블럭 위치 정보라서 그 정보를 0번째 [ idx = 0 으로 초기화 해놓은 전역변수]

부터 차례대로 넣어줘서 내가 마우스를 뒤로갈 때 0번째부터 그림을 그리도록 만들었다.


스크립트

TestMain

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.GraphicsBuffer;

public class TestMain : MonoBehaviour
{

    [SerializeField]
    private GameObject wallPrefab;
    [SerializeField]
    private GameObject blockPrefab;
    [SerializeField]
    private Transform boardTr;
    private TestBlock testBlock;
    private TestSaveLocation location;
    [SerializeField]
    private TestLine testLine;
    [SerializeField]
    private float raycastDistance = 1f;
    private int[,] str =
    {
        {0, 4, 4, 2, 4, 1, 0},
        {0, 4, 5, 4, 1, 2, 0},
        {0, 5, 5, 1, 3, 2, 0},
        {0, 1, 1, 2, 3, 2, 0},
        {0, 1, 3, 3, 5, 5, 0},
        {0, 5, 4, 3, 2, 2, 0},
        {0, 0, 0, 0, 0, 0, 0}
    };

    private List<TestSaveLocation> listBlock = new List<TestSaveLocation>();
    private Stack<TestSaveLocation> stackBlock = new Stack<TestSaveLocation>();
    private bool IsCount = false;
    private List<bool> listCount = new List<bool>();
    private TestSaveLocation prevLocation;
    private TestSaveLocation currLocation;
    // Start is called before the first frame update
    void Start()
    {
        int maxRow = 7;
        int maxCol = 7;
        this.testBlock = new TestBlock(maxRow, maxCol);

        for (int row = 0; row < maxRow; row++)
        {
            for (int col = 0; col < maxCol; col++)
            {
                switch (str[row, col])
                {
                    case 0:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.wallPrefab, this.boardTr, TestBlock.eBlockType.WALL);
                        break;
                    case 1:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.RED);
                        break;
                    case 2:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.BLUE);
                        break;
                    case 3:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.GREEN);
                        break;
                    case 4:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.YELLOW);
                        break;
                    case 5:
                        testBlock.Move(row, col);
                        testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.PURPLE);
                        break;
                }
            }
        }
    }

    private void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero, raycastDistance);
            //마우스 왼쪽 버튼을 누르고 있을 때
            //1. 인식 [좌표 출력]
            if (hit == false)
            {
                //gameObject bool로 Count하기
                if (IsCount == true)
                {
                    this.IsCount = false;
                }
                return;
            }
            else // hit == true
            {
                //블럭일 때
                if (hit.collider.CompareTag("Block"))
                {
                    //gameObject Count 세기
                    if (IsCount == false)
                    {
                        this.location = hit.collider.gameObject.GetComponent<TestSaveLocation>();
                        //좌표찍기
                        this.location.PutLocation();
                        //스텍이 0개인지 아닌지 [다른 블록 넘어가지 않기]
                        if (stackBlock.Count != 0)
                        {
                            //스택이 1개 이상일 때
                            if (stackBlock.Peek().type == this.location.type) // type이 같을 때
                            {
                                //블록 저장, 선긋기, 스택저장, Count 저장
                                this.listCount.Add(this.IsCount); // 2
                                if (prevLocation?.type == location.type &&
                                prevLocation?.row == location.row &&
                                prevLocation?.col == location.col)
                                {
                                    Debug.Log("일치함");
                                    this.stackBlock.Pop();
                                    TestSaveLocation[] info = stackBlock.ToArray();
                                    for(int i = 0; i < info.Length; i++)
                                    {
                                        Debug.LogFormat("{0} : {1},{2} / {3}번", info[i].type, info[i].row, info[i].col, i);
                                    }
                                    this.testLine.Play(info);
                                    this.DeleteBlock(this.currLocation);
                                    //됐다.. prev 위치 조정
                                    if(this.location == info[info.Length - 1])
                                    {
                                        //2번째 블럭 미만인 경우
                                        this.prevLocation = info[info.Length - 1];
                                        this.listCount.Remove(this.IsCount);
                                        this.listCount.Remove(this.IsCount);
                                    }
                                    else
                                    {
                                        //2번째 블럭 이상인 경우
                                        this.prevLocation = info[1];
                                        this.listCount.Remove(this.IsCount);
                                        this.listCount.Remove(this.IsCount);
                                    }
                                    Debug.LogFormat("prev : {0} : {1},{2}", prevLocation.type, prevLocation.row, prevLocation.col);
                                    Debug.LogFormat("curr : {0} : {1},{2}", location.type, location.row, location.col);
                                    this.currLocation = this.location;
                                    Debug.Log(this.listCount.Count);
                                }
                                else // type, row, col 값 중에 하나라도 다른 경우
                                {
                                    this.testLine.Play(this.location);
                                    this.SaveBlock(this.location);
                                    this.prevLocation = this.currLocation;
                                    this.currLocation = this.location;
                                    this.stackBlock.Push(this.location); // 3, 2, 1 // 빠질 때 3부터
                                }
                            }
                        }
                        else
                        {
                            //0개라면, 블록 저장, 선긋기, 스택저장, Count 저장
                            Debug.Log("아직 스택이 없습니다.");
                            this.SaveBlock(this.location);
                            this.testLine.Play(this.location);
                            this.stackBlock.Push(this.location);
                            //stack이 1개가 되는 시점
                            this.currLocation = this.location;
                            this.listCount.Add(this.IsCount); // 1
                        }
                        this.IsCount = true;
                    }
                }
            }
        }
        else if (Input.GetMouseButtonUp(0)) // 마우스버튼을 뗐을 때
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);
            if (hit == false)
            {
                return;
            }
            else
            {
                //listCount가 2개라면 Destroy 안하고 다시 listCount 0으로 초기화시키기
                if (this.listCount.Count >= 3)
                {
                    //3개 이상이라면
                    this.DestroyBlock();
                    this.testLine.Stop();
                    this.listCount.Clear();
                    this.stackBlock.Clear();
                    IsCount = false;
                }
                else if (this.listCount.Count <= 2)
                {
                    //2개 이하라면
                    this.testLine.Stop();
                    this.listCount.Clear();
                    this.listBlock.Clear();
                    this.stackBlock.Clear();
                    Debug.Log(listCount.Count);
                    IsCount = false;
                }
            }
        }
    }

    private void DeleteBlock(TestSaveLocation prevLocation)
    {
        this.listBlock.Remove(prevLocation);
        Debug.Log(this.listBlock.Count);
    }

    //블럭 저장하는거
    public void SaveBlock(TestSaveLocation blockGo)
    {
        this.listBlock.Add(blockGo);
        Debug.Log(this.listBlock.Count);
    }
    public void DestroyBlock()
    {
        for (int i = 0; i < listBlock.Count; i++)
        {
            //만약 100개를 찍었다. Destroy를 했다 -> 0번 부터 100개까지 Destroy 시킨다.
            Destroy(this.listBlock[i].gameObject);
        }

        this.listBlock.Clear();
    }
}

 

TestLine

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

public class TestLine : MonoBehaviour
{
    private LineRenderer lineRenderer;

    private int idx = 0;
    private void Awake()
    {
        this.lineRenderer = GetComponent<LineRenderer>();

        this.lineRenderer.enabled = false;
    }

    public void Play(TestSaveLocation target)
    {
        this.lineRenderer.enabled = true;

        this.lineRenderer.positionCount = idx + 1; // 1

        this.lineRenderer.SetPosition(idx, target.transform.position); // 0번 , target 생성
        idx++; // idx = 1; 
    }

    public void Play(TestSaveLocation[] target) // 마우스로 찍은 gameObject 정보들 넘어옴
    {
        this.Init();
        int index = target.Length - 1;

        this.lineRenderer.positionCount = index + 1; // 3개가 찍혀있다면 2개

        for(int i = 0; i < target.Length; i++)
        {
            Debug.LogFormat("<color=purple>target[index] : {0} / {1},{2} / {3}번</color>", target[index].type, target[index].row, target[index].col, i);
            this.lineRenderer.SetPosition(idx, target[index].transform.position); // 0번 , target 생성
            index--;
            idx++;
        }
    }

    public void Stop()
    {
        this.lineRenderer.enabled = false;

        this.Init();
    }

    public void Init()
    {
        //Play의 target.position과 idx를 초기화해줘야할듯
        
        for(int i = 0; i < idx; i++)
        {
            this.lineRenderer.SetPosition(i, Vector3.zero);
        }
        idx = 0;
        //this.stackBlock.Clear();
    }
}