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

[게임메이커강좌-슈팅]탑뷰 슈팅게임 만들기-2-적의 구성 및 공격

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

 

 

GAME MAKER 강좌

 

 

KAYAN

 

 

 

이번 강좌에서는 적의 구성 및 공격에 대해 설정해보도록 합시다.

 

 

(▲ 적과 공격 설정)

 

 

 

 

 

 

 

◈플레이어의 공격(obj_bullet)

 


먼저 플레이어의 공격을 만들어 봅시다.

 

 

(▲ 플레이어의 공격)


플레이어의 공격은 마우스 왼쪽 버튼을 눌렀을 때, 마우스 포인터가 위치한 방향을 향해 총알을

발사하게 됩니다.

 

 

(▲ 마우스 포인터를 향해 발사)


일단 총알로 사용할 이미지를 준비해 스프라이트(spr_bullet1)로 구성하도록 해요.

 

 

(▲ 총알 이미지)


그리고 스프라이트의 중심점을 설정합니다.

 

(▲ 총알 스프라이트)


불규칙한 총알의 모양이나 원래 이미지보다 다르게 마스크를 설정하려면 Modify Mask 를 눌러

마스크를 설정하도록 해요.

이제 총알로 사용할 오브젝트를 하나 만들고 Sprite 에 준비한 총알 스프라이트 이미지를 지정합니다.

 

 

(▲ 총알 오브젝트)


그리고 depth(오브젝트의 깊이)를 설정해주세요.
총알 오브젝트가 플레이어 밑에서 생성되게 하려면 플레이어의 depth 보다 크게 설정하면 되고,

플레이어보다 위에 생성되게 하려면 플레이어 depth 보다 낮게 설정하시면 됩니다
강좌에서는 플레이어 밑에 생성되도록 하겠습니다.

총알은 이동 방향에 따라 이미지가 회전을 해야겠지요.
Step 이벤트image_angle 변수를 사용해 이미지를 회전하도록 설정합니다.

 



     ★ obj_bullet - Step 이벤트

     image_angle=direction;



총알이 화면 밖으로 나갔을 때는 총알을 파기해야합니다.
파기 하지 않게 되면, 총알 오브젝트가 누적되어 게임이 느려질 수가 있어요.
그렇기 때문에 의도한 임무를 마친 오브젝트는 파기하여 게임 플레이가 원활하도록 만들어야 합니다.
룸 밖으로 나갔을 때 파기하려면, 이벤트 메뉴OtherOutside room 이벤트를 사용하시면 되고,

만약 뷰 밖으로 나갔을 때는  이벤트 메뉴OtherViewsOutside view 이벤트를 사용하시면

됩니다.
강좌에서는 Outside View 이벤트를 사용하여, 화면(뷰) 밖으로 나갔을 때 파기하도록 하겠습니다.

 



     ★ obj_bullet - Outside View 0 이벤트

     instance_destroy();



이렇게 하면 화면(뷰) 밖으로 총알이 나갔을 때, 파기 하게 됩니다.

총알에 잔상이라도 남기게 만들어 볼까요.

 

 

(▲ 잔상 효과)


잔상을 만들기 위해 이펙트용 오브젝트(obj_effect)를 하나 만듭시다.

이펙트로 표시되는 스프라이트는 생성할 때 변경 가능하니, 지정하고 싶은 이미지로 지정하셔도 됩니다.

강좌에서 오브젝트에 지정한 기본 Sprite 는 총알과 같은 스프라이트 이미지를 지정했습니다.

 

 

(▲ 이펙트 오브젝트)


그리고 Create 이벤트를 추가하고, 이펙트에 필요한 변수들을 선언하도록 해요.

 



     ★ obj_effect - Create 이벤트

     subimg=0;//스프라이트의 서브이미지

     scale=1;//이미지 확대치
     angle=0;//이미지 회전
     alpha=1;//투명도

     fade_spd=0.05;//투명도 감소치



강좌에서는 간단하게 확대치, 회전값, 투명도 설정에 관련된 변수들로 구성하도록 하겠습니다.

이제 Draw 이벤트를 추가하고 이미지를 표시합니다.

 



     ★ obj_effect - Draw 이벤트

     draw_sprite_ext(sprite_index,subimg,x,y,scale,scale,angle,c_white,alpha);



이것은 Create 이벤트에서 선언한 확대치, 회전값, 투명도 변수를 적용한 것입니다.

이 오브젝트가 룸에 계속 남아 있으면 안되니, 파기 이벤트를 구성해야겠지요.
강좌에서는 투명도가 0이 되었을 때, 파기하도록 하겠습니다. Step 이벤트를 추가하고 이벤트를

