GAME MAKER 강좌
KAYAN
◈ 미니맵 만들기
이번 강좌에서는 미니맵을 만들어 봅시다.
(▲ 미니맵)
우선 미니맵 구성을 하기위해 미니맵에 표시할 유닛 오브젝트를 만들고 룸에 배치합시다.
플레이어 오브젝트는 obj_player, 적 오브젝트는 obj_enemy 으로 합니다.
(▲ 배치할 플레이어 유닛)
(▲ 배치할 적 유닛)
어차피 테스트용이기 때문에 대충 만드셔도 됩니다.
다음은 룸을 추가하여 룸의 크기를 설정하고, 유닛 오브젝트들을 배치합니다.
강좌에서는 프로젝트를 생성했을 때 기본적으로 생성된 룸을 활용하여 룸의 크기는 2000 x 2000 으로 설정하겠습니다.
(▲ 룸에 유닛 배치)
그리고 카메라 뷰를 설정합니다.
카메라 뷰 활성화는 Enable Viewports 를 체크하고, 사용할 뷰에서 Visible을 체크하면 됩니다.
(▲ 카메라 설정)
카메라 뷰는 룸의 크기보다 작은 800 x 600 으로 설정해봅시다.
이제 본격적으로 만들 미니맵을 표시/제어할 오브젝트를 하나 만들고, 룸에 배치해둡니다.
이름은 간단하게 obj_minimap 로 하겠습니다.
(▲ 미니맵 오브젝트)
먼저 [Create 이벤트]를 추가하고, 필요한 변수를 만들거에요.
강좌에서는 대충 미니맵의 기본 위치, 미니맵 크기, 미니맵에 필요한 변수를 만듭니다.
//● obj_minimap 오브젝트 - Create 이벤트 minimap_x=16;//미니맵 기본 위치 minimap_y=16;//미니맵 기본 위치 minimap_width=160;//미니맵 가로 크기 minimap_height=120;//미니맵 세로 크기 minimap_click=0;//미니맵 내부에 마우스 포인터가 있을 때=1, 밖에 있을 때=0 |
이와 같이 여러 곳에서 공유되는 중요한 값들을 미리 만들어두면 나중에 수정하기가 매우 편합니다.
미니맵은 [Draw GUI 이벤트]에서 표시할 거에요.
[Draw GUI 이벤트]는 [Draw 이벤트]보다 상위에 표시되는 이벤트로 카메라 좌표에 영향을 받지 않는 특별한 이벤트입니다.
일반적으로 사용자 인터페이스를 구성할 때 사용합니다.
미니맵 오브젝트에 [Draw GUI 이벤트]를 추가하고, 미니맵 틀을 구성합니다.
미니맵을 만들기 위해서 카메라의 좌표와 미니맵의 좌표를 알고 있어야 합니다.
//● obj_minimap 오브젝트 - Draw GUI 이벤트 //카메라 좌표 var _w,_h,vx,vy,vw,vh; vx=camera_get_view_x(view_camera[0]);//카메라 x 좌표 vy=camera_get_view_y(view_camera[0]);//카메라 y 좌표 vw=camera_get_view_width(view_camera[0]);//카메라 너비 vh=camera_get_view_height(view_camera[0]);//카메라 높이 //미니맵의 좌표와 크기 var map_x,map_y,map_w,map_h; map_x=minimap_x;//미니맵 x 좌표 map_y=minimap_y;//미니맵 y 좌표 map_w=minimap_width;//미니맵 너비 map_h=minimap_height;//미니맵 높이 |
대충 위와 같이, 임시변수에 필요한 값을 할당해두면 활용하기가 좋겠죠.
이 좌표를 사용하여 미니맵을 표시할 거에요.
강좌에서 미니맵은 화면의 왼쪽 상단에 표시하겠습니다.
먼저, 미니맵 외형을 만들어 보아요.
//● obj_minimap 오브젝트 - Draw GUI 이벤트 //카메라 좌표 var _w,_h,vx,vy,vw,vh; vx=camera_get_view_x(view_camera[0]); vy=camera_get_view_y(view_camera[0]); vw=camera_get_view_width(view_camera[0]); vh=camera_get_view_height(view_camera[0]); //미니맵의 좌표와 크기 var map_x,map_y,map_w,map_h; map_x=minimap_x; map_y=minimap_y; map_w=minimap_width; map_h=minimap_height; //--------------------- ▼ 이어서 추가 //미니맵 UI var c; c=c_dkgray;draw_rectangle_color(map_x,map_y,map_x+map_w,map_y+map_h,c,c,c,c,0);//배경 c=c_gray;draw_rectangle_color(map_x,map_y,map_x+map_w,map_y+map_h,c,c,c,c,1);//외곽선 |
이와 같이 해서 테스트해보면 짙은 회색에 밝은 회색선의 미니맵이 아래와 같이 표시될 겁니다.
(▲ 테스트 화면)
어...음... 뭔가 썰렁하네요. ㅎㅎ
어째든 다음은 현재 화면을 비추고 있는 카메라 뷰의 위치를 표시해 볼거에요.
미니맵에 카메라 뷰를 표시하려면, 먼저 카메라의 좌표를 미니맵의 좌표로 변환한 값을 알아야 합니다.
(▲ 룸의 좌표를 미니맵 크기로 축소)
미니맵좌표 = 카메라좌표 x 미니맵크기 / 룸크기
이와 같은 식으로 각각 미니맵에 표시할 x,y 좌표를 구하면, 아래와 같이 얻을 수 있습니다.
//카메라의 좌표 x=(vx*map_w)/room_width; y=(vy*map_h)/room_height //카메라의 크기 w=(vw*map_w)/room_width; h=(vh*map_h)/room_height; |
이것을 응용하여 미니맵 좌표를 더해 표시하면 됩니다.
//● obj_minimap 오브젝트 - Draw GUI 이벤트 //--------------------- ▼ 이어서 추가 //미니맵에서 뷰의 위치 표시 var _x,_y,_px,_py,_pw,_ph; _px=map_x+((vx*map_w)/room_width); _py=map_y+((vy*map_h)/room_height); _pw=(vw*map_w)/room_width; _ph=(vh*map_h)/room_height; c=c_white;draw_rectangle_color(_px,_py,_px+_pw,_py+_ph,c,c,c,c,1); |
테스트해보면 흰색의 사각형이 미니맵 위에 표시될 거에요. 이것이 현재 카메라 뷰의 위치가 됩니다.
(▲ 테스트 화면)
어우~ 여전히 먼가 허전합니다. ㅎㅎ
강좌에서는 단순하게 표시했지만, 여러분은 원하시는 형태로 구성하시면 됩니다.
다음은 아래와 같이 룸에 배치한 유닛 오브젝트들을 표시해봅시다.
플레이어 유닛은 노란색, 적 유닛은 빨간색으로 표시할 거에요.
(▲ 미니맵에 유닛 표시)
좌표는 미니맵의 표시한 방식과 같습니다.
with(obj_player){ _x=map_x+((x*map_w)/room_width); _y=map_y+((y*map_h)/room_height); } |
이것을 응용하여 룸 안에 있는 유닛을 표시한다면 아래와 같습니다.
//● obj_minimap 오브젝트 - Draw GUI 이벤트 var _w,_h,vx,vy,vw,vh; vx=camera_get_view_x(view_camera[0]); vy=camera_get_view_y(view_camera[0]); vw=camera_get_view_width(view_camera[0]); vh=camera_get_view_height(view_camera[0]); var map_x,map_y,map_w,map_h; map_x=minimap_x; map_y=minimap_y; map_w=minimap_width; map_h=minimap_height; //미니맵 UI var c; c=c_dkgray;draw_rectangle_color(map_x,map_y,map_x+map_w,map_y+map_h,c,c,c,c,0);//배경 c=c_gray;draw_rectangle_color(map_x,map_y,map_x+map_w,map_y+map_h,c,c,c,c,1);//외곽선 //미니맵에서 뷰의 위치 표시 var _x,_y,_px,_py,_pw,_ph; _px=map_x+((vx*map_w)/room_width); _py=map_y+((vy*map_h)/room_height); _pw=(vw*map_w)/room_width; _ph=(vh*map_h)/room_height; c=c_white;draw_rectangle_color(_px,_py,_px+_pw,_py+_ph,c,c,c,c,1); //--------------------- ▼ 이어서 추가 //유닛의 위치 표시 //플레이어 오브젝트 with(obj_player){ if x>0 && y>0 && x<room_width && y<room_height{ _x=map_x+((x*map_w)/room_width); _y=map_y+((y*map_h)/room_height); draw_circle_color(_x,_y,2,c_yellow,c_yellow,0); }} //적 오브젝트 with(obj_enemy){ if x>0 && y>0 && x<room_width && y<room_height{ _x=map_x+((x*map_w)/room_width); _y=map_y+((y*map_h)/room_height); draw_circle_color(_x,_y,2,c_red,c_red,0); }} |
여기까지 해보면 우리가 원했던 표시가 이루어질 거에요.
이제 미니맵 위에 있는 카메라를 드래그하여 화면을 움직여봅시다.
강좌에서는 사용자 이벤트에 드래그 이벤트를 구성하여 [Step 이벤트]에서 호출할 거에요.
[User Defined 0 이벤트]를 추가합니다.
우선 마우스 포인터가 미니맵 안에 있는지 체크해야합니다.
//● obj_minimap 오브젝트 - User Defined 0 이벤트 var _w,_h,vx,vy,vw,vh,mx,my; vx=camera_get_view_x(view_camera[0]); vy=camera_get_view_y(view_camera[0]); vw=camera_get_view_width(view_camera[0]); vh=camera_get_view_height(view_camera[0]); mx=mouse_x; my=mouse_y; var map_x,map_y,map_w,map_h; map_x=vx+minimap_x; map_y=vy+minimap_y; map_w=minimap_width; map_h=minimap_height; //마우스 포인터가 미니맵에 있는지 체크 if mx>map_x && my>map_y && mx<map_x+map_w && my<map_y+map_h{ minimap_click=1;//미니맵 내부에 마우스 포인터가 있을 때 } else{ //미니맵 밖에 있고, 마우스를 클릭하지 않았다면 변수를 초기화 if !(mouse_check_button(mb_left)){minimap_click=0;} } |
그리고 마우스 포인터가 미니맵 안에 있을 때, 마우스를 클릭하면 마우스 포인터 위치를 중심으로 카메라를 이동시킬 겁니다.
카메라의 위치는 아래의 함수를 사용하여 설정할 수 있습니다.
camera_set_view_pos(camera, x, y)
미니맵 좌표를 룸의 좌표를 변환하려면, 룸 좌표를 미니맵 좌표로 변환한 식을 반대로 응용하시면 됩니다.
(▲ 미니맵 좌표를 룸의 좌표로 확대)
카메라좌표 = (마우스좌표-(미니맵좌표 + 카메라좌표)) x 룸크기 / 미니맵크기
기본식을 그대로 사용하면 마우스 포인터 위치가 카메라 왼쪽 상단으로 정렬 될 겁니다.
따라서 기본식으로 얻은 값에 카메라 크기의 절반을 각각 x,y 위치에서 빼주면 카메라 가운데로 정렬할 수 있습니다.
이것을 응용하면 아래와 같이 할 수 있습니다.
//● obj_minimap 오브젝트 - User Defined 0 이벤트 var _w,_h,vx,vy,vw,vh,mx,my; vx=camera_get_view_x(view_camera[0]); vy=camera_get_view_y(view_camera[0]); vw=camera_get_view_width(view_camera[0]); vh=camera_get_view_height(view_camera[0]); mx=mouse_x; my=mouse_y; var map_x,map_y,map_w,map_h; map_x=vx+minimap_x; map_y=vy+minimap_y; map_w=minimap_width; map_h=minimap_height; //마우스 포인터가 미니맵에 있는지 체크 if mx>map_x && my>map_y && mx<map_x+map_w && my<map_y+map_h{ minimap_click=1;//미니맵 내부에 마우스 포인터가 있을 때 } else{ //미니맵 밖에 있고, 마우스를 클릭하지 않았다면 변수를 초기화 if !(mouse_check_button(mb_left)){minimap_click=0;} } //--------------------- ▼ 이어서 추가 //미니맵을 통해 뷰 이동 var _x,_y; if minimap_click==1{ _x=floor(((mx-map_x)*room_width)/map_w); _y=floor(((my-map_y)*room_height)/map_h); if mouse_check_button(mb_left){//마우스를 클릭하면 카메라를 이동 //변환한 마우스 포인터 위치가 카메라의 가운데로 위치하도록 설정 vx=max(0,min(_x-(vw/2),room_width-vw)); vy=max(0,min(_y-(vh/2),room_height-vh)); camera_set_view_pos(view_camera[0],vx,vy); } } |
이것은 마우스 왼쪽 버튼을 누를 떄, 미니맵 위에 마우스 위치를 룸의 실제 좌표로 변환하여 카메라 뷰의 위치를 갱신하는 것입니다.
후우~ 끝났네요.
[Step 이벤트]를 추가하고, 이 이벤트를 호출하면 됩니다.
//● obj_minimap 오브젝트 - Step 이벤트 //미니맵 드래그 event_user(0); |
잘 이동하는지 테스트 해봅시다.
(▲ 미니맵 드래그하여 카메라 이동)
이번에는 미니맵 안에 마우스 오른쪽 버튼을 클릭했을 때, 오브젝트를 생성해봅시다.
강좌에서는 생성할 오브젝트는 플레이어 오브젝트입니다.
(▲ 미니맵을 통해 오브젝트 생성)
미니맵 드래그 이벤트와 마찬가지로 사용자 이벤트를 활용하겠습니다.
[User Defined 1 이벤트]를 추가하고, 이벤트를 구성합니다.
미니맵에서의 마우스 좌표를 룸의 좌표로 변환하려면 아래의 식으로 얻을 수 있습니다.
카메라 뷰 이동했을 때와 같죠.
룸 좌표 변환 = (마우스좌표- (미니맵좌표 + 카메라좌표)) x 룸크기 / 미니맵크기
이 식을 응용하여 마우스 오른쪽 버튼을 클릭했을 때 오브젝트를 생성해봅시다.
//● obj_minimap 오브젝트 - User Defined 1 이벤트 //--------------- 미니맵을 통해 룸 좌표를 제어 시작 var _w,_h,vx,vy,vw,vh,mx,my; vx=camera_get_view_x(view_camera[0]); vy=camera_get_view_y(view_camera[0]); vw=camera_get_view_width(view_camera[0]); vh=camera_get_view_height(view_camera[0]); mx=mouse_x; my=mouse_y; var map_x,map_y,map_w,map_h; map_x=minimap_x; map_y=minimap_y map_w=minimap_width; map_h=minimap_height; //룸 내에서의 미니맵 위치(카메라 위치 기준) var cx,cy; cx=vx+map_x; cy=vy+map_y; //미니맵에서의 마우스 위치를 룸의 좌표로 환산 var map_mouse_x,map_mouse_y; map_mouse_x=((mx-cx)*room_width)/map_w; map_mouse_y=((my-cy)*room_height)/map_h; //오브젝트 생성 테스트 if minimap_click==1{ if mouse_check_button_pressed(mb_right){ instance_create_depth(map_mouse_x,map_mouse_y,0,obj_player); }} //--------------- 미니맵을 통해 룸 좌표를 제어 끝 |
이렇게 하면, 미니맵 위에서 마우스 오른쪽 버튼을 눌렀을 때, 미니맵 위의 마우스 위치를 룸의 좌표로 변환한 위치에 플레이어 유닛을 생성하게 됩니다.
이제 구성한 사용자 이벤트를 [Step 이벤트]에서 호출하면 됩니다.
//● obj_minimap 오브젝트 - Step 이벤트 //미니맵 드래그 event_user(0); //------------------- ▼ 이어서 추가 //미니맵을 통해 룸 좌표를 제어 event_user(1); |
여기까지~!
잘 작동하는지 테스트해봅시다.
강좌는 단순히 원리 위주로 설명했지만, 여러분은 더 멋진 UI를 구성하실 거라 생각합니다.
'GameMaker강좌[GMS2] > 기타장르강좌' 카테고리의 다른 글
[게임메이커 강좌-기타][GMS2]그리드 기반의 길찾기-6 A Star 알고리즘 (2) | 2023.01.29 |
---|---|
[게임메이커 강좌-기타][GMS2]그리드 기반의 길찾기-5 이동 거리 제한 (0) | 2023.01.18 |
[게임메이커 강좌-기타][GMS2]그리드 기반의 길찾기-4 응용편3 (0) | 2023.01.13 |
[게임메이커 강좌-기타][GMS2]그리드 기반의 길찾기-3 응용편2 (0) | 2023.01.12 |
[게임메이커 강좌-기타][GMS2]그리드 기반의 길찾기-2 응용편1 (0) | 2023.01.11 |
댓글