2019년 10월 6일 일요일

GMS2 GameMaker Studio 2 로 슈팅 게임 만들기 (5) (Let's Make shooting game)


0. 목차


슈팅 게임의 기초 - 배경 스크롤
다중 배경 스크롤
주인공 object
ON Screen Jog
적 object
적 탄환
boss object
boss 탄환
Timelines 사용
Paths 사용
Player 입장 구현
Player 퇴장 구현
우주 배경 배경 스크롤

1. BOSS 소개

boss object는 oBossSky로 이름 지었습니다. 대게의 반쪽을 형상화하여 제작되었습니다. 그리고 주인공이 가까이 있을때는 3발의 탄환을 발사하며 멀리있을 경우 다수의 탄환을 발사하도록 제작하였습니다.

oBossSky의 step 코드 입니다. state가 일정 시간이 흐르면 need_to_change_state flag가 true가 되면서 다음 state로 변환하게 하는 state machine구조를 가지고 있습니다.
if( need_to_change_state ){
 // change state
 // last state
 // change the state as the last state
 switch(state){
  case SM_WALK:
  case SM_WLKR:
  case SM_WLKL:
   state = choose(SM_WALK,SM_WALK,SM_FIRE);
  break;
  case SM_FIREWAIT:
  case SM_FIRE:
   state = SM_WALK;
  break;
 }
 
 // enter state for init code
 speed = 0
 direction = 0
 state_count = 0
 switch(state){
  case SM_WALK:
   state_count_max = 90;
   if( state_save!=SM_WALK && state_save != -1 ){
    state = state_save;
   }
   if( instance_exists(oPlayerSky) ){
    if( oPlayerSky.x > x ){
     facing=-1;
    }else{
     facing=1;
    }
   }
  break;
  case SM_JUMP:
   state_count_max = 120;
  break;
  case SM_STAY:
   vx=0;
   state_count_max = 30;
  break;
  case SM_FIRE:
   state_save = prev_state;
   state_count_max = 10;
   vx=0;
  break;
 }
 
 need_to_change_state = false
}



// action
state_count++;

if (state==SM_STAY) {
}

if (state==SM_FIRE) {
 if( state_count > state_count_max ){
  if( instance_exists(oPlayerSky) ){
   var obj;
   if(distance_to_object(oPlayerSky)<50){
    obj = instance_create_layer(x,y-10,"Instances_Ammo",oEBulletTriSp);
   }else{
    obj = instance_create_layer(x,y-10,"Instances_Ammo",oEBulletMulti);
   }
   var dir = 0;
   if( facing == 1 ) dir = 180;
   else dir = 0;
   var gp = gun_power;
   with(obj){
    gun_power = gp;
    speed     = 5;
    direction = dir;
   }
   state_count = 0;
   state=SM_FIREWAIT;
  }
 }
}

이때 boss의 탄환은 SM_FIRE 에서 구현을 하였으며, 주인공과 거리가 50 이상이냐 이하 이냐에 따라서 다른 총알을 생성 하도록 구현하였습니다.

   if(distance_to_object(oPlayerSky)<50){
    obj = instance_create_layer(x,y-10,"Instances_Ammo",oEBulletTriSp);
   }else{
    obj = instance_create_layer(x,y-10,"Instances_Ammo",oEBulletMulti);
   }

2. Bullet object

oEBulletMulti, oEBulletTriSp 두개 모두 구현 방식은 동일합니다.
핵심은 alarm[0] 이벤트이며 코드는 아래와 같습니다. -4 ~ 4 까지 9개의 탄환이 발사 됩니다. 그리고 자기 자신은 소멸합니다.

var i;
for(i=-4;i<=4;i++){
 var obj = instance_create_layer(x,y,"Instances_Ammo",oEBullet);
 var spd = speed;
 var dir = direction;
 //var gp = gun_power;
 with(obj){
  //gun_power = gp;
  speed     = spd;
  direction = dir+10*i;
  image_angle = dir+10*i-90;
 }
}

instance_destroy()

3. Boss 출동

object를 모두 만들었으면, 해당 object를 실행시키는 곳을 고민해야합니다.

그것은 바로 timelines에 넣으면 됩니다.
boss니 미지막에 넣으면 될것입니다. moment 2200을 마지막으로 두었기 때문에 그곳에 boss를 생성하는 코드를 넣습니다.

var inst = instance_create_layer(0,0,"Instances_Boss",oBossSky);
with(inst){
 path_start(pSky_B1_enter, 1, path_action_stop, true);
 pathinfo[0]=pSky_B1_move1;
 pathinfo[1]=pSky_B1_move1;
 pathinfo[2]=pSky_B1_move2;
}

이때 단순히 boss obeject를 넣는것이 아니라 boss도 어떤 움직임을 따라서 움직여야 합니다. 이것을 위해서 두개의 path를 만들었고 입장을 위해서도 한개의 path를 만들었습니다.
입장용 입니다. pSky_B1_enter


위 두개의 path는 random으로 선택되어집니다.

선택되는 코드는 oBossSky 의 path ended 이벤트에서 아래와 같이 구현하였습니다.

len = array_length_1d(pathinfo);

path_start(pathinfo[irandom(len-1)], 1, path_action_stop, false);

주의할점음 두개의 path가 입장점으로 돌아오도록 제작하여야 합니다. 그래야 랜덤으로 돌았을때 반복적으로 호출해도 동작이 어색하지 않게 됩니다.

4. 전체 코드


https://drive.google.com/open?id=1uJsjbFqMaDRo-uf7goB21VfuR23DDSFh



댓글 없음:

댓글 쓰기