작성하도록 해요.

 



     ★ obj_effect - Step 이벤트

     if alpha>0{alpha-=fade_spd;}else{instance_destroy();}



이렇게 하면 투명도가 점점 감소되다, 0이 되면 이펙트 오브젝트를 파기하게 됩니다.

이펙트 오브젝트가 완성되었습니다.
다시 총알 오브젝트(obj_bullet)Step 이벤트로 이동해서, 준비한 이펙트 오브젝트를 이용해

잔상을 생성하도록 해요.

 



     ★ obj_bullet - Step 이벤트

     aa=instance_create(x,y,obj_effect);
     aa.depth=depth+1;//이펙트 생성 깊이(총알 오브젝트 밑에 생성되도록 함)
     aa.angle=direction;//이펙트 회전
     aa.sprite_index=sprite_index;//이펙트에 총알과 같은 스프라이트 이미지를 지정
     aa.fade_spd=0.1;//투명도 감소치



이렇게 하면 총알을 생성했을 때, 잔상을 남기게 됩니다.

이제 이 총알 오브젝트를 플레이어 오브젝트에서 마우스 왼쪽 버튼을 눌렀을 때 생성되도록 만듭시다.
먼저 공격을 할 때, 재공격간에 약간의 딜레이를 주도록 합시다.
Create 이벤트에 딜레이용 변수를 추가합니다.

 



     ★ obj_player - Create 이벤트

     att_sw=0;



딜레이 처리는 알람 이벤트를 이용하면 편합니다.

사용할 알람 이벤트(Alarm 0)를 추가하고, 공격 딜레이용 변수를 초기화시킵니다.

 



     ★ obj_player - Alarm 0 이벤트

     att_sw=0;



이제 총알 오브젝트(obj_bullet)을 발사하도록 이벤트를 구성해요.
이벤트 메뉴MouseGlobal mouseGlobal left button 이벤트를 추가하고 이벤트를

작성합니다.

 



     ★ obj_player - Global left button 이벤트

     if att_sw=0{//공격 변수가 0일때 총알 오브젝트를 생성

     aa=instance_create(x,y,obj_bullet);
     aa.direction=point_direction(x,y,mouse_x,mouse_y)+random_range(-5,5);//공격 방향. 정확도 오차는 10도
     aa.speed=8;

     att_sw=1;
     alarm[0]=10;//공격 변수를 초기화(재공격간의 지연시간)

     }



이렇게 하면 마우스 버튼을 눌렀을 때 총알을 발사하게 됩니다.
강좌에서 방향은 random_range를 사용해 약간 부정확하게 발사하도록 설정했는데, 정확하게

발사시키고자 한다면 point_direction(x,y,mouse_x,mouse_y)만 적용하시면 됩니다.

 

     예) 총알의 방향이 마우스 포인터 방향으로 정확하게 발사시키는 경우

 

 

 

 



     ★ obj_player - Global left button 이벤트(정확한 방향)
     if att_sw=0{

     aa=instance_create(x,y,obj_bullet);
     aa.direction=point_direction(x,y,mouse_x,mouse_y);//◀오차 없도록 정확한 방향으로 설정
     aa.speed=8;

     att_sw=1;
     alarm[0]=10;

     }



이런 식으로 방향에 random_range 를 빼면 총알 오브젝트가 정확한 방향으로 일정하게 발사 됩니다.

여러분의 취향에 맞게 설정하세요.

 

 

 

여기까지!

일단 설정한대로 제대로 되는지 테스트 해봅시다.
다음은 적을 한번 만들어 봅시다.





◈ 적 구성(obj_enemy, obj_en1)

 


먼저 적을 구성할 이미지를 준비해 스프라이트로 구성하도록 해요.

 

 

(▲ 적 이미지)


강좌에서는 플레이어 이미지에서 색만 변경한 붉은색 드래곤 이미지를 준비했습니다.

 

 

(▲적 스프라이트)


그리고 중심점을 맞추고, Modify Mask 버튼을 누르고 마스크를 설정하도록 해요.

이제 적을 구성하기 위에 오브젝트(obj_en1)를 하나 만들고, Sprite에 준비한 이미지를 지정하도록 해요.
적이 여럿이면 아래와 같이 parent 오브젝트를 만드는 것이 좋습니다.

 

     obj_enemy(parent 오브젝트) - obj_en1, obj_en2, obj_en3 ...(실제 배치되는 오브젝트)

 

(▲ 적 오브젝트)

 

