본문 바로가기
GameMaker강좌[GM8]/기타장르강좌

[게임메이커강좌-기타]벽돌 깨기 게임 만들기

by 타락카얀 2013. 7. 31.
728x90

 

 

GAME MAKER 강좌

 

 

KAYAN

 

 

 

 

 

 

◈벽돌 깨기 게임 만들기

 


이번 강좌에선 간단한 벽돌깨기 게임을 만들어 보도록 해요.

 

 

(▲벽돌 깨기 게임)


벽돌 깨기 게임은 여러분도 해보셨겠지만, 만들기 이전에 플레이어를 어떻게 조작하게 할 것인지, 또는 블럭을

어떻게 배치할 것인가, 아이템들, 그리고, 사운드등 어떻게 만들 것인지를 자세하게 구상해 놓는 것이 만들 때 좋습니다.

 

 

 

 

 

 

 

 

 


◈플레이어 설정(obj_player)

 


먼저 플레이어부터 만들어 봅시다.
이미지를 준비하여 스프라이트(spr_player1)를 구성합니다.

 

 

(▲플레이어 이미지)


그리고 중심점은 가운데 맞춥니다.
강좌에서 마스크 설정은 Automatic - Precise로 맞추었어요.

다음은 오브젝트(obj_player)를 하나 만들고, Sprite에 준비한 플레이어 스프라이트를 지정하고 Solid를 체크합니다.

 

 

(▲플레이어 오브젝트)


이제 이 플레이어를 움직이게 해야겠지요.
강좌에서 플레이어는 마우스 포인터를 따라 좌우로 이동 시킬 거에요.
Step 이벤트를 추가하고, 아래와 같이 작성합니다.

 



     ★ obj_player - Step 이벤트

     x=max(32,min(mouse_x,room_width-32));



이렇게 하면 플레이어의 x좌표는 마우스의 포인터를 따라 움직이게 됩니다.
플레이어의 설정이 끝났네요.
잘 움직이는지 룸을 하나 만들고, 플레이어를 배치한 후 테스트 해봅시다.


 

 

 



◈게임의 테두리 블럭

 


다음은 게임의 테두리를 만들어봅시다.
이 테두리 블럭은 볼이 밖으로 나가는 것을 막고, 이 블럭에 닿으면 튕기게 합니다.

 

 

(▲게임의 테두리)


일단 이미지를 준비하여 스트라이트로 구성(spr_wall_h,spr_wall_v)합시다.
강좌에선 가로방향과 세로방향으로 긴 이미지를 준비했습니다만, 더 길어도 되고, 짧아도 됩니다.
아니면 게임 화면에 맞게 통째로 만들어도 됩니다.

 

 

(▲테두리 블럭 가로 이미지)

 

 

(▲테두리 블럭 세로이미지)


이미지를 준비했으니, 룸에 배치할 오브젝트들을 구성해야겠지요.
일단 블럭들의 parent로 사용할 오브젝트(obj_block)를 하나 만듭니다.

 

 

(▲블럭 오브젝트)

 

그리고 실질적으로 배치시킬 하위 오브젝트를 각각 만듭니다.

    obj_block(parent오브젝트)obj_wall_h, obj_wall_v(룸에 배치할 하위 오브젝트)

하위 오브젝트(obj_wall_h, obj_wall_v)들은 parent(obj_block)를 지정하고, solid를 체크해주세요.
이제 이 블럭들을 룸 테두리 부분에 배치시키시면 됩니다.

 

 

 

 

 

 

 

 

◈ 블럭

(obj_block_unit, obj_bl_A, obj_bl_B,obj_bl_C)

 


이제 실질적으로 게임 진행에 사용될 블럭들을 만들어봅시다.
이 블럭들은 볼에 맞게 되면 부숴져버리는 블럭들입니다.

 

 

(▲강좌에서 사용될 블럭 이미지들)

