본문 바로가기
GameMaker강좌[GM8]/RPG강좌

[게임메이커강좌-액션Rpg 강좌]액션Rpg-3-적 유닛(2/2)

by 타락카얀 2013. 10. 15.
728x90

 

 

GAME MAKER 강좌

 

 

KAYAN

 

 

 

이번에는 플레이어의 공격에 대한 이벤트를 설정하도록 합시다.

 

 

(▲플레이어의 공격)

 

 

 

 

 

 

 

 

 

◈플레이어의 공격(obj_player,obj_pl_att)

 
강좌에서는 아래와 같은 공격을 만들어 볼 것입니다.

 

 

(▲플레이어의 공격)


이것은 플레이어에서 공격 오브젝트를 발사하면, 공격 오브젝트는 앞으로 나아가다 점점 투명해지는데, 투명해지기

전에 적들 중 하나에게 닿으면, 그 적 대상의 HP를 감소시키게 됩니다. 또한 공격을 한 적은 뒤로 약간 밀어버립니다.

공격 오브젝트가 완전히 투명해지면 더이상 필요가 없으므로 오브젝트를 파기해 버립니다.

그리고 약간의 딜레이 후 플레이어는 다시 재공격을 할 수 있게합니다.

이러한 설정을 만들어 보겠습니다.


플레이어의 공격에 대한 이미지를 준비하고, 스프라이트(spr_pl_dmg1)로 구성하도록 해요.

 

 

(▲플레이어 공격 이미지)

 

스프라이트는 애니메이션으로 구성해도 됩니다.

애니메이션일 경우 Animation End 이벤트로 오브젝트를 파기하고, 파기되기 전에 공격을 처리하면 되겠지요.

강좌에선 이미지 1장이니 1장에 관련된 이벤트를 작성할 것입니다.

 

 

(▲공격 스프라이트)

 

이제 오브젝트(obj_pl_att)를 하나 만들고, sprite에 준비한 공격 스프라이트(spr_pl_dmg1)를 지정합니다.

 

(▲공격 오브젝트)


Create 이벤트를 추가하고, 공격에 필요한 변수를 선언하도록 해요.

 



     ★ obj_pl_att - Create 이벤트

     att=0;//데미지 수치. 플레이어에서 입력함.
     check=0;//완전히 투명해지기 전에 1개의 적 유닛만 공격하도록 체크

     alp=2;//투명도
     fade_spd=0.2;//페이드 속도


 

공격을 할 수 있는 변수와 투명도에 관련된 변수를 선언했습니다.

 

이제 이미지를 표시해야겠지요.
Draw 이벤트를 추가하고, 이미지를 표시합니다.

 



     ★ obj_pl_att - Draw 이벤트

     draw_sprite_ext(sprite_index,0,x,y,1,1,direction,c_white,alp);


 

이미지가 1장이라 서브이미지를 0으로 넣었습니다만, 만약 애니메이션이라면 서브이미지에 -1을 넣으면 됩니다.

 

     draw_sprite_ext(sprite,-1,x,y,xscale,yscale,angle,color,alpha)


이제 파기되는 조건이 필요하겠지요.
Step 이벤트를 추가하고, 오브젝트가 파기되는 조건을 이벤트로 작성하도록 해요.

 



     ★ obj_pl_att - Step 이벤트

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


 

이것은 이미지가 점점 투명해지다가 투명도가 0이되면 파기되는 것입니다.

만약 일정 시간이 지난 후 파기하려면 알람 이벤트를 이용하도록 해요.
알람 이벤트(Alarm 0) 하나를 추가하고, 오브젝트 파기 이벤트를 작성하도록 합시다.

 



     ★ obj_pl_att - Alarm 0 이벤트

     instance_destroy();



이 공격 오브젝트도 depth설정이 필요하겠죠.
End Step 이벤트를 추가하고, depth를 설정합니다.

 



     ★ obj_pl_att - Alarm 0 이벤트

     depth=floor(room_height-y);



이제 공격에 대한 설정을 만들어 봅시다.
적들의 parent 오브젝트(obj_enemy)와의 충돌 이벤트를 추가하고, 이전에 설정했었던 적 공격(obj_en_att) 이벤트를

