본문 바로가기
GameMaker강좌[GM8]/액션게임강좌

[게임메이커강좌-플랫폼]간단한 플랫폼게임 만들기-1-중력과 이동

by 타락카얀 2013. 4. 28.
728x90




플랫폼게임의 기본적인 원리에 대해 알아봅시다.









◈중력




(▲중력 설정)


그림과 같이 플레이어가 공중에 있을 때 아래로 떨어지게 되면 점점 속도가 붙으며 빨리 떨어지다
일정 속도가 되면 일정하게 떨어지게 하고,
블럭에 착지하면 플레이어는 멈추게 됩니다.

이제 이러한 중력이 적용된 플레이어와 이동하는 부분을 만들어봅시다.

먼저 parent로 설정할 블럭 오브젝트(예.obj_block)를 하나 만듭시다.



(▲블럭 오브젝트)


그리고 룸에 실제 배치할 하위 오브젝트를 만듭니다.
만든 하위 오브젝트를 열어 solid를 체크하고, obj_block을 parent로 지정합니다.

블럭설정은 대충 끝났네요.

다음은 플레이어를 만듭시다.

일단 플레이어가 이동하는 이미지를 스프라이트로 구성합니다.



(▲플레이어가 이동하는 이미지)


강좌에서는 4장으로 구성했습니다.
플레이어에 사용할 스프라이트의 중심점을 맞춰주세요.



(▲이미지를 스프라이트로 구성)


강좌에서는 편의상 가운데로 맞춰주었습니다.

그리고 무엇보다도 중요한 마스크를 설정해주어야 합니다. Modify Mask버튼을 눌러 마스크를

지정합시다.
마스크를 지정하지 않으면 블럭에 끼여버리는 상황이 발생하게 됩니다.

왜냐하면 마스크를 지정하지 않았을 때는 스프라이트의 서브 이미지 모양대로 마스크가 처리되어,

불규칙한 형태가 되어버립니다.

그리고 스프라이트 이미지가 재생될 때 다른 오브젝트에 끼여버리게 되는 것이지요.

그래서 마스크 모양을 통일할 필요가 있는 겁니다.



(▲이미지를 스프라이트로 구성)


옆의 미리보기에서 마우스로 드래그해 지정할 수도 있고, 좌표를 주어 지정할 수도 있습니다.
플랫폼게임의 마스크는 사각형모양이 좋기 때문에 강좌에서는 사각형으로 구성했습니다.


이 스프라이트를 표시하기 위해서는 오브젝트가 필요합니다.
오브젝트는 이벤트를 처리하기 위한 실질적인 주체가 되는 것이지요.
오브젝트(obj_player)를 하나 만들고, Sprite에 이전에 준비한 스프라이트를 지정하도록 해요.

이제 중력에 대한 설정을 해봅시다.
먼저 Step이벤트를 추가하고,



조건문으로 Control->Questions->Check Empty액션을 삽입합니다.


     x : 0
     y : 1
     object : Only solid

     [V]Relative


이 조건문은 (x,y+1)지점에 이동했을 때 solid오브젝트가 있는지, 또는 충돌하는지를 체크하는 것입니다.
말그대로 공중에 있을 때의 상황이죠.

다음은 Control->Others->Start BlockEnd Block을 추가하고, 그 사이에



(▲중력 액션)


중력액션인 Move->Move->Set Gravity액션을 삽입합니다.


     direction : 270
     gravity : 0.3     //더 빨리 떨어지게 하려면 큰 숫자를 넣으면 됨.


그리고 Control->Others->Else액션을 추가하고,
마찬가지로 Control->Others->Start BlockEnd Block을 추가합니다.
Else는 조건문의 반대 조건문에 해당합니다.
따라서 여기에선 solid오브젝트에 닿았을 때의 조건입니다.



(▲solid오브젝트에 닿았을 때의 조건)


중력액션인 Move->Move->Set Gravity액션을 삽입합니다.


     direction : 270
     gravity : 0


중력부분은 되었지만, 너무 빨리 낙하하지 않도록 속도를 제어해야겠지요.



(▲vspeed 제어)


속도제어를 위한 조건문으로 Control->Variables->Test Variable액션을 추가합니다.


     variable : vspeed
     value : 8
     operation : larger than


그리고 속도를 설정해야겠지요.



(▲vspeed 제어)


Move->Move->Speed Vertical액션을 추가합니다.


     vert.speed : 8


이제 블럭의 착지 했을 때의 이벤트를 만들어야 합니다.
블럭오브젝트(블럭의 parent로 지정)와의 충돌이벤트를 추가합니다.


