GAME MAKER 강좌
KAYAN
☆이번에는 화면 상단에 미니맵을 구성하는 것에 대해 알아 볼 것입니다.
(▲게임 화면)
◈미니맵 구성(obj_ctrl_sys)
간단하게 적의 위치와 지금 어느 위치를 보고 있는지 확인할 수 있는 미니맵을 구성해봅시다.
(▲이번 강좌에서 만들게 될 미니맵)
먼저 게임을 제어하는 시스템 오브젝트(obj_ctrl_sys)로 이동해서, Create 이벤트에 필요한 변수들을 추가해줍니다.
★ obj_ctrl_sys - Create 이벤트 minimap_width=160;//미니맵 가로 사이즈 minimap_height=120;//미니맵 세로 사이즈 minimap_click=0;//마우스 포인터가 미니맵 안에 있는지 체크 |
이것은 미니맵의 크기를 미리 정해주는 것입니다.
다음은 Draw 이벤트에서, 아래와 같이 추가해 미니맵의 위치와 모양을 표시해주도록 해요.
★ obj_ctrl_sys - Draw 이벤트 var _w,_h,vx,vy,vw,vh; vx=view_xview[0];//미니맵의 표시 기준점 vy=view_yview[0];//미니맵의 표시 기준점 vw=view_wview[0]; vh=view_hview[0]; _w=minimap_width; _h=minimap_height; c=c_dkgray;draw_rectangle_color(vx,vy,vx+_w,vy+_h,c,c,c,c,0);//미니맵 바탕 c=c_gray;draw_rectangle_color(vx,vy,vx+_w,vy+_h,c,c,c,c,1);//미니맵 외곽선 |
이것은 어두운 회색 바탕의 약간 밝은 회색의 외곽선을 가진 사각형 모양의 미니맵입니다.
강좌에서 미니맵의 위치는 (vx, vy)좌표, 즉, 뷰의 좌표인(view_xview[0], view_yview[0])의 좌표를 기준으로
표시됩니다. 만약, 미니맵의 위치를 변경하고 싶다면, 뷰의 좌표에 위치를 추가하시면 됩니다.
예를 들어 화면의 (32, 320) 위치에 미니맵을 표시하고 싶다면, (view_xview[0]+32,view_yview[0]+320)
위치에 미니맵을 표시하세요.
예)
var _w,_h,vx,vy,vw,vh;
vx=view_xview[0]+32;//변경된 좌표
vy=view_yview[0]+320;//변경된 좌표
_w=minimap_width;
_h=minimap_height;
c=c_dkgray;draw_rectangle_color(vx,vy,vx+_w,vy+_h,c,c,c,c,0);//미니맵 바탕
c=c_gray;draw_rectangle_color(vx,vy,vx+_w,vy+_h,c,c,c,c,1);//미니맵 외곽선
다음은 뷰의 위치와 크기를 표시해볼까요.
마찬가지로 Draw이벤트에서, 위의 내용 밑에 아래와 같이 추가합니다.
★ obj_ctrl_sys - Draw 이벤트 _px=(view_xview[0]*_w)/room_width; _py=(view_yview[0]*_h)/room_height; _pw=(view_wview[0]*_w)/room_width; _ph=(view_hview[0]*_h)/room_height; c=c_white;draw_rectangle_color(vx+_px,vy+_py,vx+_px+_pw,vy+_py+_ph,c,c,c,c,1); |
흰색의 사각형모양으로 뷰의 크기와 위치를 확인할 수 있게 만들었습니다.
뷰의 위치와 크기를 미니맵 크기로 환산하자면 아래와 같은 식으로 구할 수 있습니다.
값=(실제 변동하는 크기X환산할 최대치)/실제 최대 크기
예를 들면 미니맵의 넓이가 160일때 룸 넓이(room_width)를 기준으로 뷰의 x좌표를 미니맵 크기로 환산한다면
값=(view_xview*160)/room_width
이렇게 됩니다. 간단하죠. 헤헤~
이제 이 식으로 유닛의 위치도 표시해보도록 해요.
Draw 이벤트에 아래와 같이 추가하여, 유닛들의 위치를 표시하도록 합니다.
★ obj_ctrl_sys - Draw 이벤트 with(obj_player){ if x>0 && y>0 && x<room_width && y<room_height{//룸 내에 있을 때만 표시함. _x=(x*_w)/room_width; _y=(y*_h)/room_height; draw_point_color(vx+_x,vy+_y,c_yellow);//플레이어는 노란색 }} with(obj_enemy){ if x>0 && y>0 && x<room_width && y<room_height{ _x=(x*_w)/room_width; _y=(y*_h)/room_height; draw_point_color(vx+_x,vy+_y,c_red);//적은 붉은 색 }} |
이것은 유닛이 룸 내에 있을 때만 위치를 표시하게 됩니다.
룸 밖에 있을 때도 표시한다면 미니맵에서 벗어나 보기에 안 좋겠지요.
표시색은 되도록이면 눈에 잘보이는 색으로 표시하도록 해요.
◈미니맵에서 드래그해 뷰를 이동시키기(obj_ctrl_sys)
다음은 미니맵에서 드래그해 뷰를 이동 시켜 보도록 만들어 보아요.
이 이벤트는 사용자 정의 이벤트(User Defined)를 이용해보도록 하겠습니다.
사용자 정의 이벤트(User Defined)는 이벤트에서 직접 실행시키지 않으면, 이벤트가 발생되지 않지만, 이벤트를
호출하게 되면 바로 실행시킬 수 있는 이벤트입니다.
뭐- 이를테면 대기 이벤트라고 볼 수 있지요.
이벤트 메뉴-> Other -> User Defined -> User 0 이벤트를 추가하고, 아래와 같이 작성합니다.
★ obj_ctrl_sys - User Defined 0 이벤트 var _w,_h,vx,vy,vw,vh,mx,my; vx=view_xview[0];//미니맵의 표시 기준점 vy=view_yview[0];//미니맵의 표시 기준점 vw=view_wview[0]; vh=view_hview[0]; mx=mouse_x; my=mouse_y; _w=minimap_width; _h=minimap_height; //뷰 드래그 if mx>vx && my>vy && mx<vx+_w && my<vy+_h && pressed=0{//마우스 포인터가 미니맵 안에 있을 때 _x=floor(((mx-vx)*room_width)/_w); _y=floor(((my-vy)*room_height)/_h); if mouse_check_button(mb_left){ view_xview[0]=max(0,min(_x-(vw/2),room_width-vw)); view_yview[0]=max(0,min(_y-(vh/2),room_height-vh)); } minimap_click=1; } |
이것은 마우스 포인터가 미니맵 안에 있을 때, 그리고 유닛을 선택하려고 드래그 하지 않았을 때 발생하게 합니다.
그리고 뷰의 위치를 미니맵에서 실제 크기로 환산하여 재배치하게 됩니다.
이때 미니맵 안에 있을 때 필드의 상황에 영향을 주지 않도록 minimap_click변수의 값을 1로 만들 놓습니다.
이제 이 이벤트를 End Step이벤트에서 호출 시켜 봅시다.
End Step 이벤트에 아래와 같이 추가합니다.
★ obj_ctrl_sys - End Step 이벤트 //------------------------▼추가 event_user(0); ◀미니맵 이벤트 호출 //------------------------▲추가 var mx,my; mx=mouse_x; my=mouse_y; mbc_L=mouse_check_button(mb_left); mbp_L=mouse_check_button_pressed(mb_left); mbc_R=mouse_check_button(mb_right); //------------------------▼수정 if mbp_L=1 && minimap_click=0{ ◀유닛 선택은 미니맵 밖에 있을 때 발생하도록 변경 //------------------------▲수정 with(obj_player){select=0;} aa=collision_point(mx,my,obj_player,1,1); if !(instance_exists(aa)){mp_x=mx;mp_y=my;pressed=1;} else{with(aa){select=1;}} } //유닛 드래그 선택 var _x1,_y1,_x2,_y2; if pressed=1 && mbc_L=0{ _x1=mp_x;_y1=mp_y; _x2=mx;_y2=my; if mp_x>mx{_x1=mx;_x2=mp_x;} if mp_y>my{_y1=my;_y2=mp_y;} var _sel,_max; _sel=0;_max=12; with(obj_player){if _sel<_max{if x>_x1 && y>_y1 && x<_x2 && y<_y2{ select=1; it=instance_find(obj_unit_position,_sel); if instance_exists(it){it.target=id;} _sel+=1;}}} pressed=0;} //------------------------▼수정 if mbc_R=1 && minimap_click=0{ ◀유닛 선택은 미니맵 밖에 있을 때 발생하도록 변경 //------------------------▲수정 with(obj_player){if select=1{ aa=collision_point(mx,my,obj_player,1,1); bb=collision_point(mx,my,obj_enemy,1,1); if !(instance_exists(bb)){ if !(instance_exists(aa)){ move_on=1; move_x=mx;move_y=my;target=noone; alarm[5]=point_distance(x,y,move_x,move_y)/pspeed; } }else{ move_on=1; move_x=mx;move_y=my;target=bb; alarm[5]=point_distance(x,y,move_x,move_y)/pspeed; } }} } //---------------move pointer-------------- with(obj_unit_position){ if instance_exists(target){ if check=1{ with(target){if select=1{move_x=other.x;move_y=other.y;}} }}else{target=noone;}} //------------------------▼추가 if minimap_click=1{pressed=0;minimap_click=0;}//미니맵 체크를 다시 초기화함 //------------------------▲추가 |
으아아~ 이렇게 보니 복잡해보이네요. 헤헤~
이 설정, 저 설정 넣다보면 느는건 코드양입니다. 전략 게임을 만들다보면 어쩔 수 없는 부분이죠.
이것은 event_user(이벤트 번호)로 사용자 정의 이벤트를 호출할 수 있으며, 호출하는 즉시 이벤트가 발생하게 됩니다.
그리고 미니맵에서 뷰를 드래그하는 것은 유닛 선택부분보다 먼저 발생하도록 처리합니다.
이제 잘되는지 테스트 해봅시다.
◈미니맵을 통한 유닛의 이동(obj_ctrl_sys)
마찬가지로 사용자 정의 이벤트(User Defined)를 이용하도록 합시다.
이벤트 메뉴-> Other -> User Defined -> User 1 이벤트를 추가하고, 아래와 같이 작성합니다.
★ obj_ctrl_sys - User Defined 1 이벤트 var _w,_h,vx,vy,vw,vh,mx,my; vx=view_xview[0];//미니맵의 표시 기준점 vy=view_yview[0];//미니맵의 표시 기준점 vw=view_wview[0]; vh=view_hview[0]; mx=mouse_x; my=mouse_y; _w=minimap_width; _h=minimap_height; //유닛 이동 if minimap_click=1{//미니맵 안에 있고 if mouse_check_button_pressed(mb_right){//마우스 오른쪽 버튼을 눌렀을 때 발생 var _x,_y; _x=((mx-vx)*room_width)/_w; _y=((my-vy)*room_height)/_h; with(obj_unit_position){check=1; x=_x+irandom_range(-8,8); y=_y+irandom_range(-8,8);} with(obj_player){if select=1{ move_on=1; move_x=_x;move_y=_y;target=noone; alarm[5]=point_distance(x,y,_x,_y)/pspeed; }} }} |
저번 강좌에서 이동 설정에 대해 해보았죠?
넵. 그것과 같은 것입니다.
조금 다르다면 목표물(target) 설정이 없다는 것뿐이죠.
미니맵에서 실제크기로 좌표를 환산하여, 유닛 포지션 오브젝트(obj_unit_position)의 위치를 지정해주고, 선택된
유닛들의 위치도 지정하여 이동 시키는 것입니다.
이제 이 이벤트를 End Step이벤트에서 호출 시켜 봅시다.
End Step 이벤트에 아래와 같이 추가합니다.
★obj_ctrl_sys - End Step 이벤트 //------------------------미니맵 event_user(0); //------------------------미니맵 var mx,my; mx=mouse_x; my=mouse_y; mbc_L=mouse_check_button(mb_left); mbp_L=mouse_check_button_pressed(mb_left); mbc_R=mouse_check_button(mb_right); if mbp_L=1 && minimap_click=0{ with(obj_player){select=0;} aa=collision_point(mx,my,obj_player,1,1); if !(instance_exists(aa)){mp_x=mx;mp_y=my;pressed=1;} else{with(aa){select=1;}} } //select var _x1,_y1,_x2,_y2; if pressed=1 && mbc_L=0{ _x1=mp_x;_y1=mp_y; _x2=mx;_y2=my; if mp_x>mx{_x1=mx;_x2=mp_x;} if mp_y>my{_y1=my;_y2=mp_y;} var _sel,_max; _sel=0;_max=12; with(obj_player){if _sel<_max{if x>_x1 && y>_y1 && x<_x2 && y<_y2{ select=1; it=instance_find(obj_unit_position,_sel); if instance_exists(it){it.target=id;} _sel+=1;}}} pressed=0;} if mbc_R=1 && minimap_click=0{ with(obj_player){if select=1{ aa=collision_point(mx,my,obj_player,1,1); bb=collision_point(mx,my,obj_enemy,1,1); if !(instance_exists(bb)){ if !(instance_exists(aa)){ move_on=1; move_x=mx;move_y=my;target=noone; alarm[5]=point_distance(x,y,move_x,move_y)/pspeed; } }else{ move_on=1; move_x=mx;move_y=my;target=bb; alarm[5]=point_distance(x,y,move_x,move_y)/pspeed; } }} } //-----------------------▼삽입 event_user(1); ◀미니맵 클릭 이벤트 호출 //-----------------------▲삽입 //---------------move pointer-------------- with(obj_unit_position){ if instance_exists(target){ if check=1{ with(target){if select=1{move_x=other.x;move_y=other.y;}} }}else{target=noone;}} //------------------------minimap if minimap_click=1{pressed=0;minimap_click=0;} //end |
캬아~ 길다~
위의 위치에 호출 이벤트를 한줄 삽입하시면 됩니다.
이렇게 하면 미니맵을 클릭했을 때 선택된 유닛이 해당 좌표로 이동해요.
와우~! 드디어 미니맵이 완성되었습니다.
테스트! 테스트를 해봅시다. 하악~!
(▲테스트 화면)
후아~ 강좌는 여기까지입니다.
기초적인 부분만 설명했으나, 강좌가 많이 복잡했는데, 재미있으셨는지 모르겠네요.
이제 여러분이 이 강좌를 토대로 응용하셔서 게임을 제작하시면 됩니다.
어째든 재미있는 게임을 만들어 보도록 해요. 아자~!^^
- 끝 -
--------- 예 제 --------
'GameMaker강좌[GM8] > 전략게임강좌' 카테고리의 다른 글
[게임메이커강좌-디펜스]간단한 디펜스게임 만들기-3-스테이지 클리어 (14) | 2013.12.02 |
---|---|
[게임메이커강좌-전략]RTS 게임 만들기 - 4 적 유닛 (17) | 2013.07.02 |
[게임메이커강좌-전략]RTS 게임 만들기 - 3 유닛 공격 (25) | 2013.07.01 |
[게임메이커강좌-전략]RTS 게임 만들기 - 2 유닛 이동 (14) | 2013.06.30 |
[게임메이커강좌-전략]RTS 게임 만들기 - 1 유닛 선택 (35) | 2013.06.29 |
댓글