이렇게 하면 충돌이벤트나 적 오브젝트 호출시 따로 처리하지 않아도 parent 오브젝트만 호출하면 쉽게

처리할 수 있기 때문입니다

 

[중요]

간혹 parent 오브젝트로 이벤트에서 사용했을 때, 정작 룸에 배치되는 오브젝트에 parent 설정에

지정하지 않아 인식을 못한다고 말씀을 하시는 분들이 종종 있지요.

이벤트에서 parent 오브젝트로 처리할 경우, 룸에 배치되는 오브젝트는 반드시 [Parent 설정에

parent 오브젝트를 지정]해야 정상적으로 처리됩니다.


현재 만들고자 하는 적 유닛은 플레이어가 공격 범위 안에 있으면 플레이어의 위치를 향해 이동하는 적입니다.

적 오브젝트(obj_en1)Create 이벤트를 추가하고, 플레이어와 같이 체력이나, 이동 속도와 같은

필요한변수들을 선언하도록 해요.

 



     ★ obj_en1 - Create 이벤트

     hp=30;//체력
     hp_max=hp;//최대 체력

     pspeed=1;//이동 속도

     att_sw=0;//공격 변수
     att_range=640;//공격 범위
     att_min=96;//공격 최소 범위(이동 관련)

     image_speed=0.3;//애니메이션 속도



이제 공격 범위에 들어온 플레이어 방향으로 적 오브젝트를 이동하게 만들어 봅시다.
Step 이벤트를 추가하고, 이벤트를 구성해요.

 



     ★ obj_en1 - Step 이벤트

     if instance_exists(obj_player){//플레이어가 있을 때, 이벤트를 작동하도록 함
     target=instance_nearest(x,y,obj_player);//가까운 플레이어 오브젝트를 찾음

     dist=distance_to_object(target);//플레이어와의 거리를 측정
     if att_range>dist{//플레이어가 공격 범위에 있는가?

     //---------- 이 동 ---------
     if dist>att_min{move_towards_point(target.x,target.y,pspeed);}
     else{friction=0.01;direction=point_direction(x,y,target.x,target.y);}

     }
     }

     image_angle=direction;//방향대로 캐릭터 이미지를 회전



이렇게 하면 플레이어가 범위에 들어왔을 때, 적 오브젝트는 플레이어의 위치를 향해 이동하게 됩니다.
그리고 캐릭터 이미지는 이동하는 방향에 따라 변하게 됩니다.

체력이 0이 되었을 때, 파기 이벤트도 추가해봅시다.
Step 이벤트에서 바로 추가해도 되지만, 강좌에서는 찾기 쉽도록 End Step 이벤트에서 작성하도록

하겠습니다.

 



     ★ obj_en1 - End Step 이벤트

     if hp<=0{hp=0;instance_destroy();}



이렇게 하면 체력(hp)가 0이 되었을 때, 파기됩니다.

다음은 아래와 같이 적의 공격을 만들어 봅시다.

 

 

(▲ 적의 공격)


적의 공격을 만들기 위해 총알 이미지를 준비하세요.

강좌에서는 원형 이미지로 단순하게 만들었습니다.

 

 

(▲ 적의 총알이미지)


스프라이트로 구성하고, 중심점을 맞추도록 해요.

 

 

(▲ 총알 스프라이트)


마스크 설정이 필요하다면 Modify Mask 버튼을 눌러 마스크를 설정하시면 됩니다.

이제 적의 총알로 사용할 오브젝트(obj_bullet)를 하나 만들고, Sprite 에 준비한 이미지를 지정합니다.

 

(▲ 총알 오브젝트)


적 오브젝트 밑에 생성되게 하려면 depth를 적 오브젝트보다 높게 설정하시면 됩니다.

다음은 플레이어(obj_player)와 충돌 이벤트를 추가하고, 플레이어의 체력(hp)을 감소시키는 이벤트를
구성해야합니다.

 



     ★ obj_en_bullet - obj_player 와의 충돌 이벤트

     other.hp-=5;//플레이어의 체력 감소
     instance_destroy();//이벤트 실행 후 총알 오브젝트는 파기



이것은 적의 총알 오브젝트가 플레이어와 충돌했을 때, 플레이어의 체력을 감소시키고, 오브젝트를

파기하는 것입니다.
플레이어와 충돌 했을 때, 기본 이펙트라도 생성되게 만들어 볼까요.

 



     ★ obj_en_bullet - obj_player 와의 충돌 이벤트

     other.hp-=5;

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

     effect_create_above(ef_explosion,x,y,0.2,c_white);//기본 이펙트 생성

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

     instance_destroy();


 