응용하여 만들어 보아요.



     ★ obj_pl_att - obj_enemy와의 충돌 이벤트

     if check=0{//공격 체크

     dmg=att-floor(other.unit_def*0.5);//피해를 입힐 데미지 최대 수치


     if dmg<=0{if irandom(3)=1{dmg=0;}else{dmg=1;}}//데미지가 0일때 0 또는 1의 데미지 재설정

     else{dmg=max(1,irandom(dmg));}//데미지가 0이 아니라면 데미지는 랜덤

     if irandom(5)=1{dmg=att;}//1/6확률로 최대수치의 데미지를 입힘

     if other.hp>dmg{other.hp-=dmg;}else{other.hp=0;}//적의 유닛 HP를 감소
     other.x+=lengthdir_x(5,direction);
     other.y+=lengthdir_y(5,direction);//해당 적 유닛(other)을 약간 밀어버림

     other.stun=10;//적(other)의 색을 빨간색으로 표시


     it=instance_create(other.x,other.y,obj_ef1);//데미지 이펙트 발생
     it.spr=spr_effect1;
     it.img=1;
     it.sca=0.5;

     it=instance_create(other.x,other.y-8,obj_point_text);//데미지 수치 표시
     it.point=dmg;
     it.vspeed=-1;

     check=1;}//적 유닛을 한번 공격하면 더이상 공격을 못하도록 변수를 변경함


 

적의 공격과 비슷하지요. 다만, 다른 것이 있다면 공격 횟수입니다.
이것은 공격 오브젝트가 파기되기 전에 공격하는 것으로, 파기될때까지 공격은 1회로 한정하는 것입니다.

즉, 처음 충돌하는 1개의 적만 공격할 수 있다는 것이죠(check변수로 공격을 체크).

이제 이 공격 오브젝트를 플레이어 오브젝트에서 생성하면 됩니다.
플레이어 오브젝트(obj_player)로 이동해서 Step 이벤트에 공격에 대한 이벤트를 작성하도록 해요.
먼저 어떤 키를 사용할 것인지, 어떻게 공격을 만들것인지 생각해보고 적용하도록 해요.
Create 이벤트에 공격에 필요한 변수(공격 스위치등)들을 추가 선언합니다.

 



     ★ obj_pl - Create 이벤트

     att_sw=0;
     att_type=0;



그리고 Step 이벤트에 공격 이벤트를 작성하도록 해요.
강좌에선 [Z]키를 사용하겠습니다.

 



     ★ obj_pl - Step 이벤트

     //-------------------------▼ 이벤트 추가
     if keyboard_check_pressed(ord("Z")) && key_disable=0{
     if att_sw=0{

     aa=instance_create(x,y,obj_pl_att);
     aa.att=global.player_dmg_total;//공격수치 입력
     aa.direction=direction;//방향은 플레이어의 방향
     aa.alarm[0]=10;//공격 오브젝트 파기될때까지 딜레이
     aa.speed=1.5;//발사 속도


     att_sw=1;//공격 스위치 변경
     alarm[0]=10;//재공격을 위해 딜레이를 줌

     }
     }



재공격을 위해 알람 이벤트(Alarm 0)를 추가하고, 공격 스위치 변수를 초기화합니다.

 



     ★ obj_pl - Alarm 0 이벤트

     att_sw=0;



음... 칼날만 나가니 뭔가 밋밋하지요.
플레이어의 동작도 추가해보도록 해요.
먼저 방향별로 이미지를 준비하도록 합니다.
강좌에선 4방향이니, 4장만 준비하도록 하겠습니다.

 

 

(▲방향별 공격 이미지)


물론 이미지를 애니메이션별로 준비하여 스프라이트로 구성해도 됩니다.
준비된 이미지를 각각의 스프라이트로 구성합니다.

 

 

(▲방향별 공격 스프라이트 이미지)


전에 이동 스프라이트를 배열에 할당하는 방법을 해보셨죠.
그것과 마찬가지로 플레이어 오브젝트의 Create 이벤트에 방향별 배열을 만들어 각각 스프라이트들을