다음은 gravity액션을 쓰다보면 블럭에 착지했을 때,
가끔 1~2 픽셀정도 약간 뜨는 경우가 발생합니다.
이럴때는 다음과 같이 강제로 solid에 붙여주는 액션이 필요합니다.




(▲Move to Contact액션)


Move->Jump->Move to Contact액션을 삽입합니다.


     direction : direction
     maximum : 8   또는 max(1,speed)
     against : solid objects


이렇게 하면 블럭에 착지시 약간 뜬 경우, 중력방향(270 또는 direction 방향)으로 완전히 붙여주게
됩니다.
maximum은 최대 여분의 값, 또는 속도(speed)만큼의 값을 넣으시면 됩니다.

그리고 중력이 적용되었기 때문에 중력을 멈춰야 합니다.



(▲vspeed 제어)


Move->Move->Speed Vertical액션을 추가합니다.


     vert.speed : 0



-주농님 팁 추가-
또다른 방법으로는


     direction : direction
     maximum : speed
     against : solid objects


로 할 수도 있습니다.
보통 이것은 360방향의 이동을 할때사용하기도 합니다.

다만, Move to Contact 액션 이전에 vspeed를 0으로 멈추면 direction이 180으로 변경이

되기 때문에, 왼쪽 방향으로 밀려나게 됩니다.

그래서 vspeed를 0으로 멈추게 할 것이라면, Move to Contact 액션 이후에 사용하거나,
speed라는 변수로 멈추어야하고(방향이 바뀌지 않기위해), 플랫폼 특성상 중력 방향이 270이므로
Move to Contact 액션 이전의 direction(방향)은 항상 270 값이어야 합니다.









◈이동



이제 이동에 대한 이벤트를 작성해봅시다.
먼저 Left키에 대한 이벤트를 추가하고,



(▲왼쪽에 이동하면 블럭에 닿을 지 체크)


조건문으로 Control->Questions->Check Empty액션을 삽입합니다.


     x : -2   //이동하는 만큼 지정
     y : 0
     object : Only solid

     [V]Relative


그리고 좌표를 왼쪽으로 이동해야겠지요.



(▲왼쪽으로 이동)


이동 액션으로 Move->Jump->Jump to Position을 추가하고,


     x : -2   //이동하는 만큼 지정
     y : 0

     [V]Relative


왼쪽으로 이동이 끝났습니다.
이제 오른쪽키 이벤트도 왼쪽키처럼 작성하시면 됩니다.

Right키에 대한 이벤트를 추가하고, 조건문으로 Control->Questions->Check Empty액션을

삽입합니다.


     x : 2   //이동하는 만큼 지정
     y : 0
     object : Only solid

     [V]Relative


이동 액션으로 Move->Jump->Jump to Position을 추가하고,


     x : -2   //이동하는 만큼 지정
     y : 0

     [V]Relative


다음은 점프 이벤트를 작성해봅시다.
강좌에선 Space키를 사용해보도록 하지요.
Space키 이벤트를 추가하고,



(▲바닥에 있는지 체크)


조건문으로 Control->Questions->Check Empty액션을 삽입합니다.


     x : 0   //이동하는 만큼 지정
     y : 1
     object : Only solid

     [V]Relative    [V]Not


다음은 점프 속도를 설정해야합니다.


Move->Move->Speed Vertical액션을 삽입합니다.


     vert.speed : -6


이동과 점프가 모두 끝났습니다.
룸에 블럭과 플레이어를 배치하고 제대로 이동하는지 테스트해봅시다.





◈애니메이션





(▲4장의 애니메이션)



위의 이미지와 같이 애니메이션이 있는 이미지로 캐릭터를 만들려면 조금 더 설정해주어야 합니다.

먼저 Create이벤트를 추가하고, Control->Variables->Set Variable을 이용하여
애니메이션을 제어할 변수들을 만듭시다.



(▲변수 생성)



     //점프하는 중인지 체크할 변수
     variable : jump
     value : 0


     //이동하는지 체크할 변수
     variable : move
     value : 0


     //이미지 방향에 대한 변수
     variable : xdir
     value : 1   //-1은 반대 방향


     //애니메이션 속도 제어
     variable : image_speed
     value : 0.2  //1은 룸 속도. 1보다 작으면 점점 느려짐






(▲점프 변수 설정)


위 그림처럼 점프중일 때와 점프 안했을 때 변수를 삽입합니다.


     //점프 중일때
     variable : jump
     value : 1


     //점프 안할때
     variable : jump
     value : 0


다음은 키 이벤트에 대한 이동 변수를 설정합시다.



(▲왼쪽 키에 대한 방향과 이동 변수 설정)