이렇게 하면 아래의 화면처럼, 적의 총알 오브젝트가 플레이어와 충돌했을 때, 이펙트를 발생하게

됩니다.

 

 

(▲ 적의 공격)


플레이어의 총알과 마찬가지로 룸이나 화면 밖으로 나갔을 때는 파기하도록 이벤트를 추가해야 합니다.

룸 밖으로 나갔을 때 계속 남아있게 되면 필요 없는 총알 오브젝트가 누적되어 게임이 느려지겠지요.
게임특성에 맞게 이벤트를 구성하시면 되는데, 강좌에서는 룸 밖으로 나갔을 때 파기하도록 하겠습니다.

이벤트 메뉴OtherOutside Room 이벤트를 추가하고, 파기 이벤트를 작성해요.

 



     ★ obj_en_bullet - Outside Room 이벤트

     instance_destroy();



이제 적 오브젝트에서 총알 오브젝트를 생성하면 됩니다.
적 오브젝트(obj_en1)로 이동해서 플레어와 마찬가지로 알람 이벤트(alarm 0)를 추가하고,

공격 변수를 초기화하도록 합니다.

 



     ★ obj_en1 - Alarm 0 이벤트

     att_sw=0;



그리고 Step 이벤트에 아래와 같이 추가해요.

 



     ★ obj_en1 - Step 이벤트

     if instance_exists(obj_player){
     target=instance_nearest(x,y,obj_player);

     dist=distance_to_object(target);
     if att_range>dist{

     if dist>att_min{move_towards_point(target.x,target.y,pspeed);}
     else{friction=0.01;direction=point_direction(x,y,target.x,target.y);}

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

     if att_sw=0{//공격 변수가 0일때 총알 오브젝트를 생성

     aa=instance_create(x,y,obj_en_bullet);
     aa.direction=point_direction(x,y,target.x,target.y);//방향은 플레이어 방향
     aa.speed=8;

     alarm[0]=120;//공격 변수를 초기화(재공격 지연시간)
     att_sw=1;
     }

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

     }
     }

     image_angle=direction;



이것은 플레이어가 공격 범위에 들어왔을 때, 플레이어의 위치를 향해 이동하면서 공격을 하게 됩니다.

적들이 플레이어를 향해 이동하다보면, 적 유닛끼리 겹쳐 하나로 뭉쳐버릴 수 있습니다.
그것을 방지하기 위해 겹치지 않도록 떨어뜨려야합니다.
적의 parent 오브젝트(obj_enemy)와의 충돌 이벤트를 추가하고, 아래와 같이 이벤트를 추가해요.

 



     ★ obj_en1 - obj_enemy 와의 충돌 이벤트

     dir=point_direction(x,y,other.x,other.y)+180;
     x+=lengthdir_x(0.5,dir);
     y+=lengthdir_y(0.5,dir);



이렇게 하면 유닛이 겹쳐질 때, 유닛끼리 밀어버리게 됩니다.

적의 공격 설정이 끝났네요.
제대로 되는지 테스트 해봅시다.

앗. 플레이어의 공격(obj_bullet) 설정이 되지 않았지요.
플레이어의 총알 오브젝트(obj_bullet)으로 이동해서 적들의 parent 오브젝트(obj_enemy)와의

충돌 이벤트 추가하고, 공격 이벤트를 작성해요.

 



     ★ obj_bullet - obj_enemy 와의 충돌 이벤트

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



이제 다시 테스트 해봅시다.

 

 

 


음. 적 유닛이 파기될때 그냥 파기되니 허전해보이는군요. 아래의 화면처럼 이펙트라도 생성하도록

합시다.

 

 

(▲ 파기 이펙트)


Destroy 이벤트를 추가하고 이펙트를 생성합니다.

 



     ★ obj_en1 - Destroy 이벤트

     effect_create_above(ef_explosion,x,y,1,c_red);



플레이어 유닛도 마찬가지로 파기 되었을 때, 이펙트를 생성하도록 이벤트를 추가해요.

 



     ★ obj_player - Destroy 이벤트

     effect_create_above(ef_explosion,x,y,1,c_red);



와우! 이제 슈팅 게임의 기본틀이 완성되었네요.
지금까지 설정한 이벤트들이 제대로 작동되는지 테스트 해봅시다.

 

 

(▲ 테스트 화면)




- 계속 -

 

 

 


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

 

topview_ex2.exe
다운로드

 

topview_ex2.gmk
다운로드

 

 

300x250

댓글