본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 7일차

by LemongO 2024. 1. 2.

오늘은 난이도가 좀 있네;;;

 

 

C# 문법 종합반 3주차 과제로 스네이크 콘솔 게임 만들기를 했다.

 

로직에서 좀 많이 헤매게 됐는데 전체 코드가 기니까 어려웠던 부분과 새로 알게된 부분을 작성해야겠다.

 

 

먼저 새로 알게된 것은 아래와 같다.

Console.KeyAvailable

해당 코드는 키 입력이 있을 때에만 true를 반환하는 코드이다.

 

if (Console.KeyAvailable)
{
    ConsoleKeyInfo key = Console.ReadKey(true);
    ConsoleKey pressedKey = key.Key;
    switch (pressedKey)
    {
        case ConsoleKey.LeftArrow:
            snake.dir = Direction.LEFT;
            break;
        case ConsoleKey.RightArrow:
            snake.dir = Direction.RIGHT;
            break;
        case ConsoleKey.UpArrow:
            snake.dir = Direction.UP;
            break;
        case ConsoleKey.DownArrow:
            snake.dir = Direction.DOWN;
            break;
    }
}

while(true) 문 내부에 위 코드를 넣어주게되면
방향키 입력이 있다면 switch 문으로 들어가 해당되는 case 에 따라 코드가 실행된다.

만약 아무키도 입력하지 않았다면 if문은 생략하게 되고 나머지 코드가 실행된다.

 

해당 기능을 쓰면 이번 과제의 경우 키 입력없이 Snake가 저장된 방향으로 매 루프마다 한 칸 씩 이동하게된다.

 

어려웠던 부분은 

Snake를 한 칸 씩 이동할 때 어떤식으로 이동 시키는지에 대해 고민을 했다.

처음엔 머리를 두고 몸 한 칸 마다 Snake 클래스를 생성 해 자신의 앞 칸의 몸을(또는 머리를) 부모로 지정해

머리가 한 칸 이동하면 모든 몸이 차례로 자신의 부모 Snake 위치로 이동하게 하는 방법을 쓸까 했다.(LinkedList 느낌으로)

 

하지만 코드가 너무 복잡해질 것 같아 이 방법은 기각하고 좀 더 쉬운 방법을 생각해봤다.

 

※ List를 사용해 머리와 꼬리를 인지한다.

1. 꼬리를 삭제 시킨다.

2. 새로운 머리를 다음 방향 1칸 앞에 위치시킨다.

3. 꼬리와 머리 그린부분을 제거 및 추가 시킨다.

 

처음 Snake가 만들어질 때

마지막에 추가된 부분을 HEAD

index 0 자리에 있는 부분을 TAIL 로 삼는다.

 

index 0 을 HEAD로 할까 생각 해보았지만 새로 추가되는 부분이 HEAD 이기에 간편하게 마지막을 HEAD로 하기로 했다.

 

먼저 좌표정보를 가지고있는 Point 클래스이다.

public class Point
{
    public int x { get; set; }
    public int y { get; set; }
    public char sym { get; set; }

    // Point 클래스 생성자
    public Point(int _x, int _y, char _sym)
    {
        x = _x;
        y = _y;
        sym = _sym;
    }

    // 점을 그리는 메서드
    public void Draw()
    {
        Console.SetCursorPosition(x, y);
        Console.Write(sym);
    }

    // 점을 지우는 메서드
    public void Clear()
    {
        sym = ' ';
        Draw();
    }
}

Point 클래스는 Snake의 각 몸통에서 가지고 있을 좌표정보를 가지고 있으며

Snake 클래스의 List에 저장된다.

 

public class Snake
{    
    public Direction dir; // {LEFT, RIGHT, UP, DOWN}
    public List<Point> bodies = new List<Point>();

    // Direction 에 따라 움직일 좌표 dirX / dirY. X좌표는 1일 때 미관상 별로라 2로 했다.
    int[] dirX = [-2, 2, 0, 0];
    int[] dirY = [0, 0, -1, 1];

    public void Move()
    {
        // 움직임 로직 : 꼬리를 자르고 다음 진행 좌표에 새로운 머리가 온다.
        // tail은 Point List의 첫 번째로 할당한다
        Point tail = bodies[0];
        // List에 있던 tail은 삭제시켜준다
        bodies.Remove(tail);
        // head는 NextPos로 진행방향 다음칸을 할당한다
        Point head = NextPos();
        // 구해온 head Point를 List에 추가 시킨다.
        bodies.Add(head);
        
        // tail을 콘솔상에서 지워준다.
        tail.Clear();
        // tail을 콘솔상에서 그려준다.
        head.Draw();
    }

    public Point NextPos()
    {
        // 다음 HEAD 의 좌표를 구해준다.
        int nextPosX = bodies[bodies.Count - 1].x + dirX[(int)dir];
        int nextPosY = bodies[bodies.Count - 1].y + dirY[(int)dir];
        
        // 새로운 Point에 다음 x, y 좌표와 그려줄 심볼을 넣어 다음 HEAD에 할당한다.
        Point head = new Point(nextPosX, nextPosY, '*');

        return head;
    }
}

Snake 클래스에 다음 방향으로 움직이는 Move 메서드가 실행될 때,

꼬리는 사라지고 새로운 머리가 다음 위치에 들어온다.

 

이런 느낌으로 된다