이 블럭들을 만들기 위해 여러 이미지들을 준비하고, 스프라이트(spr_block_A, spr_block_B, spr_block_C)
구성하도록 해요.

강좌에선 색상별로 3종류 준비했습니다. 헤헤~

 

 

(▲블럭 스프라이트)


다음은 블럭들을 제어할 parent(obj_block_unit)를 하나 만듭니다.

 

 

(▲블럭들의 parent)


이 블럭은 다른 블럭들의  parent로 사용되지만, 한번에 제어가능하게 테두리(obj_wall_h, obj_wall_v)에 쓰였던

parent(obj_block) 지정해주도록 합니다.


그리고 실질적으로 배치할 하위 오브젝트들(obj_bl_A, obj_bl_B, obj_bl_C)을 만들고

parent(obj_block_unit)각각 지정해줍니다.

 


 obj_block(parent오브젝트)obj_block_unit(parent오브젝트)obj_bl_A, obj_bl_B,

 obj_bl_C(배치되는 오브젝트)

 

 

 

(▲실질적으로 배치될 블럭 오브젝트. 색만 다르고 동일한 유형의 블럭)


배치되는 오브젝트들의 Sprite에 이전에 준비한 스프라이트를 지정하고, Solid를 체크합니다.

이제 블럭에 대한 이벤트들을 작성해보도록 해요.
블럭들의 첫번째 parent(obj_block)Create 이벤트를 추가하고, 다음과 같은 이벤트를 작성합니다.

 



     ★ obj_block - Create 이벤트

     hp=1;



다음은 두번째 parent(obj_block_unit)Create 이벤트를 추가하고, 다음과 같은 이벤트를 작성합니다.

 



     ★ obj_block_unit - Create 이벤트

     hp=1;



※[참고] parent에 대한 이벤트 설정은 하위 오브젝트가 있는 경우 이벤트들을 그대로 상속시킵니다.
즉, 배치되는것은 하위 오브젝트이나, parent에 설정한 이벤트들을 하위 오브젝트들이 똑같이

실행시키는 것이죠.

다만, 주의할 것은 하위 오브젝트에 parent와 같은 이벤트(Create, Step이벤트등)가 없어야 적용됩니다.
만약 같은 이벤트가 있다면, parent의 이벤트는 실행되지 않고, 현재 배치된 오브젝트의 이벤트만

실행됩니다.
parent의 이벤트도 같이 실행되게 하려면, 현재 오브젝트에서 parent와 동일한 이벤트에

event_inherited()를 추가하면
parent의 이벤트를 상속받아, 현재 오브젝트와 parent의 이벤트가 같이 실행됩니다.

이것은 볼이 블럭과 충돌했을 때 -1씩 감소 시켜 hp가 0이 되면 부숴지게 하려는 것입니다.
hp가 1이면 1번만 충돌해도 부숴지게 되죠.
이것은 기본 설정이고, 다양한 hp를 구성하고 싶다면, 실질적으로 배치되는 오브젝트들(obj_bl_A,

obj_bl_B, obj_bl_C)에 따로 설정하시면 됩니다.

다음은 Step 이벤트에 hp가 0이 되었을 때 이벤트를 작성해봅시다.

 

     ★ obj_block_unit - Step 이벤트

     if hp<=0{instance_destroy();}


이렇게 하면 hp가 0이 되었을 때, 해당 인스턴스는 파기됩니다.






◈볼(obj_ball)

 


다음은 게임에 사용될 볼을 만들어 봅시다.
이미지를 준비하고, 스프라이트로 구성(spr_ball)합니다.

 

 

(▲볼 이미지)


마스크 설정은 Automatic - Disk로 설정했습니다.

볼로 사용할 오브젝트(obj_ball)를 하나 만들고, Sprite에 준비한 볼 스프라이트를 지정합니다.

 

 

(▲볼 오브젝트)


