메뉴 건너뛰기

창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳

2편 : 기본적인 캐릭터 움직임

일단 강좌를 시작하기 전에 2가지 사항을 이야기 하겠습니다.
사실 안 읽으셔도 별로 상관없습니다.

/*------------------------------------ 주석인 셈입니다. -----------------------------------------------------------

1. 흥크립트 자동 대화창 기능에서 메모리 누수 현상이 발견되었습니다
치명적인 것은 아니지만 집의 메모리가 128MB이하라면 곤란할 수도?

처음에는 매 출력마다 대화창을 자동으로 크게에 맞게 그리는 식이었는데
속도 낭비가 너무 심해서 메모리를 할당해 미리 그린 후 빠르게 출력하게 했습니다.
그런데 어디가 잘못되었는지 계속해서 조금씩 메모리가 낭비되더군요.

1) 어쨌든 강좌를 하다보면 이것 저것 라이브러리의 문제점이 발견될지도 모르고
2) 아직은 대화창에 관련된 강좌는 하지 않을 것이고
3) 저 메모리 누수로 컴퓨터 다운 시키려면 상당히 대규모 게임을 만들어야 할 테니 발생할 확률도 적고
4) 자동대화창 기능을 그냥 없애고 싶지 않아서 손 볼려는 데, 시간이 꽤 걸릴 듯

이런 이유로 일단은 덮어 두겠습니다.


2. 과거에 문D라이브 강좌를 한 적이 있습니다.

1편
http://blog.naver.com/kfgenius.do?Redirect=Log&logNo=130014444939

2편
http://blog.naver.com/kfgenius.do?Redirect=Log&logNo=130014480937

3편
http://blog.naver.com/kfgenius.do?Redirect=Log&logNo=130014567046

4편
http://blog.naver.com/kfgenius.do?Redirect=Log&logNo=130014707401

대화창 클래스(CTextDlg) 빼고는 지금 버전에 그대로 적용되니
안 해보신 분은 이걸 연습해 보시는 것도 좋습니다.

//------------------------------------------------------------------------------------------------------------------------*/


그럼 다시 본론으로 돌아와서 더블 드래곤 같은 액션 게임 만들기 입니다.

Source2.zip

이걸 받아서 MoonD.sln이 있는 폴더에 풉니다.
하위 폴더 만드시지 마시고 그 자리에 풀어 주십시오.

원래는 Mayday님이 만드신 무투를 그대로 구현하는 게 쉬울 것 같아서 그걸 보여 드리려고 했는데
알고보니 그래픽 파일이 모두 xyz으로 되어 있어서 일단 접어두고,
이 샘플 소스로 하겠습니다. 여기 배경은 알만툴 것이고 그림은 독고진님이 그리셨던 건데...
뭐 설마 이거 가지고 뭐라고 하시겠습니까?
Mayday님은 혹시 괜찮다면 무투 소스 좀 보내주세요.
무투 그대로 재현하는 것을 강좌 3부터 해보도록 하죠.

일단 소스를 어디에 적어야 하나?
강좌1에 있었던 Sample에서 MoonD.sln을 더블클릭해서 프로젝트를 엽시다.
일단 main.cpp로 가야하는데 아무것도 안 떠 있다면...



화면 왼쪽이나 오른쪽 구석에 있을 솔루션 탐색기를 선택해서



main.cpp를 더블 클릭하십시오.
만약 솔루션 탐색기가 안 보이면 보기 메뉴에서 - 솔루션 탐색기를 선택하십시오.



VC++ 툴을 다루는 것은 그다지 어렵지 않으니 잘 익혀두십시오.
제가 하나하나 설명하기에 지면 낭비가 심할 듯 싶군요.

자, 이제 main.cpp가 열렸다면 고쳐야 할 부분은 친절하게도 주석 (일종의 설명으로 컴파일때는 처리되지 않고
코드를 작성할 때만 보여서 코드의 이해를 돕는 문장)이 달려있습니다.

//////////////////////////////////////////////////
//메인코드
//////////////////////////////////////////////////
int main(char* arg[])
{
     //창생성
     if(!MainInitialize("Sample", TRUE, FALSE, window_mode))return 0;

     //윈도우창이동
     if(window_mode)
     {
          jdd->OnMove(100, 100);
          SetCursor(LoadCursor(0, IDC_ARROW));
     }
    
     //메인실행
     while(!GetKey(vkey_esc))
     {
          if(!ProcessMessage())break;

          //이곳에게임을만듭니다.

          jdd->Render();
     }

     //정리하고끝내기
     jdd->DeleteFont(global_font);

     return 0;
}