할당하도록 합시다.

 



     ★ obj_pl - Create 이벤트

     spr_att[0]=spr_pl_0_att;
     spr_att[1]=spr_pl_90_att;
     spr_att[2]=spr_pl_180_att;
     spr_att[3]=spr_pl_270_att;



그리고 Draw 이벤트에서 공격 중일 때 공격 이미지를 표시하도록 해요.

 



     ★ obj_pl - Draw 이벤트

     var col;
     col=c_white;
     if stun>0{col=c_red;}

     //-------------------------▼ 조건문 추가
     if att_sw=0{//공격중이 아닌가?
     //-------------------------▲ 조건문 추가

     if move_on=0{
     draw_sprite_ext(spr_move[unit_dir],0,x,y,1,1,0,col,1);
     }else{
     draw_sprite_ext(spr_move[unit_dir],-1,x,y,1,1,0,col,1);
     }

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

     else{//공격중인가?
     draw_sprite_ext(spr_att[unit_dir],0,x,y,1,1,0,col,1);//공격 이미지 표시
     }

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


이것은 공격 스위치 변수인 att_sw가 1일때, 즉, 공격중일때 공격 이미지를 방향별로 표시하고, 공격중이 아니면

대기 이미지 또는 이동 이미지를 표시하게 됩니다.

간단하죠?

굳!

 

만약 플레이어의 공격 모션이 애니메이션이라면 공격 키를 눌렀을 때, 서브 이미지를 초기화해야합니다.

 



     ★ obj_pl - Step 이벤(공격 모션이 애니메이션인 경우)

     if keyboard_check_pressed(ord("Z")) && key_disable=0{
     if att_sw=0{
     aa=instance_create(x,y,obj_pl_att);
     aa.att=global.player_dmg_total;
     aa.direction=direction;
     aa.alarm[0]=10;
     aa.speed=1.5;
     //-------------------------▼ 서브 이미지 초기화
     image_index=0;
     //-------------------------▲ 서브 이미지 초기화
     att_sw=1;
     alarm[0]=10;
     }
     }



그래야 공격키를 눌렀을때 처음부터 애니메이션이 재생되겠죠.

만약 초기화를 하지 않게 되면 공격했을때의 일반 애니메이션을 재생하다, 공격애니메이션을 재생하니

이전 애니메이션 프레임 번호가 그대로 유지되어 들쑥날쑥해져버립니다.

그렇기 때문에 스프라이트 애니메이션을 제대로 재생하려면, 스프라이트가 바뀔때 마다 한번씩은 초기화를

해주어야 합니다.

[참고]
     image_index는 지정한 스프라이트의 서브이미지 번호입니다.

그리고 Draw 이벤트에서는 오브젝트에 지정된 스프라이트를 행동에 따라 변경해야합니다.

 



     ★ obj_pl - Draw 이벤트(공격 모션이 애니메이션인 경우)

     var col;
     col=c_white;
     if stun>0{col=c_red;}

     if att_sw=0{//공격중이 아닌가?
     sprite_index=spr_move[unit_dir]; ◀스프라이트를 교체
     if move_on=0{
     draw_sprite_ext(spr_move[unit_dir],0,x,y,1,1,0,col,1);
     }else{
     draw_sprite_ext(spr_move[unit_dir],-1,x,y,1,1,0,col,1);
     }

     }

     else{//공격중인가?
     sprite_index=spr_att[unit_dir]; ◀스프라이트를 교체
     draw_sprite_ext(spr_att[unit_dir],-1,x,y,1,1,0,col,1); ◀서브이미지에 -1
     }



sprite_index로 스프라이트를 교체하는 것은 지정한 sprite의 서브이미지 수만큼 애니메이션이 재생되기

때문에 스프라이트를 교체함으로써 애니메이션을 모두 재생하기 위함입니다.
예를들어 오브젝트에 지정한 스프라이트의 서브 이미지가 3장이고, 재생하려는 이미지가 10장이라면 실제 표시되는

이미지의 수는 3장만 재생되게 됩니다.
그래서 모두 재생하려면 오브젝트의 지정한 스프라이트를 sprite_index로 이용해 변경해야 합니다.

음. 대충 이런 식으로 할 수도 있겠지요.
여러분이 만들고 있는 구성에 맞게 제작하시면 됩니다.

 

 

 




◈레벨업 시스템(obj_system)

 
경험치가 완전히 차게 되면, 레벨업을 하게 되지요. 그리고 그에 따른 각종 플레이어의 능력치 또한 오르게 됩니다.
이러한 레벨업 시스템을 만들어봅시다.
오브젝트를 새로 만들어 설정해도 좋지만, 강좌에선 이전에 만들었던 시스템 오브젝트(obj_system)을 이용하도록
하겠습니다.
시스템 오브젝트(obj_system)로 이동해서 End Step 이벤트를 추가하고, 여러분이 생각하신 레벨업 설정을 하도록 해요.

 



     ★ obj_system - End Step 이벤트

     if global.player_exp>=global.player_exp_max{//경험치가 최대가 되면 능력치가 오름

     global.player_LV+=1;//레벨업

     global.player_hp_max+=10*global.player_LV;
     global.player_hp=global.player_hp_max;
     global.player_mp_max+=(10*global.player_LV)+global.player_int;
     global.player_mp=global.player_mp_max;

     global.player_str+=2;
     global.player_def+=1;
     global.player_int+=2;
     global.player_dex+=1;
     global.player_dmg+=3;

     global.player_exp_max=floor(global.player_exp_max*1.5);//최대 경험치를 올림. 소수점일경우 소수점은 버림

     global.player_exp=0;//경험치를 초기화함
     }

     set_eqm_statistics();//장비 장착 및 능력치 설정



이것은 경험치가 최대에 이르렀을때, 레벨업하여 각종 능력치를 올리고, 다시 경험치는 초기화하여
다음 레벨업을 대기하는 것입니다.
강좌에선 간단하게 설정했지만, 여러분이 생각하신대로 설정하시면 됩니다.

 

 

 


◈게임 재시작(obj_game_check)

 
플레이어가 죽었을때 재시작하는 이벤트도 작성해볼까요.
이 설정을 위해 오브젝트(obj_game_check)를 하나 만듭니다.

 

(▲게임 재시작 오브젝트)


Create 이벤트를 추가하고, 약간의 딜레이를 위해 알람 이벤트를 실행하도록 합니다.

 



     ★ obj_game_check - Create 이벤트

     alarm[0]=200;



알람 이벤트(Alarm 0)를 추가하고, 플레이어를 다시 생성하는 이벤트를 작성합시다.

 



     ★ obj_game_check - Alarm 0 이벤트

     global.player_hp=global.player_hp_max;
     global.player_mp=global.player_mp_max;//체력과 마나를 원상태로 되돌림

     instance_create(global.map_xstart,global.map_ystart,obj_pl);//플레이어를 생성함

     instance_destroy();//이 오브젝트를 파기함



이것은 체력과 마나를 원상태로 복구하고, 플레이어를 맵의 시작 좌표에 생성하는 것입니다.

이제 이 오브젝트를 플레이어 오브젝트(obj_pl)Destroy 이벤트에서 생성하면 됩니다.

 



     ★ obj_pl - Destroy 이벤트

     //-------------------------▼ 이벤트 추가
     instance_create(0,0,obj_game_check);



이렇게 하면 플레이어가 죽었을때 플레이어 오브젝트는 파기되고, 다시 얼마간의 딜레이 후 룸의 시작되는 좌표에
능력치가 복구된 다음 오브젝트를 재생성하게 됩니다.

설정이 끝났네요.
제대로 되는지 테스트 해보도록 합시다.

 

 

(▲테스트 화면)

 

후우~ 잘따라 해보셨는지 모르겟네요.

드디어 적 유닛이 하나 완성되었었고, 어느정도 게임의 틀이 잡혔습니다.

물론 여러분이 생각하셨던 유형의 적은 아니었지만 이것은 단지 예일뿐, 대체로 이런식으로 작동되고 만들 수

있다는 것을 보여드린 것입니다.

여하튼 필요하신 부분을 응용하여 여러분만의 게임을 만드시면 되는 것이죠.

 

 

 

 

 

 

 

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

 

RpgX-03.gmk
다운로드

 

RpgX-03.exe
다운로드

 

 

300x250

댓글