볼에 대한 설정을 해봅시다.
Create 이벤트에 필요한 변수들을 설정해줍시다.

 



     ★ obj_ball - Create 이벤트

     vspeed=3;//생성되었을 때 볼 이 아래로 떨어지게함

     speed_max=20;//볼이 시간에 지남에 따라 추가될 수 있는 최대 속도
     speed_add=0.1;//볼의 추가 속도



먼저 생성되었을 때 볼이 아래로 떨어지게 해야합니다.
그래야 플레이어가 볼을 튕기게 할 수 있죠.
가속도가 붙었을 경우 볼이 너무 빠르면 제어가 안되기 때문에 속도를 제한하도록 해요.
End Step 이벤트를 추가하고, 아래와 같이 속도를 제한하도록 합니다.

 



     ★ obj_ball - End Step 이벤트

     if speed>speed_max{speed=speed_max;}



이것은 시간에 지남에 따라 점점 빨라지도록 가속도를 붙게 하는 것입니다.

가끔 게임을 진행하다보면 볼이 수평방향으로 이동해, 아래로 내려오지도 않고, 위로 올라가지도 않고,
볼이 계속 좌우로만 이동하여 게임이 진행이 안되는 경우가 생기기도 합니다.
이것을 방지하기 위해 End Step이벤트에 아래와같이 추가 작성해 주도록 해요.

 



     ★ obj_ball - End Step 이벤트

     if round(direction)=0 || round(direction)=180{direction=direction+choose(-5,5);}



이렇게 하면 방향이 수평으로 이동해 진행이 안될 때, 방향을 랜덤으로 약간 변경하여 이동하게 됩니다.

다음은 플레이어와 충돌했을 때의 이벤트를 작성해봅시다.
플레이어(obj_player)와 충돌이벤트를 추가하고 아래와 같이 작성합니다.

 



     ★ obj_ball - obj_player와의 충돌 이벤트

     move_bounce_solid(1);//바운스되게 함
     if other.x>x{direction+=5;}else{direction-=5;}
     if speed<speed_max{speed+=speed_add;}



이렇게 하면 플레이어와 충돌 했을 때 튕겨 이동하게 됩니다.
마찬가지로 블럭(obj_block)과의 충돌 이벤트도 작성해 봅시다.

 



     ★ obj_ball - obj_block과의 충돌 이벤트

     if other.hp>0{other.hp-=1;}else{other.hp=0;}
     move_bounce_solid(0);//바운스되게 함
     if speed<speed_max{speed+=speed_add;}



엇! move_bounce_solid에 넣는 인자가 다르네요.
이것은 경사진 벽을 따른 바운스 설정을 할것인지를 지정하게 해요.
여기에 1값을 넣게 되면 바운스되는 모양에 따라 다양한 방향으로 이동하게 됩니다.
그래서 플레이어에는 1을 넣어도 상관 없지만, 블럭에 1을 넣으면 원치 않은 결과가 나올 수 있습니다.
모양이 직각 형태라도 엉뚱한 방향으로 튕기게 될 수 있죠. 그래서 0을 넣는 것입니다.

볼과 플레이어를 룸에 배치하고 제대로 작동 되는지 테스트 해봅시다.

이동하는 볼이 뭔가 밋밋해보이는 군요.
볼에 잔상을 남기는 효과를 줘 봅시다.

 

 

(▲잔상 효과)


이펙트로 사용할 오브젝트(obj_effect)를 먼저 만듭니다.
이 이펙트는 다양한 용도로 쓰일 것입니다.

 

 

(▲이펙트 오브젝트)


Create 이벤트를 추가하고, 필요한 변수들을 선언합시다.

 



     ★ obj_effect - Create 이벤트

     spr=sprite_index;
     img=0;//서브이미지
     fade_spd=0.05;//페이드 속도
     sca=1;//확대치
     sca_spd=0;//확대/축소 속도
     rot=0;//회전값
     rot_spd=0;//회전속도
     col=c_white;//혼합색
     alp=1;//투명도



