오늘은 난이도가 좀 있네;;;
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 메서드가 실행될 때,
꼬리는 사라지고 새로운 머리가 다음 위치에 들어온다.
'스파르타 내배캠' 카테고리의 다른 글
스파르타 내배캠 Unity 3기 9일차 (1) | 2024.01.04 |
---|---|
스파르타 내배캠 Unity 3기 8일차 (1) | 2024.01.03 |
스파르타 내배캠 Unity 3기 6일차 (1) | 2023.12.29 |
스파르타 내배캠 Unity 3기 5일차 (0) | 2023.12.28 |
스파르타 내배캠 Unity 3기 4일차 (1) | 2023.12.27 |