스네이크 게임이 뭔지 알아보자
3-1 스네이크
콘솔 기반의 간단한 뱀 게임을 구현하는 것입니다. 기본적인 뱀 게임의 동작 방식은 아래와 같습니다:
- 뱀은 매 턴마다 자신의 앞으로 이동합니다.
- 사용자는 방향키를 이용하여 뱀의 이동 방향을 제어할 수 있습니다.
- 뱀은 맵에 무작위로 생성되는 음식을 먹을 수 있습니다. 뱀이 음식을 먹으면 점수가 올라가고, 뱀의 길이가 늘어납니다.
- 뱀이 벽이나 자신의 몸에 부딪히면 게임이 끝나고 'Game Over' 메시지를 출력합니다.
요구사항:
- Snake 클래스를 만듭니다. 이 클래스는 뱀의 상태와 이동, 음식 먹기, 자신의 몸에 부딪혔는지 확인 등의 기능을 담당합니다.
- FoodCreator 클래스를 만듭니다. 이 클래스는 맵의 크기 내에서 무작위 위치에 음식을 생성하는 역할을 합니다.
- Main 함수에서 게임을 제어하는 코드를 작성합니다. 이 코드는 뱀의 이동, 음식 먹기, 게임 오버 조건 확인 등을 주기적으로 수행합니다.
- 필요에 따라 추가적인 함수나 클래스를 작성하여 게임을 완성합니다.
slither.io와 같은 게임이라는것을 이해했다
시작하기전에 미리 제공된 코드가 있는데, 이걸 사용하여 먼저 완성을 하는게 맞는걸까
처음부터 만들어보는 것이 맞는걸까
난 처음부터 만들어보고, 그다음에 주어진 것을 사용해보고 싶다
구현해야 할 요소를 생각해보면
1. 맵(콘솔창의 테두리에 ■ 표시면 충분할 것 같다. 그리고 창 크기 변화를 반영할 수 있으면 더 좋겠다)
2. 뱀의 머리
3. 뱀의 몸통
4. 이동로직
5. 음식을 먹는 함수
5. 길이가 늘어나는 함수
6. 충돌체크 (충돌하면 게임이 끝난다)
7. 여러 종류의 음식
8. 점수
이정도면 될 것 같다
우선 기본적인 프로토타입을 만든다
0. 기본 변수 설정
static int x, y; // 커서의 위치, 캐릭터의 위치 저장에 쓴다
static int dir; // 이동방향 저장
static int key; // 입력받은 키 저장
static int speed = 200;
const string sign_Head = "O";
const string sign_Body = "ㅇ";
1. 타이틀 만들기
화면을 보여주기전에 키입력이 없는 상태로 만들어주자
// 키 입력이 있으면 비운다(키 입력이 없는 상태로 만듦)
while (Console.KeyAvailable) // 키 입력이 있으면 true
{
Console.ReadKey(true); // 키 버퍼 비우기
}
제목을 출력한다
static void PrintTo(int x, int y, string s)
{
Console.SetCursorPosition(x * 2, y); // 콘솔창에서 커서의 위치를 x*2, y로 이동
Console.Write(s);
//Console.Out.Flush(); // 즉시 출력 반영
}
PrintTo(15, 5, "+--------------------------+");
PrintTo(15, 6, " S N A K E ");
PrintTo(15, 7, "+--------------------------+");
키 입력을 하면 머리가 생성될 커서 위치를 정한다
while (true)
{
if (Console.KeyAvailable)
{
key = Console.ReadKey(true).Key; // true: 입력된 키를 화면에 표시하지 않음,
// .Key: 어떤 키가 눌렸는지 반환된다(왼쪽 화살표 누르면 ConsoleKey.LeftArrow 반환)
if (key == ConsoleKey.Escape) Environment.Exit(0); // 프로그램 즉시 종료
else break;
}
PrintTo(15, 10, " < PRESS ANY KEY TO START > ");
Thread.Sleep(400);
PrintTo(15, 10, " ");
Thread.Sleep(400);
}
입력을 받으면 머리 생성위치를 정하고, 게임시작으로 넘어간다
Console.Clear();
Console.CursorVisible = false; // 커서를 안보이게
// 머리가 생성될 위치(출력은 PrintTo)
x = 15;
y = 8;
여기까지 정리
static void Title()
{
// 키 입력이 있으면 비운다(키 입력이 없는 상태로 만듦)
while (Console.KeyAvailable) // 키 입력이 있으면 true
{
Console.ReadKey(true); // 키 버퍼 비우기
}
PrintTo(15, 5, "+--------------------------+");
PrintTo(15, 6, " S N A K E ");
PrintTo(15, 7, "+--------------------------+");
while (true)
{
if (Console.KeyAvailable) // 키 입력 버퍼에 키 입력을 받으면 true, 아무 입력이 없으면 false
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true); // true: 입력된 키를 화면에 표시하지 않음,
// .Key: 어떤 키가 눌렸는지 반환된다(왼쪽 화살표 누르면 ConsoleKey.LeftArrow 반환)
key = (int)keyInfo.Key;
break;
}
PrintTo(15, 10, " < PRESS ANY KEY TO START > ");
Thread.Sleep(400);
PrintTo(15, 10, " ");
Thread.Sleep(400);
}
Console.Clear();
Console.CursorVisible = false; // 커서를 안보이게
// 머리가 생성될 위치(출력은 PrintTo)
x = 15;
y = 8;
}
2. 이동로직
방향키 입력을 받는다
if (Console.KeyAvailable) // 키 입력 버퍼에 키 입력을 받으면 true, 아무 입력이 없으면 false
{
key = Console.ReadKey(true).Key; // true: 입력된 키를 화면에 표시하지 않음,
// .Key: 어떤 키가 눌렸는지 반환된다(왼쪽 화살표 누르면 ConsoleKey.LeftArrow 반환)
}
Thread.Sleep(speed);
switch (key)
{
case ConsoleKey.LeftArrow:
if (dir != (int)ConsoleKey.RightArrow) dir = (int)ConsoleKey.LeftArrow;
break;
case ConsoleKey.RightArrow:
if (dir != (int)ConsoleKey.LeftArrow) dir = (int)ConsoleKey.RightArrow;
break;
case ConsoleKey.UpArrow:
if (dir != (int)ConsoleKey.DownArrow) dir = (int)ConsoleKey.UpArrow;
break;
case ConsoleKey.DownArrow:
if (dir != (int)ConsoleKey.UpArrow) dir = (int)ConsoleKey.DownArrow;
break;
case ConsoleKey.Escape:
Environment.Exit(0);
break;
}
key = 0; // 입력된 키 값을 초기화
key = 0은 입력된 키 값을 초기화하는데 0이어야 하는 이유는
0인 이유는 enum값인 ConsoleKey의 None값이 0으로 정의되었기 때문이다
이제 이동방향에 따라서 뱀의 머리를 이동해보자
3. 뱀의머리
위에서 정의한 static 변수를 PrintTo 로직으로 표시한다
static void Move(int dir)
{
Console.Clear();
if (dir == (int)ConsoleKey.LeftArrow) --x;
if (dir == (int)ConsoleKey.RightArrow) ++x;
if (dir == (int)ConsoleKey.UpArrow) --y;
if (dir == (int)ConsoleKey.DownArrow) ++y;
PrintTo(x, y, sign_Head);
}
위의 내용을 무한반복
static void Main(string[] args)
{
Title();
while (true)
{
if (Console.KeyAvailable) // 키 입력 버퍼에 키 입력을 받으면 true, 아무 입력이 없으면 false
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true); // true: 입력된 키를 화면에 표시하지 않음,
// .Key: 어떤 키가 눌렸는지 반환된다(왼쪽 화살표 누르면 ConsoleKey.LeftArrow 반환)
key = (int)keyInfo.Key;
}
Thread.Sleep(speed);
switch (key)
{
case (int)ConsoleKey.LeftArrow:
if (dir != (int)ConsoleKey.RightArrow) dir = (int)ConsoleKey.LeftArrow;
break;
case (int)ConsoleKey.RightArrow:
if (dir != (int)ConsoleKey.LeftArrow) dir = (int)ConsoleKey.RightArrow;
break;
case (int)ConsoleKey.UpArrow:
if (dir != (int)ConsoleKey.DownArrow) dir = (int)ConsoleKey.UpArrow;
break;
case (int)ConsoleKey.DownArrow:
if (dir != (int)ConsoleKey.UpArrow) dir = (int)ConsoleKey.DownArrow;
break;
case (int)ConsoleKey.Escape:
Environment.Exit(0);
break;
}
key = 0; // 입력된 키 값을 초기화
Move(dir);
}
}
이렇게 프로토타입 완성
머리는 이동한다
'유니티 부트캠프 8기 > Ch02. 프로그래밍 기초(C#)' 카테고리의 다른 글
3주차 과제1. 스네이크 게임3. 먹이 추가, 게임 종료 조건 (0) | 2025.02.16 |
---|---|
3주차 과제1. 스네이크 게임2. 맵 만들기, 몸통 추가 (0) | 2025.02.16 |
Console.KeyAvailable() (0) | 2025.02.08 |
디버깅 심화: 직접 실행창 사용하기 (0) | 2025.02.07 |
문자열의 저장방식 (0) | 2025.02.07 |