바로 빨간 저 부분이지요.
저 주석은 지워버리고 새로운 코드를 적어봅시다.
팩맨 만들어 보신 분 있다면 이건 중복이겠지만 복습치고 해봅시다.

int main(char* arg[])
{
     //창생성
     if(!MainInitialize("Sample", TRUE, FALSE, window_mode))return 0;

     //윈도우창이동
     if(window_mode)
     {
          jdd->OnMove(100, 100);
          SetCursor(LoadCursor(0, IDC_ARROW));
     }

     jdd->LoadPicture("배경", "던젼6.jpg", NULL, true);
     jdd->LoadPicture("걷기1", "w1.gif", NULL, true);
     jdd->LoadPicture("걷기2", "w2.gif", NULL, true);
     jdd->LoadPicture("걷기3", "w3.gif", NULL, true);

     //메인실행
     while(!GetKey(vkey_esc))
     {
          if(!ProcessMessage())break;

          jdd->DrawPicture(backbuffer, "배경", 0, 0, NULL);
          jdd->DrawPicture(backbuffer, "걷기1", 100, 100, NULL);

          jdd->Render();
     }

     //정리하고끝내기
     jdd->DeleteFont(global_font);

     return 0;
}

간단하게 그림을 읽어 들이고(LoadPicture) 그림을 출력(DrawPictrue)하는 겁니다.
각각 어떻게 쓰는지 봅시다.

jdd->LoadPicture("그림 이름", "파일명", NULL, true);

식으로 씁니다.
뒤에 NULL과 true는 신경 끄시고 그냥 저렇게만 적어 주면 됩니다.
아마 저걸 알 필요는 없을 겁니다.

ID값은 프로그램 내에서 저 그림에 부여하는 이름입니다.
나중에 저 그림을 부를 때 쓸 이름이죠.
그리고 뒤에는 파일명, 그림파일의 지금 현재 작업 폴더로 부터 상대 경로를 적어주면 됩니다.
절대 경로 적어주셔도 먹힙니다.
단, 다른 컴퓨터에 다른 폴더가 된다면 작동 안 하니까 절대 경로는 쓰지 마십시오.

어쨌든 위에서는 "던젼.jpg"라는 그림을 "배경"이란 이름을 붙여 불렀군요.

여기서 또 하나!

게임의 메인 루프는 while의 안입니다.

 while(!GetKey(vkey_esc))
{
     (이 안)
}

LoadPicture 명령은 반드시 이 밖에서, 루프가 시작되기 전에 해야합니다.
루프는 보통 1초에 100번 도는데 로드 같은 작업을 1초에 100번 시키면 난리납니다.
그러니까 루프 들어가기 전에 딱 한번!

그럼 이번엔 불러 들인 그림을 출력해 봅시다.

jdd->LoadPicture(backbuffer, "그림 이름", X좌표, Y좌표, NULL);

역시 다른 부분은 신경 끄고 파란 부분만 봅시다.
눈치 있으신 분은 알겠지만 해당하는 X좌표와 Y좌표에 불러 들인 그림을 찍는 겁니다.
지금 게임에서는 "배경"이란 그림을 X:0 Y:0 에 찍고 있는 겁니다.
"걷기1"이란 그림은 X:100 Y:100 에 찍고요.

제대로 하셨다면 아래와 같이 출력 될 겁니다.




다음은 캐릭터를 이동시켜 봅시다.
지금은 100, 100에 무조건 찍게 되어 있습니다.
이걸 바꿔야 겠죠?

변수라고 아십니까? 모르는 분들도 있을 테니 설명을 하겠습니다.
변수는 간단히 변하는 수입니다.

지금 코드에 적어놓은 100, 100은 무슨 일이 있어도 변하지 않습니다.
프로그램을 잡고 온갖 난리를 떨어도 100, 100은 100,100입니다.

그럼 어떻게 해야 할까?
이렇게 해야 합니다.

 jdd->DrawPicture(backbuffer, "걷기1", x, y, NULL);