히익~! 많은 변수를 선언했네요.

뭐, 색상도 변경할 수 있고, 이펙트 스프라이트도 변경가능하고, 확대 및 축소도가능하고, 회전도 가능한

다용도 이펙트입니다. 이것은 강좌용이긴 하지만 여러분도 여러분만의 이펙트를 만들어 보시면

재미있을 거에요.


다음엔 이 변수들을 제어해봅시다.
Step 이벤트를 추가하고, 아래와 같이 작성합니다.

 



     ★ obj_effect - Step 이벤트

     if alp>0{alp-=fade_spd;}else{alp=0;instance_destroy();}
     rot+=rot_spd;
     sca+=sca_spd;



이것은 투명도가 0이되면 이펙트는 파기되게 하는 것입니다.
이제 이펙트를 표시해야겠죠.
Draw 이벤트를 추가하고, 다음과 같이 작성해요.

 



     ★ obj_effect - Draw 이벤트

     draw_sprite_ext(spr,img,x,y,sca,sca,rot,col,alp);



이펙트 오브젝트가 하나 만들어졌습니다.
이제 이 오브젝트를 볼에서 생성하면 됩니다.
볼 오브젝트(obj_ball)로 이동해서, End Step이벤트에 아래와 같이 추가해요.

 

 
    ★ obj_ball - End Step 이벤트

     aa=instance_create(x,y,obj_effect);
     aa.spr=spr_ball;
     aa.alp=0.5;
     aa.depth=depth+1;



이렇게 하면 볼이 이동할 때마다 잔상을 남기게 됩니다.

 

 

 




◈이펙트 생성

 


이왕 만든김에 플레이어와 블럭에 충돌했을 때 이펙트도 만들어 봅시다.

 

 

(▲충돌했을때 이펙트 발생)


강좌에선 흰색 동그라미 이미지를 사용해보도록 하겠습니다.

 

 

(▲이펙트 이미지)


볼 오브젝트(obj_ball)User Defined 0 이벤트를 추가하고 아래와 같이 작성하도록 해요.

 



     ★ obj_ball - User Defined 0 이벤트

     repeat(8){
     aa=instance_create(x,y,obj_effect);
     aa.spr=spr_effect;
     aa.img=0;
     aa.direction=direction+180+irandom_range(-20,20);
     aa.speed=random_range(1,5);
     aa.friction=0.1;
     aa.sca=random_range(0.1,0.5);
     }


 

※[참고]irandom_range(최소, 최대)와 random_range(최소, 최대)는 최소값과 최대값을 지정하여

두 값 사이의 랜덤 값을 반환시킬때 사용합니다.

차이점은 irandom_range는 정수만, random_range는 소수점을 포함한 랜덤 값을 반환 시킨다는 것이

다릅니다.

 

이 이펙트는 볼 충돌하기 전의 방향 반대편으로 8개의 이펙트를 생성하게 됩니다.
이제 이 이펙트 이벤트를 플레이어와 블럭과의 충돌이벤트에서 event_user(번호)를 통해
호출 시키면 됩니다.

 



     ★ obj_ball - obj_player와의 충돌 이벤트

     //-------------------
     event_user(0);       ◀이벤트 삽입
     //-------------------

     move_bounce_solid(1);
     if other.x>x{direction+=5;}else{direction-=5;}
     if speed<speed_max{speed+=speed_add;}



마찬가지로 블럭과의 충돌이벤트에도 추가하도록 합니다.

 



     ★ obj_ball - obj_block과의 충돌 이벤트

     if other.hp>0{other.hp-=1;}else{other.hp=0;}
     //--------------------
     event_user(0);       ◀이벤트 삽입
     //--------------------
     move_bounce_solid(0);
     if speed<speed_max{speed+=speed_add;}



이번에는 블럭이 파기될때 이펙트를 발생시켜 봅시다.

 

 

