플레이어 임의의 이동
이전에 만들었던 맵을 바탕으로 Player 클래스를 만들고 랜덤으로 이동하는 프로그램을 만들어보자.
class Player
{
//?
}
막상 플레이어 클래스를 만들었지만 무엇을 먼저 해야하는지 감이 안잡힌다.
그래서 천천히 밑에서부터 주석과 글을 참조해서 이해하자.
첫번째로 해야할 것을 생각해보면 Board클래스에 Player을 가지고 있으면 Board에서 렌더링할대 편하니 추가해주자.
그리고 플레이어 좌표를 가지고 와서 그 좌표랑 현재 y,x좌표가 일치하면 플레이어 전용 색상인 파란색으로 표시해주자.
class Board
{
const char CIRCLE = '\u25cf';
public TileType[,] Tile{ get; private set;}
public int Size { get; private set;}
Player _player;
public void Initialize(int size, Player player)
{
if (size % 2 == 0)
return;
Tile = new TileType[size, size];
_player = player;
Size = size;
//Generate BinaryTree Algorithm
//GenerateByBinaryTree();
GenerateBySideWinder();
}
public void Render()
{
ConsoleColor prevColor = Console.ForegroundColor;
for(int y = 0; y < Size; y++)
{
for(int x = 0; x < Size; x++)
{
//플레이어 좌표를 가지고 와서, 그 좌표랑 현재 y,x 가 일치하면 플레이어 전용 색상으로 표시.
if (y == _player.PosY && x == _player.PosX)
{
Console.ForegroundColor = ConsoleColor.Blue;
}
else
{
Console.ForegroundColor = GetTileColor(Tile[y, x]);
}
Console.Write(CIRCLE);
}
Console.WriteLine();
}
Console.ForegroundColor = prevColor;
}
}
메인함수를 살펴보면,
Board 와 Player을 생성해서 각각 Initialize에 정보를 넘겨준다.
board의 Initialize는 Board 의 크기와 player 이다.
player의 Initialize는 플레이어의 초기 (y좌표,x좌표,도착지y좌표,도착지x좌표,board) 이다.
프레임관리에서 deltaTick을 추가한 이유는 player가 보드를 움직일때 현재 30FPS (1/30초)마다 한칸씩 이동하면 너무 빠르게 움직이기에 deltaTick을 이용해서 1/10초마다 한번씩 움직이게 로직을 바꾸려고 한다.
player.Update(deltaTick) 함수로 플레이어를 랜덤으로 상하좌우 움직이게 만든다.
static void Main(string[] args)
{
int lastTick = 0;
const int WAIT_TICK = 1000/30;
Board board = new Board();
Player player = new Player();
board.Initialize(25,player);
player.Initialize(1, 1,board.Size-2,board.Size-2,board);
Console.CursorVisible = false;
while (true)
{
#region 프레임관리
int currentTick = System.Environment.TickCount;
if (currentTick - lastTick < WAIT_TICK)
continue;
int deltaTick = currentTick - lastTick;
lastTick = currentTick;
#endregion
//입력
//로직(데이터가 변하는 부분)
player.Update(deltaTick); //현재시간과 마지막측정시간의 차이를 넘겨준다.
//렌더링
Console.SetCursorPosition(0, 0);
board.Render();
}
}
internal class Player
{
//외부에서 get으로 좌표만 얻고 설정은 클래스 내에서만 은닉성
public int PosY {get; private set;}
public int PosX {get; private set;}
Random _random = new Random(); //플레이어 상하좌우를 랜덤으로 설정
Board _board; //보드정보 저장
public void Initialize(int posY,int posX, int destY,int destX, Board board)
{
//Player의 초기 y,x좌표 설정
PosY = posY;
PosX = posX;
//현재 딱히 목적지좌표는 사용하지 않는다. 랜덤으로 이동하는 것에 집중
//플레이어도 Board의 정보를 받아와서 이동가능한지 판단해야하므로 board정보 저장
_board = board;
}
const int MOVE_TICK = 100; // 100ms = 1/10초
int _sumTick = 0;// 시간 카운트
public void Update(int deltaTick) //자기의 좌표를 변화시킬 수 있는 함수
{
//deltaTick은 메인함수의 30FPS에 1/30초마다 한칸씩 움직이면 너무 빠르니 deltaTick ( 현재시간 - 마지막측정시간) 을 받아서 동작 할지 안할지 정한다.
_sumTick += deltaTick;
if(_sumTick >= MOVE_TICK) // 시간 카운트 >= 1/10초이면 로직 실행
{
_sumTick = 0; //시간카운트 다시 초기화
//0.1초마다 실행될 로직
int randValue = _random.Next(0,4); //상하좌우 4개
switch(randValue)
{ //맵크기를 벗어나지않는지 체크 && 타일이 비어있는지 체크
case 0: //상
if(PosY - 1 >= 0 && _board.Tile[PosY-1 , PosX] == Board.TileType.Empty)
PosY = PosY - 1;
break;
case 1: //하
if(PosY + 1 < _board.Size && _board.Tile[PosY+1, PosX] == Board.TileType.Empty)
PosY = PosY + 1;
break;
case 2: //좌
if(PosX - 1 >= 0 && _board.Tile[PosY,PosX-1] == Board.TileType.Empty)
PosX = PosX - 1;
break;
case 3: //우
if(PosX + 1 < _board.Size && _board.Tile[PosY,PosX+1] == Board.TileType.Empty)
PosX = PosX + 1;
break;
}
}
}
}
위에 프로그램의 중간 장면이다.
실제로 프로그램을 돌려보면, 랜덤으로 움직이기에 원하는 곳으로 언제 갈지 모르는 문제가 생긴다.
다음에는 오른손 법칙으로 플레이어를 움직이는 방법을 알아보자.
잘 봤습니다. 좋은 글 감사합니다.