본문 바로가기
GameMaker강좌[GM8]/슈팅게임강좌

[게임메이커강좌-슈팅]탑뷰 슈팅게임 만들기-3- 체력 정보 표시

by 타락카얀 2014. 4. 24.
728x90

 

 

GAME MAKER 강좌

 

 

KAYAN

 

 

이번 강좌에서는 체력을 표시하는 방법에 대해 알아보도록 합시다.

 

 

(▲ 게임 화면)

 

 

 

 

 

 

 

 

 

◈체력 표시(obj_screen)

 


아래 화면은 강좌에서 만들 정보 화면입니다.

 

 

(▲ 체력 표시)


왼쪽 상단이 플레이어 체력이고, 오른쪽 상단은 플레이어가 적을 공격했을때 데미지를 입은 적의

체력이에요.
그리고 아래쪽은 룸 상에 있는 적들의 체력을 모두 합한 체력이지요.

이번 강좌에서는 이 정보들을 표시하는 방법에 대해 알아 볼 거에요.

일단 플레이어의 체력으로 표시할 이미지를 준비하도록 해요.

 

 

(▲ 체력 이미지)


강좌에서는 3가지 이미지를 준비했습니다.
첫번째는 체력바의 뒷 배경으로 사용하고, 두번째는 체력 변동에 관련된 이미지, 세번째는 체력바의

외곽선으로 표시할 것입니다.
이렇게 구성하여 스프라이트(spr_bar_240)로 만듭니다.

 

 

(▲ 체력 스프라이트 240 X 16)


다음은 적의 종합 체력으로 표시할 이미지를 준비해봅시다.

 

 

(▲ 체력 이미지)


그리고 스프라이트(spr_bar_320)로 구성해요.

 

 

(▲ 체력 스프라이트 320 X 16)


강좌에서는 이렇게 2가지 스프라이트를 사용해 표시할 것입니다.

이제 체력을 표시해야 겠지요.
오브젝트(obj_screen)를 하나 만들도록 해요.

 

 

(▲ 정보를 표시하게 될 오브젝트)


그리고 정보를 화면 맨 앞에 표시되야 하니, depth를 다른 오브젝트들 보다 낮게 설정하세요.

먼저 플레이어의 체력부터 표시해보도록 합시다.
체력 표시의 기본 식은 아래와 같습니다.

     표시값 = 체력 X 화면에 표시할 최대 크기 X (1/최대 체력)

 

이 식을 응용하여 draw_sprite_part_ext 함수를 통해 체력의 변화를 표시할 것입니다.

 

     draw_sprite_part_ext(sprite,subimg,left,top,width,height,x,y,xscale,yscale,color,alpha)

 

     sprite : 스프라이트

     subimg : 스프라이트의 서브이미지

     left : 왼쪽 기준점(스프라이트 이미지에서)

     top : 위쪽 기준점(스프라이트 이미지에서)

     width : 기준점으로 부터의 넓이

     height : 기준점으로 부터의 높이

     x : 표시할 x좌표

     y : 표시할 y좌표

     color : 혼합 색

     alpha : 투명도

 

draw_sprite_part_ext 함수는 스프라이트 이미지를 그대로 표시하는 것이 아닌 일부분을 잘라서

표시할 때 사용하는 것입니다.

스프라이트에서 잘라 표시할 때 (left, top)는 기준점(룸에서 기준점이 아니라, 스프라이트 이미지에서

기준점. 왼쪽 상단은 0,0)이 되며, (width, height)는 어느정도 크기로 잘라 표시할 지를 지정하게 됩니다.


Draw 이벤트를 추가하고, 위 식을 통해 체력 표시 이벤트를 작성해요.

 



     ★ obj_screen - Draw 이벤트

     var vx,vy,vw,vh;
     vx=view_xview; //뷰의 x좌표
     vy=view_yview; //뷰의 y좌표
     vw=view_wview; //뷰의 넓이
     vh=view_hview; //뷰의 높이


     with(obj_player){
     _p=hp*240*(1/hp_max); //플레이어의 체력 표시값
     draw_sprite_ext(spr_bar_240,0,vx+32,vy+32,1,1,0,c_white,1); //뒷배경
     draw_sprite_part_ext(spr_bar_240,1,0,0,_p,16,vx+32,vy+32,1,1,c_white,1); //체력
     draw_sprite_ext(spr_bar_240,2,vx+32,vy+32,1,1,0,c_white,1); //외곽선
     }



일반적으로 그냥 좌표만 사용해 표시했을 때, 룸이 뷰보다 크면 화면에 고정되지 않지요.
이 때는 위와 같이 뷰의 좌표를 사용하여 표시해야 화면에 고정할 수 있습니다.

플레이어의 체력이 제대로 표시되는지 테스트 해봅시다.

 

 

(▲ 플레이어의 체력)


다음은 플레이어에게 데미지 입은 적의 체력을 오른쪽 상단에 표시해봅시다.
적의 체력을 표시하려면 공격한 적의 id를 알고 있어야 합니다. 그리고 계속 표시하는 것보다 몇 초