숫자 대신 x와 y라고 적었습니다.
이게 변수입니다.
그런데 이렇게 쓰고 실행시켜 보면 에러가 날겁니다.
왜냐면 C++에는 선언이 필요하기 때문이죠.

while이 시작되기 전에 변수를 선언해줍시다.

int x = 100;
int y = 100;

int란 정수란 뜻입니다. integer죠.
'변수 x는 내가 정수로 쓸텐데 일단 초기값은 100이다.' 라고 선언하는 겁니다.
프로그램에게 선언하는 거죠. 나 이렇게 쓸거야 하고.

이것만 넣고 테스트 해봐야 같을 테니 소스를 이렇게 바꿔봅시다.
선언부분도 포함해 두었으니 이걸 보고 아까 코드를 수정해 봅시다.


//////////////////////////////////////////////////
//메인코드
//////////////////////////////////////////////////
int main(char* arg[])
{
     //창생성
     if(!MainInitialize("Sample", TRUE, FALSE, window_mode))return 0;

     //윈도우창이동
     if(window_mode)
     {
          jdd->OnMove(100, 100);
          SetCursor(LoadCursor(0, IDC_ARROW));
     }

     jdd->LoadPicture("배경", "던젼6.jpg", NULL, true);
     jdd->LoadPicture("걷기", "w1.gif", NULL, true);
     jdd->LoadPicture("걷기", "w2.gif", NULL, true);
     jdd->LoadPicture("걷기", "w3.gif", NULL, true);

     int x = 100;
     int y = 100;

     //메인실행
     while(!GetKey(vkey_esc))
     {
          if(!ProcessMessage())break;

          if(GetKey(vkey_up,1))y-=5;
          if(GetKey(vkey_down,1))y+=5;
          if(GetKey(vkey_left,1))x-=5;
          if(GetKey(vkey_right,1))x+=5;

          jdd->DrawPicture(backbuffer, "배경", 0, 0, NULL);
          jdd->DrawPicture(backbuffer, "걷기", x, y, NULL);

          jdd->Render();
     }

     //정리하고끝내기
     jdd->DeleteFont(global_font);

     return 0;
}

이렇게 고친 후 실행 해 보면 키 조작에 의해서 상하좌우로 이동하는 캐릭터를 보실 수 있습니다.
일단 GetKey부터 설명해야 겠군요.

GetKey(키ID, 연속입력 간격)

키 ID는 반드시 지정된 것을 써야 인식을 합니다.
약 90여개가 있지만 사실 그 키들을 다 쓸 일은 없을테고 나올 때마다 설명하기로 하죠.
처음부터 다 알고 싶은 분은 donglib.h에서 vkey로 검색해 보시길.
다 정의되어 있습니다.

아무튼 해당 키ID의 입력이 들어오면 GetKey는 '참'이란 값을 돌려 줍니다.
'참'이란 값을 돌려 주다니? 무슨 소리... 라고 아직 C++의 표현에 익숙하지 않으신 분들을 일단 넘어갑시다.
나중에 if 이야기하면서 설명하겠습니다.

다음 값인 연속입력 간격에 대해 설명하겠습니다.
일단 저 값을 안 적고 GetKey(vkey_up)으로 한번 바꿔 보십시오.
그러면 위쪽 화살표를 누른 순간에만 인식을 하고 그 후로는 안 먹힙니다.
손을 뗀 후 다시 눌렀을 때 먹힙니다.
이동 할 때마다 따다다닥 눌러 댈 순 없으니 꾹 누르고 있으면 그냥 움직이게 하고 싶겠죠?
그럴 때는 저 값을 적어줍니다. 1이라고 적으면 1/100초를 기다렸다가 다시 확인해본다는 겁니다.
1/100가 지나서 다시 확인해봤는데도 누르고 있는 상태라면 해당 이벤트를 한 번 더 일으킵니다.
확실히 익히시고 싶으시면 저 값을 바꿔 보십시오. 마이너스 값은 의미 없습니다.
단, -1은 특별 값으로 -1을 적으면 한 번 인식한 후 뗐다가 다시 누를 때까지 인식하지 않습니다.
아무 것도 안 적었을 때와 같은 값이죠.

그럼 if를 볼까요? 게임에서는 if가 가장 중요합니다.
조건문 없이는 게임이 아닌 영화가 되겠지요. 뭐 잡설은 그만하고.