(▲블럭 파기 이펙트)


실제 배치되는 블럭들의 두번째 parent(obj_block_unit)User defined 0 이벤트를 추가하고

아래와 같이 작성합니다.

 



     ★obj_block_unit - User defined 0 이벤트

     _w=24;
     aa=instance_create(x+_w,y,obj_effect);
     aa.spr=spr_effect;
     aa.img=0;
     aa.sca=1;
     aa.sca_spd=0.1;

     aa=instance_create(x+_w,y,obj_effect);
     aa.spr=spr_effect;
     aa.img=0;
     aa.sca=1;
     aa.col=c_red;

     aa=instance_create(x+_w,y,obj_effect);
     aa.spr=spr_effect;
     aa.img=0;
     aa.sca=0.6;
     aa.col=c_yellow;

     repeat(8){
     aa=instance_create(x+_w,y,obj_effect);
     aa.spr=spr_effect;
     aa.img=0;
     aa.direction=irandom(360);
     aa.speed=random_range(1,5);
     aa.friction=0.1;
     aa.sca=random_range(0.1,0.8);
     }



핫! 이펙트를 좀 많이 생성했군요. 헤헤~
어째든 이렇게 하면 블럭이 파기될때 이펙트를 발생하게 됩니다.
이것을 블럭 parent(obj_block_unit)Destroy이벤트에서 호출하시면 됩니다.

 

 
    ★obj_block_unit - Destroy 이벤트

     event_user(0);



굳! 어느정도 재료가 모였군요.
게임을 구성해보도록 합시다.



 

 

 

 

 


◈게임 구성(obj_ctrl_sys, obj_ball_position)

 


이제 게임을 구성해보도록 할까요.
전반적으로 게임을 제어할 오브젝트(obj_ctrl_sys)를 하나 만듭니다.

 

 

(▲시스템 오브젝트)


이 오브젝트는 여러가지 정보를 표시해야하기 때문에 depth를 낮게 설정해줍시다.
강좌에선 -10000으로 설정했습니다.

Create 이벤트를 추가하고, 필요한 변수들을 선언하도록 합니다.

 



     ★obj_ctrl_sys - Create 이벤트

     game_start=0;//게임 시작 스위치
     game_clear=0;//게임 클리어 스위치



자~ 이제 볼을 룸에 배치하지 않아도 자동으로 생성하도록 만들어봅시다.
먼저 볼의 생성 위치를 잡아줄 오브젝트(obj_ball_position)를 하나 만듭니다.

 

 

(▲볼의 위치를 잡아줄 오브젝트)


이것은 룸에 배치만하고, 게임상에서는 보이지 않게 해야하기 때문에 Visible을 체크해제 합니다.

다음은 이것을 이용해 시스템 오브젝트(obj_ctrl_sys)에서 볼을 생성하도록 해요.
볼을 생성할 때 약간의 지연시간을 주도록 해요.
강좌에선 Alarm 0 이벤트를 이용하도록 하겠습니다.
Create 이벤트에, Alarm 0 이벤트 설정을 아래와 같이 추가합니다.

 



     ★obj_ctrl_sys - Create 이벤트

     alarm[0]=90;



다음은 Alarm 0 이벤트를 추가하고, 아래와 같이 볼을 생성하도록 합니다.

 



     ★obj_ctrl_sys - Alarm 0 이벤트

     with(obj_ball_position){instance_create(x,y,obj_ball);}//볼 위치 오브젝트에 볼 생성
     game_start=1;//게임 시작



플레이어가 룸 밖에 나갔을 때 재시작하는 이벤트를 작성해봅시다.
시스템 오브젝트(obj_ctrl_sys)Step 이벤트를 추가하고, 아래와 같이 작성합니다.

 



     ★obj_ctrl_sys - Step 이벤트

     with(obj_ball){
     if y>room_height+32{other.alarm[0]=60;instance_destroy();}
     }