먼저 Left키 이벤트끝에  Control->Variables->Set Variable을 이용하여 변수를 설정합니다.


     //이동
     variable : move
     value : 1


     //이동 방향
     variable : xdir
     value : -1


마찬가지로 Right키 이벤트도 비슷하게 작성하시면 됩니다.

     //이동
     variable : move
     value : 1


     //이동 방향
     variable : xdir
     value : 1


다음은 Draw이벤트를 추가하고, 표시되는 애니메이션을 제어하면 됩니다.



(▲Draw이벤트)


스프라이트에 대한 다양한 설정을 액션만으로는 힘들기 때문에 코드로 작성해야합니다.
(Main1->Sprite->Transform Sprite액션으로 설정할 수도 있으나,
이 액션은 마스크의 영향을 주기 때문에, 설정이 갑자기 변경되면 캐릭터가 블럭에 끼일 수 있음)

따라서 Draw이벤트Control->Code->Execute Code액션을 추가하고 아래와 같은 코드를

작성합니다.


     //점프 안함
     if jump=0{
          if move=1{
               draw_sprite_ext(sprite_index,-1,x,y,xdir,1,0,c_white,1);//이동중 이미지
          }
          else{
               draw_sprite_ext(sprite_index,0,x,y,xdir,1,0,c_white,1);//정지했을 때 이미지
          }
     }
     //점프 중일때
     else{
          draw_sprite_ext(sprite_index,3,x,y,xdir,1,0,c_white,1);//점프중일 때 이미지
     }

     move=0; //이동변수를 다시 리셋


Draw 이벤트란 주로 화면에 이미지 같은 것을 표시할 때 사용하는 이벤트입니다.
대개 draw_로 시작하는 함수를 사용할 때 이 이벤트를 사용하지요.

(코드창에 draw_까지만 치면 밑에 어떤 함수가 있는지 주르륵하고 뜹니다)
여기서 사용하는 draw_sprite_extdraw_sprite의 확장 함수로써, 스프라이트 이미지를 다양하게

변형시켜 화면에 표시할 때 사용합니다.

     draw_sprite_ext(sprite,subimg,x,y,xscale,yscale,rot,color,alpha)

함수에 들어가는 인자는 다음과 같아요.

     sprite : 스프라이트 이미지
     subimg : 스프라이트의 서브 이미지. -1일때는 애니메이션 재생
     x,y : 화면에 표시할 좌표
     xscale : 가로 스케일링. 기본값은 1.
     yscale : 세로 스케일링. 기본값은 1.
     rot : 이미지 회전. 기본값은 0.
     color : 컬러 혼합. 기본값은 c_white.
     alpha : 투명도. 기본값은 1.

예를 들어 위에서

     draw_sprite_ext(sprite_index,-1,x,y,xdir,1,0,c_white,1);

이것은 이동중일때 이벤트이죠. 자세히 들여다 봅시다.
sprite_index는 오브젝트에 지정한 현재 스프라이트를 가리키며, 이동 중이므로 -1값을 넣어

스프라이트의 애니메이션을 재생하게 하는 것입니다.

만약 다른 스프라이트를 지정하고 싶으면 해당 스프라이트의 이름을 넣으시면 됩니다.


(x,y)좌표니까 현재 오브젝트의 위치에 이미지를 표시하고, xdir 방향에 따라 이미지를 스케일링하게

되지요.
즉, xscale이 -1이면 왼쪽 방향으로 이미지를 변형시켜 화면에 표시하고, 1이면 오른쪽 방향 형태로
이미지를 표시하게 되는 거에요 (참고로 현재 지정된 스프라이트는 오른쪽 방향임. 이미지가

왼쪽 방향이면 값을 반대로 설정하시면 됨).


yscale은 변형이 없으므로 그대로 1값을 설정합니다.


color에는 표시할 스프라이트 이미지에 색을 혼합시킬 수 있는데, 이미지 원본대로 화면에 표시하고자
한다면 흰색값인 c_white를 넣으시면 됩니다 (코드창에 c_를 치면 어떤 색이 있는지 알수 있으며

$FFFFFF , $FF와 같은 형식의 색도 사용가능함).


alpha값은 0~1값을 넣을 수 있는데 0이면 투명하게 되고, 1이면 불투명하게되며 그 사이의

소수점 값을 넣으면 반투명한 상태가 됩니다.





여기 까지!
이제 플랫폼의 기본 설정이 모두 끝났습니다.



(▲테스트 화면)


배경도 삽입하고, 블럭과 다른 오브젝트도 배치해서
제대로 작동되는지 테스트해봅시다.






-------응용예제------



platform-1-액션.gmk


platform-1-액션.exe




300x250

댓글