정도만 표시하는 것이 좋겠죠.
Create 이벤트를 추가하고, 여기에 필요한 변수들을 선언하도록 해요.

 



     ★ obj_screen - Create 이벤트

     global.target_id=noone; //데미지 입은 적
     global.target_reset=0; //표시 시간



다음은 플레이어의 총알 오브젝트(obj_bullet)으로 이동해서 적과의 충돌이벤트에 플레이어의 총알이

데이지 입힌 적의 id를 얻을 수 있도록 이벤트를 추가합니다.

 



     ★ obj_bullet - obj_enemy와의 충돌 이벤트

     other.hp-=5;
     effect_create_above(ef_explosion,x,y,0.2,c_white);

     //------------ ▼ 이벤트 추가

     global.target_id=other.id; //적의 id를 저장
     global.target_reset=90; //표시 유지 시간

     //------------ ▲ 이벤트 추가

     instance_destroy();



이렇게 하면 플레이어의 총알이 적과 충돌시, 충돌한 적의 idglobal.target_id 변수에 저장하게 됩니다.

그리고 정보 표시 오브젝트(obj_screen)로 이동해, Draw 이벤트에서 이 적의 id를 이용해 체력을

표시하시면 됩니다.

 



     ★ obj_screen - Draw 이벤트

     var vx,vy,vw,vh;
     vx=view_xview;
     vy=view_yview;
     vw=view_wview;
     vh=view_hview;


     with(obj_player){
     _p=hp*240*(1/hp_max);
     draw_sprite_ext(spr_bar_240,0,vx+32,vy+32,1,1,0,c_white,1);
     draw_sprite_part_ext(spr_bar_240,1,0,0,_p,16,vx+32,vy+32,1,1,c_white,1);
     draw_sprite_ext(spr_bar_240,2,vx+32,vy+32,1,1,0,c_white,1);
     }

     //------------ ▼ 이벤트 추가

     if instance_exists(global.target_id){
     with(global.target_id){
     _p=hp*240*(1/hp_max);//데미지 입은 적의 체력
     draw_sprite_ext(spr_bar_240,0,vx+320+32,vy+32,1,1,0,c_white,1); //뒷배경
     draw_sprite_part_ext(spr_bar_240,1,0,0,_p,16,vx+320+32,vy+32,1,1,c_white,1); //체력
     draw_sprite_ext(spr_bar_240,2,vx+320+32,vy+32,1,1,0,c_white,1); //외곽선
     }}

     //------------ ▲ 이벤트 추가



표시 방법은 플레이어 표시와 같습니다.
그리고 표시 유지 시간을 처리하는 이벤트가 필요하지요.

Step 이벤트를 추가하고, 이벤트를 작성하도록 해요.

 



     ★ obj_screen - Step 이벤트

     if global.target_reset>0{global.target_reset-=1;} //표시 시간 처리
     else{
     global.target_id=noone; //표시 시간이 끝났을 때, 적의 id를 기록한 변수는 초기화
     global.target_reset=0;
     }


     if !(instance_exists(global.target_id)){ //적이 룸에 없을 때 변수 초기화
     global.target_id=noone;
     global.target_reset=0;
     }



이것은 표시 시간이 0보다 크면 감소 시키고, 시간이 다되면 id를 저장한 변수를 초기화시킵니다.

여기까지 제대로 작동하는지 테스트 해봅시다.


다음은 적들의 총 체력을 하단에 표시하는 방법에 대해 알아보도록 합시다.
이 체력은 현재 어느정도의 게임 진행을 했는지 플레이어들에게 알려주기 위한 정보입니다.
물론 다른 방법도 있겠지만, 강좌에서는 적들의 체력들을 모두 합한 값으로 어느정도 게임을 진행했는지

또는 얼만큼 진행해야 게임이 클리어 되는지 표시할 것입니다.
정보 표시 오브젝트(obj_screen)Create이벤트에 적들의 체력을 계산하는데 필요한 변수들을

선언하도록 해요.

 



     ★ obj_screen - Create 이벤트

     global.enemy_total_hp=0;
     global.enemy_hp=0;



적들의 체력 총 합계는 한번만 체크해야합니다.
그러기 위해서 먼저 적 유닛(obj_en1)Create 이벤트를 추가하고, 체크용 변수를 선언하도록 해요.

 



     ★ obj_en1 - Create 이벤트

     id_check=0; //적의 id 체크 변수(적들의 체력 합계시 사용)



이 변수는 최대 체력을 업데이트 할때 사용할 거에요.

다시 정보 표시 오브젝트(obj_screen)으로 이동해 Step 이벤트에서 적들의 체력을 갱신하도록 이벤트를

추가합니다.

 



     ★ obj_screen - Step 이벤트

     global.enemy_hp=0;
     if instance_exists(obj_enemy){
     with(obj_enemy){

     global.enemy_hp+=hp; //적의 체력 갱신

     if id_check=0{

     global.enemy_total_hp+=hp_max;
     id_check=1;} //적의 최대 체력은 한번만 체크함

     }
     }