if(GetKey(vkey_up, 1))y-=5;

풀어서 설명해 보겠습니다.

만약 GetKey에서 '참'이란 값을 주면 y를 5 감소(y-=5)시켜라.

...란 뜻입니다.
아까전에 참, 거짓을 이야기 했는데 그것은 이 if를 위한 것이지요.
if는 돌아온 참이면 그 다음에 적힌 코드를 실행하고
거짓이라면 그냥 쌩까 버립니다.
그런 녀석이지요.

GetKey는 위쪽 화살표(vkey_up)를 눌렀을 때만 참이란 값을 돌려 주므로
위쪽 화살표를 누르지 않는 한 y-=5는 실행되지 않는 것이죠.

마찬가지로 밑에는 아래쪽 화살표(vkey_down), 왼쪽 화살표(vkey_left), 오른쪽 화살표(vkey_right)에 의한 반응들입니다.


어느 정도 이해하셨는지 몰라도 모르시는 것 있으시면 나중에 물으시도록 하십시오.
일단 지금은 캐릭터가 그냥 화면을 벗어나 버릴 겁니다.
그걸 막아야 겠죠.
그걸 위해 이 코드를 추가합니다.


  if(x<0)x=0;
  if(x>SCREEN_X-19)x=SCREEN_X-19;
  if(y<0)y=0;
  if(y>SCREEN_Y-29)y=SCREEN_Y-29;


어디에 추가해야 되고 무슨 뜻인지는 과제로 남기겠습니다.
만약 캐릭터가 화면을 빠져 나가지 않는다면 성공한 것입니다.

흑곰

2008.04.18
07:24:55
(*.146.136.211)

잘 봤습니다. 비베로 구현해 본 것이라 쉬웠구요.
다만 GetKey를 Getkey로 쓰는 바람에 빌드가 안되어 고생 좀 했습니다.

jdd->LoadPicture("배경", "던젼.jpg", NULL, true);은
jdd->LoadPicture("배경", "던젼6.jpg", NULL, true);이었구요.

3강은 언제쯤 되나요?

똥똥배

2008.04.18
09:16:18
(*.193.78.73)
흑곰//"던젼6.jpg"로 수정했습니다.
3강은 내일 출발하기 전에 아침에 끝낼려고 하는데 가능할지 어떨런지...
안 그러면 워크샵 다녀온 토요일이 되겠군요.
이미 과거에 해봤던 흑곰님과 대슬님에겐 죄송하지만 다른 분들도 생각해서 천천히 가겠습니다.

다른 분들도 '어려웠다', '보통이다', '쉬웠다' 정도라도 적어주십시오.
레벨 조정을 위해서...

A.미스릴

2008.04.19
03:02:00
(*.234.10.203)

근데 While문이 1/100초마다 돌아가는거였나여?
전 While문이랑 For문 둘다 그냥 CPU가 되는 한 간격을 두지 않고 온 힘을 다해 끊임없이 루프하는줄 알았는데요 ㅡ,.ㅡ;

Mayday

2008.04.19
10:16:40
(*.106.221.253)

아니 캐릭터소스는 제가 공개하기도 전에 하드에서 날려먹었던 게임에 있던 소스인데
어떻게 구하셨지..;;;;;

똥똥배

2008.04.19
23:27:12
(*.193.78.73)
Mayday님이 저한테 주신 겁니다.
그때 제가 프로그래밍하고, Mayday님이 그래픽해서
열혈물어같은 게임 만들어보려고 했었죠.
아쉽게도 실패했지만...

똥똥배

