2019년 9월 15일 일요일

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



0. 목차


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


1. 주인공 object

1.1 비행기 및 총알 그리기

옆에서 보는 비행기를 3가지 준비를 합니다. 가만히 있을때 위쪽으로 올라갈때와 내려갈때 각각 다른 이미지를 사용하면 보기에 좋습니다. 또한 뒤쪽의 엔진의 불꽃의 경우 따로 준비를 하였습니다. 불꽃의 경우 이미지 모든 이미지에 추가하게 되면 전체적인 이미지 갯수가 증가하기 때문입니다.
그럼, 그린 그림을 감상 하시죠




위로 올라갈때


아래로 내려올때


엔진 불꽃

주인공 총알

오늘의 작업 전체 이미지




1.2 Player 움직임을 위한 step 함수 구현

단순히 x , y 좌표값을 더 하는 것만으로도 쉽게 구현이 가능하지만, 여기에서는 vx(가로축의 속도) , vy (세로축의 속도) 두가지 값으로 접근을 합니다. vx가 증가해서 vxMax 까지 다다르게되고,  vy는 vyMax까지 다다르게 됩니다. 즉 이렇게 구현하는것은 속도가 한번에 급격하게 오르는것을 방지하기 위한 목적입니다. (자연스러운 움직임을 만들 수 있습니다.) 예를 들어 x축으로 +3 만큼 증가하고 있다고 쳤을때 다음 step에서 갑작이 -3으로 변경된다면 화면이 부자연 스러움이 생깁니다. 따라서 vx , vy를 두고 실제 x, y 좌표값이 결정되게 됩니다.


airAccel    = 0.7;airFric     = 0.3;vxMax       = 3;vyMax       = 3;
// Velocityvx = 0;vy = 0;
Create에는 위와 같은 변수들이 초기화 됩니다. airAccel은 가속도를 의미합니다. step마다 더 해주는 가속도를 의미합니다. airFric는 키를 안누를때 정지시키기 위한 마찰력을 의미합니다.
게임은 자동으로 스크롤 되고 있기때문에 x 속도는 0이라고 봐야 합니다.

if(kRight){ vx = Approach(vx, vxMax, airAccel);}if(kLeft){ vx = Approach(vx, -vxMax, airAccel);}if(kUp){ vy = Approach(vy, -vyMax, airAccel);}if(kDown){ vy = Approach(vy, vyMax, airAccel);}
// Frictionif (!kRight && !kLeft) {    vx = Approach(vx, 0, airFric);if (!kUp && !kDown) {    vy = Approach(vy, 0, airFric);
위 내용은 step에서 처리하는 내용입니다. k가 붙은 kRight, kLeft 등의 변수는 키를 누르면 true가 되는 변수 입니다. 다른 분이 작성한 Approach 라는 script가 있는데 이것은 현재 속도와 max값을 넣어둘때 이번에 들어가는 step(증감 하는값)을 고려해서 최종 속도를 계산하는 함수 입니다.
// Friction 부분의 코드는 마찰력을 고려하여 손을 떼었을때 움직임이 0이 되도록 처리하는 함수 입니다.

endstep에서는 vx vy를 고려하여 최종 x, y 값을 계산해 냅니다. 
if (vy < 1 && vy > -1){ // Do nothing}else{ if( vy > 0 ){     repeat(abs(vy)) {         if (y<global.screen_height-10)             y += sign(vy);         else             break;     } }else{     repeat(abs(vy)) {         if (y>+10)             y += sign(vy);         else             break;     } }}
위 코드는 endstep코드인데 y축에 대한 정보입니다. 동일하게 x축에 대한 처리도 있지만 전체 코드에서 확인 부탁드립니다. 
"Do nothing" 코드는 속도가 1 미만인 경우 좌표를 더하거나 빼거나 하지 않고 이전 좌표를 유지하게 됩니다. repeat(abs(vy)) { 이 부분은 만약 최대 속도가 3이라면 +3, -3일때 모두abs(vy)는 3이 넘어옵니다. y += sign(vy); 여기에서 1씩 더 해주거나 빼주려고 abs(절대값)을 취한 것 입니다. 
if (y<global.screen_height-10) , if (y>+10) 여기 코드는 위 아래 못 움직이는 처리를 위해서 사용하는 조건 입니다.

1.3 Player에 엔진 불꽃 추가하기


아래 코드에서 draw_sprite_ext(sEngineFire, subimage_index, x-32, y, facing * xscale, yscale, 0, mapc, image_alpha); 이 부분이 불꽃을 그리게 됩니다.
다만 주의할점은 subimage_index 라는 다른 변수를 만들고 인덱스를 따로 관리해 주어야 합니다. 여기에서는 적당하게 subimage_index += 0.2; 더해서 적당한 속도를 구현하였습니다.

var mapc = c_white;
var xscale = 1;
var yscale = 1;
var facing = 1;

if( up ){
 sprite_index = sPlayerSkyShipUp;
}else if( down ){
 sprite_index = sPlayerSkyShipDown;
}else{
 sprite_index = sPlayerSkyShip;
}

subimage_index += 0.2;

draw_sprite_ext(sEngineFire, subimage_index, x-32, y, facing * xscale, yscale, 0, mapc, image_alpha);
draw_sprite_ext(sprite_index, -1, x, y, facing * xscale, yscale, 0, mapc, image_alpha);

1.3 주인공이 발사하는 총알 object

해당 object는 특이점이 없습니다. Outside Room 이벤트에서 instance_destroy();만 해줍니다. 안그러면 총알을 발사할때마다 object가 늘어가게 됩니다.

주인공의 총알을 발사는 아래 Player 쪽에서 구현을 합니다.
kAction키가 들어오면 oAmmo object를 만들고 속도와 방향을 정해서 발사를 하게 됩니다.

if (kAction) { // Fire Bullet var bdir = 0; if( facing == 1 ) bdir = 0; else bdir = 180; var ct = oAmmo; with (instance_create_layer(x, y,"Instances_Ammo", ct)) { y = y + 6; speed     = 8; direction = bdir; }}

1.4 전체 소스

GMS2 소스입니다.
https://drive.google.com/open?id=1WqS5lQEFM90j5YQQKL3JPpPq6PzOOHfB

1.5 실행 예제



여기에서 사용된 이미지는 자유롭게 사용하셔도 됩니다. (출처를 기록하시면 더 좋습니다.)













댓글 없음:

댓글 쓰기