이렇게 하면 볼의 y좌표가 룸 높이보다 높으면(룸 밖으로 벗어 났을 때)파기하고, 약간의 지연시간을 둔 후
볼을 다시 생성하게 됩니다.

클리어 했을 때 이벤트도 작성해볼까요.
클리어 했을 때 볼을 파기하고, 지연시간 후 다음 룸으로 넘어가게 해야합니다.
강좌에선 그냥 룸을 재시작하는것으로 하지만, 다음 룸이 있다면 여러분이 다음 룸으로 이동하게 작성 하시면 됩니다.
Step 이벤트에 아래와 같이 추가합니다.

 



     ★obj_ctrl_sys - Step 이벤트

     if !(instance_exists(obj_block_unit)) && game_clear=0{
     with(obj_ball){instance_destroy();}
     alarm[5]=180;
     game_clear=1;}



Alarm 5 이벤트를 추가하고, 아래와 같이 작성합니다.

 



     ★obj_ctrl_sys - Alarm 5 이벤트

     room_restart();



이것은 룸을 재시작하는 것입니다.
다음 룸으로 이동할 때는 아래와 같이 room_goto_next()를 사용하세요.

 



     ★obj_ctrl_sys - Alarm 5 이벤트

     room_goto_next();



아니면 특정 룸으로 이동하고자 할때는 room_goto(룸 이름)을 사용하시면 됩니다.

 



     ★obj_ctrl_sys - Alarm 5 이벤트

     room_goto(room1);//room1로 이동함









◈게임 시작과 클리어 정보 표시

 


게임 시작과 클리어 때 필요한 이미지를 준비하도록 합시다.

 

 

(▲게임 시작과 클리어 이미지)


강좌에선 간단하게 '준비', '클리어' 이미지를 준비했습니다.

 

 

(▲스프라이트 구성)


스프라이트로 구성(spr_game_info)하고, 중심점을 가운데로 맞춰줍니다.

다음은 시스템 오브젝트로 이동해서, 해당 이벤트를 작성하도록 합니다.
Draw 이벤트를 추가하고, 아래와 같이 작성합니다.

 



     ★obj_ctrl_sys - Draw 이벤트

     if game_start=0{
     draw_sprite_ext(spr_game_info,0,240,320,1,1,0,c_white,1);//게임 시작
     }

     if game_clear=1{
     draw_sprite_ext(spr_game_info,1,240,320,1,1,0,c_white,1);//게임 클리어
     }



볼을 생성하였을 때 game_start변수를 사용했었죠.
그것을 이용해서 변수값이 0일때 시작 이미지를 표시하도록 하는 것입니다.

클리어 했을 때는 game_clear변수를 1로 만들기 때문에, 변수값이 1일때 정보를 표시하도록 하는 것입니다.

와우! 게임 구성이 끝났습니다.
이제 룸에 오브젝트들을 배치하고, 제대로 되는지 테스트 해봅시다.

 

 

(▲룸에 오브젝트들을 배치)


룸에 배치한 오브젝트들

     시스템 오브젝트 : obj_ctrl_sys (1개)
     테두리 블럭 오브젝트 :obj_wall_h, obj_wall_v (테두리 부분만)

     볼 위치 오브젝트 : obj_ball_position (1개)
     플레이어 오브젝트 : obj_player (1개)
     블럭 오브젝트 : obj_block_A, obj_block_B, obj_block_C (게임내 블럭배치)

 

 

(▲테스트 화면)


드디어 게임이 완성되었네요.
이번 강좌는 여기까지입니다. 제대로 따라 하셨는지 모르겠네요.
강좌에선 어떤 식으로 작동되는지 보여주기 위한 것이었지만, 여러분은 더 멋진 게임을 만드실 수 있을 거에요.

 

 



 

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

 

BBX1-1.gmk
다운로드

 

BBX1-1.exe
다운로드

 

 

300x250

댓글