2008.04.24
03:26:44
(*.239.144.2)
A.미스릴//while문이 1/100초에 도는 것이 아닙니다.
jdd->Render(); 이부분에서 프레임 수를 1/100로 조절하는 겁니다.
왜냐면 컴퓨터 사양에 따라서 어디서는 빠르게 돌아가고 어디서는 늦게 돌아가면 안 되니까요.
보통 1/100초 전에 작업이 끝나게 되고 jdd->render에서는 1/100초가 될 때까지 대기를 하게 됩니다.
List of Articles
번호 제목 글쓴이 조회 수sort 추천 수 날짜 최근 수정일
165 멘탈붕괴의 절정을 부르는 파일입출력 노루발 273   2013-09-17 2013-09-17 08:18
Love2D의 love.filesystem.load는 훼이크입니다. 파일을 로드하는 것 같지만 사실 lua 파일을 불러옴. love.filesystem.read도 그리 믿음직하지 못함. (고정 크기의 파일만 읽어옴) 우리가 믿을 수 있는 최후의 보루는 love.filesystem.lines 이었던 것입니다....  
164 [Lua] Split 노루발 361   2013-09-17 2013-09-17 08:16
상황을 가정해보자. 웹 서버에 부탁해서 유희왕 덱의 리스트를 가져왔다. 원문은 대략 이렇다고 가정하자.   셰이프스내치x3 모린팬x3 트렌트x3 ...    보기엔 이렇지만 이걸 가져오면 아래와 같이 뜰 것이다. (웹 서버니까 HTML로 줌) 셰이프스내치x3<br>모...  
163 Love2d 게임 중간에 광고 표시 [1] 노루발 377   2015-11-12 2015-11-17 00:16
http://love2d.org/forums/viewtopic.php?f=11&t=81224  
162 김프로 이미지 맵 만들기 노루발 393   2015-11-11 2015-11-11 08:05
https://docs.gimp.org/en/plug-in-imagemap.html  
161 love.graphics.print 한국어 출력 노루발 431   2013-09-17 2013-09-17 08:24
Love2D 사용 시 한국어가 ㅁㅁㅁ이나 ??? 등으로 깨져 나와 해결책을 수소문하여 겨우 찾았다. 원래 중국어 등을 출력하기 위한 것이었으니 적절한 폰트를 쓴다면 한자나 히라가나등도 출력할 수 있을 것이다. function love.load() korfont = love.graphics....  
160 턴 기반 시스템 구현에 대한 글 [4] 노루발 440   2020-11-14 2020-11-18 05:49
플레이어와 NPC들의 모든 행동에 1턴이 소요된다면 턴 기반 시스템의 구현이 쉽겠지만 (사실 엄청 쉽지는 않다... 게임엔진은 실시간으로 돌아가는데 행동은 턴으로 제약해야 하니) 전략성을 요구하기 위해 행동에 소모되는 턴을 다르게 설정한다면 다소 생각...  
159 cocos2d-x CCMenuItem 자신을 지웠을 때 생기는 에러 똥똥배 442   2013-09-13 2013-09-13 07:28
CCMenuItem으로 메뉴를 생성하고 타겟과 셀렉터를 정해서 그 명령 안에서 자신을 지우게 되었을 경우 activate() 안에서 에러가 발생한다. 아직 activate()를 실행해야 되는데 remove 당했기 때문에 생긴 문제인데, 구글에서 검색해 본 결과, https://github.c...  
158 Love2D를 사용하기 위한 Lua 강좌: 변수형 노루발 446   2013-09-17 2013-09-17 08:23
안녕하세요, 노루발입니다. 저번에 변수에 대해 다뤄보았습니다. 변수는 값을 담는 그릇이라고 했습니다. 그리고 루아는 변수 안에 있는 값이 숫자던 문자던 그냥 변수로 취급한다고 했고 "몇개를 살까요?" 라는 질문에 "ㄹ개" 라고 답할 수도 있다고 했습니...  
157 [Love2D] 일단 뭔가 해보자 노루발 457   2013-09-17 2013-09-17 08:27
감기를 딛고 다시 재기... Lua로 초 간단한 원시적인 게임을 만들려고 합니다. 뭐냐하면 소코반이라고, 이렇게 말하시면 모르지만 푸쉬푸쉬라면 아시는 분들이 엄청 많으실겁니다. 이걸 그래픽조차 씌우지 않은 아스키로. ########## #    ..      # #    o  o...  
156 Love2D? 개요, 설치, 실행. 노루발 465   2013-09-17 2013-09-17 08:20
love2d.org/Love2D 홈페이지. Lua로 2D 게임을 만드는 프레임워크입니다. 무료고, 오픈 소스이며, 윈도우, 맥, 리눅스에서 동작하며, 안드로이드에서 동작하게 하는 논의도 활발하다 합니다. 그럼 일단 받아봅시다. 아무리 좋아도 내 컴퓨터에 못 깔면 소용없...  
155 Love2d 여러 플랫폼으로 빌드 자동화 노루발 470   2014-11-12 2014-11-12 17:35
https://github.com/MisterDA/love-release/blob/master/README.md http://www.ambience.sk/lua-love2d-game-distribution/  
154 PHP로 웹게임 만드는 영상 [1] 노루발 474   2021-06-25 2022-01-28 03:40
Simple PHP Strategy Game - YouTube  
153 cocos2d-x에서 schedule_selector 정의 변화 [1] 똥똥배 522   2013-08-19 2013-09-13 07:28
예전에 적은 글에는 터치와 업데이트를 활성화 시키는 법을 적어놨다. http://hondoom.com/zbxe/index.php?mid=study&document_srl=385031 이글은 cocos2d-1.0.1-x-0.9.1를 기준으로 적은 글인데, 최신버전으로 오면서 update의 정의에 대해서 변화가 생겼...  
152 Love2D: 콜백 함수들 노루발 538   2013-09-17 2013-09-17 08:25
Love의 콜백 함수들은 love.run(가장 메인이 되는 겁니다.)에 의해 호출되며, 많은 작업들을 수행합니다. 이것들이 없다고 게임이 실행되지 않는다거나 하지는 않지만 좋은 게임을 만들기 위해선 이것들을 적재적소에 활용해야 합니다. 이미 아시는 분들도 있...  
151 cocos2d-x 게임을 iOS에 이식할 때 생기는 문제들 똥똥배 543   2013-08-26 2013-09-13 07:28
1. 윈도우 한정 명령어는 사용할 수 없다. 너무도 당연한 문제. 2. 한글 인코딩 문제 최신 VS을 사용하면 겪지 않을 문제일지 모르겠지만, 보통은 h나 cpp를 ANISI형식 문서로 만들 것이다. XCode에서는 Unicode나 UTF-8 형식을 쓰므로 소스에 박아둔 한글은 ...  
150 Love2d 안드로이드 게임 패키징하기 [3] 노루발 548   2014-12-15 2021-01-11 12:11
이 문서는 개발 환경이 갖추어져 있는 상태이고, 빌드를 무사히 마친 뒤라고 가정합니다. 또한 이 문서는 https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Game%20Packaging#markdown-header-how-to-package-the-apk-with-your-own-love-090-game ...  
149 Love2d 안드로이드 빌드하기 노루발 572   2014-12-15 2014-12-15 00:59
Love2d의 안드로이드 포트는 알파 단계입니다. 차차 개선되어 나가긴 하겠지만 아직 불안정한 부분이 많으며, 일어날 수 있는 오작동과 그로 인한 결과는 일절 책임지지 않습니다.   이 문서는 Windows 사용자 기준입니다. Linux나 Mac을 사용할 정도의 내공...  
148 구글 인앱 구매 Soomla로 구현해본 후 팁 똥똥배 577   2014-09-20 2014-09-20 18:45
1. 일단 알파 테스트라도 앱을 출시시켜야 인앱이 작동한다. 그리고 APK 업로드 후에 바로 인앱이 적용되지 않는다. 구글에 게시되는 데, 시간이 걸리므로 인앱 등록 - APK 등록을 마친 후 다음날부터 구현하는 게 깔끔하다. 이걸로 모르고 하루종일 왜 안되나...  
147 Love2D를 사용하기 위한 Lua 강좌: 코딩 스타일, 변수 노루발 585   2013-09-17 2013-09-17 08:22
안녕하세요, 노루발입니다. 어제는 Lua에 대해 대강 알아보고 입력과 출력을 다뤄봤습니다. 출력은 print([출력할 것]), 입력은 io.read()였습니다. 일단 본격적인 프로그램 작성에 앞서 Lua의 코딩 스타일에 대해 알아보겠습니다. 코드를 작성하는 것을 코딩...  
146 소코반: 맵을 초기화하자. 노루발 588   2013-09-17 2013-09-17 08:27
8*8 맵의 데이터가 담길 2차원 배열(테이블)을 초기화하는 코드이다. Map = {} for a = 1, 8 do     Map[a] = {}     for b = 1, 8 do         Map[a][b] = 0     end end Map 테이블의 [1][1]부터 [8][8]까지 모두 0이라는 값이 담기고 Map[0][0]이나 Map[1][...