이것은 룸에 있는 적들의 체력을 갱신하는 것입니다.
변화가 있는 체력은 계속 갱신하고, 최대 체력은 1번만 갱신하도록 하는 것이지요.

이제 Draw 이벤트에 이 체력 표시하면 됩니다.

 



     ★ obj_screen - Draw 이벤트

     //------------ ▼ 이벤트 추가
     _p=0;
     if instance_exists(obj_enemy){
     if global.enemy_total_hp>0{  //체력의 합계가 0보다 클 때 계산함.
     _p=global.enemy_hp*320*(1/global.enemy_total_hp);  //체력 수치
     }
     }

     draw_sprite_ext(spr_bar_320,0,vx+160,vy+vh-32,1,1,0,c_white,1); //뒷배경
     draw_sprite_part_ext(spr_bar_320,1,0,0,_p,16,vx+160,vy+vh-32,1,1,c_white,1); //체력
     draw_sprite_ext(spr_bar_320,2,vx+160,vy+vh-32,1,1,0,c_white,1); //외곽선



이런식으로 하면 갱신된 적들의 체력을 화면에 표시하게 됩니다.
체력 수치 계산시 global.enemy_total_hp 이 0보다 클때의 조건문을 넣은 것은, 적들의 체력을

합산하기 전에 이 이벤트가 실행된다면 0이 될 수도 있는데, 0이 되면 오류가 생길 수 있어

조건문을 더 추가한 것입니다.

여기까지 제대로 표시되는지 확인해보도록 해요.

 

 

 



◈ 스테이지 클리어(obj_screen)

 


다음은 게임 클리어를 만들어보도록 합니다.
강좌에서는 간단하게 적들을 모두 없앴을 때 클리어하는 것으로 하겠습니다.


먼저 Create 이벤트에 클리어용 변수를 선언하도록 해요.

 



     ★ obj_screen - Create 이벤트

     stage_clear=0; //클리어 체크



그리고 Step 이벤트에서 적들의 수를 체크합니다.
클리어했을 때 바로 다음 룸으로 가는 것보다, 알람 이벤트를 이용해 약간의 시간을 두고 이동하는 것이 좋겠죠.

 



     ★ obj_screen - Step 이벤트

     if instance_number(obj_enemy)=0{
     if stage_clear=0{alarm[5]=150;stage_clear=1;}
     }


 

 

룸에 존재하는 적이 없을 때, 알람 이벤트를 활성화시키고 클리어 변수를 1로 만들어 다시 실행하지
못하게 하는 것입니다.

그리고 알람 이벤트에서 다음 룸으로 이동하게 하는 것이지요.

 



     ★ obj_screen - Alarm 5 이벤트

     room_goto_next();



이렇게 하면 적을 모두 소멸시킨 다음, 150 스텝 후 다음 룸으로 이동하게 됩니다.
특정 룸으로 이동하고 싶다면 room_goto(룸 이름) 함수를 사용하세요.

     예) room_goto(title_room)

 

음. 그냥 다음 룸으로 이동한다면 조금 심심하겠지요.
클리어 했다는 정보라도 표시해볼까요.
클리어 했을 때 표시되는 이미지를 준비하도록 해요.

 

 

(▲ 클리어 이미지)


그리고 스프라이트(spr_clear)로 구성합니다. 배치하기 편하도록 중심점은 가운데로 맞췄어요.

 

 

(▲ 클리어 스프라이트)


이제 이것을 어떤 방식으로 표시하는가입니다.
물론 클리어만 표시할 오브젝트를 따로 만들고, 클리어 했을 때 클리어 오브젝트를 생성하셔도 됩니다.
강좌에서는 클리어했을 때 알람 이벤트를 이용해 몇초정도 시간을 두고 이동을 하게 했는데, 알람 이벤트

이용해 표시해보도록 하겠습니다.
알람 이벤트가 실행된다는 것은 당연히 0보다 큰 값에서 카운트하게 된다는 것이지요.

알람 이벤트(Alarm 5)가 0보다 클 때, 클리어 이미지를 표시하는 것입니다.

Draw 이벤트에서 이러한 것을 이벤트로 추가하도록 해요.

 



     ★ obj_screen - Draw 이벤트

     if alarm[5]>0{

     draw_sprite_ext(spr_clear,0,vx+320,vy+240,1,1,0,c_white,1);
     }


이렇게 하면 클리어했을 때 몇 초정도 룸에 머물러 있는동안 클리어 이미지를 표시하게 됩니다.

 

이제 정보 표시까지 완성되었습니다. 굳!
지금까지 설정한 이벤트들이 제대로 작동되는지 테스트 해봅시다.

 

 

(▲ 테스트 화면)

 

여기까지 강좌에서는 슈팅 게임을 어떤 식으로 제작하는지 간단하게 원리 정도만 설명했습니다.

하지만 여기까지 따라해보셨다면 게임메이커를 충분히 다루실 수 있기 때문에, 더 멋진 게임을

만드실 수 있을 것이라 생각합니다.

 

 


- 끝 -


 

-------- 예 제 --------

 

topview_ex3.exe
다운로드

 

topview_ex3.gmk
다운로드


 

 

300x250

댓글