2016년 9월 5일 월요일

3)ActionFighter의 상태 구현





게임을 만들려고 했을 때 가장 고민이었던 부분은 다양한 캐릭터의 행동을 어떻게 구현하는가 였습니다. 행동을 구현하는데 가장 힘들었던 점은 각각의 행동이 서로 간섭하지 않는 거였죠.

여러가지 알아보던 중 상태 패턴이란 것을 알게 되었고 이를 이용하기로 했습니다.

상태 패턴은 간단히 말해서 캐릭터의 상태(이동, 공격 준비, 타격 당함 등등)를 하나의 객체로 만들어서 구현하는 것입니다.

비트맵월드에 적용시킨 상태 패턴을 보며 좀 더 자세히 설명하겠습니다.


- AFstate


비트맵월드에서의 상태는 모두 AFstate라는 클래스를 상속받습니다. AFstate는 그 자체만으로 쓰이진 않지만 모든 상태들이 공유하는 공통된 기능을 구현하고 있습니다.

AFstate의 변수들부터 살펴보겠습니다.

 
ownerRef: 현재 상태를 소유하고 있는 AF의 레퍼런스. 초기화 할 때 레퍼런스를 연결시켜줍니다.
state: AF의 상태를 표현하는데 필수적인 요소들을 가지고 있는 구조체입니다.



 
그 외 내부적으로 사용되는 변수들과 해당 상태가 가지고 있는 다음 상태에 대한 레퍼런스등에 대한 정보가 있습니다.


AFstate는 상태를 구현하기 위한 몇가지 함수들을 가지고 있습니다.
Initiate: 객체가 처음 생성 될 때 호출하는 함수입니다. 상태별로 필요한 초기화를 합니다.

Update: 매 틱마다 발동되는 함수입니다. 해당 상태에서 지속적으로 이루어져야 할 일을 구현합니다.
  • 충전시간의 최신화와 충전시간에 따라 이미지가 바뀔 수 있는 atkSlotnextSlot을 매번 최신화 합니다.
  • 스태미나 사용량에 따라 시간에 따라 스태미나를 일정량 변화시킵니다.
  • 현재 AF의 스킬맵을 확인해서 필수 스킬맵이 있을 경우 그것과 맞지 않다면 idel상태로 상태를 변화시킵니다.
*스킬맵: AF가 입력을 통해 불러올 수 있는 상태를 저장 해놓는 객체입니다. 마우스 우클릭, 좌클릭으로 각기 다른 스킬맵을 불러올 수 있습니다.
Enter: 해당 상태에 들어올 때 한번 발동되는 함수입니다.
  • 상대에게 대미지를 주는 상태일 경우 이전 상태에서 받은 충전시간을 이용해 최종 대미지를 계산합니다. 상대에겐 이 최종 대미지가 들어가게 됩니다.
  • 상태가 가진 모션에 따라 AF의 스프라이트를 변경시깁니다.
  • 슬롯을 그리기 위해 슬롯 컴포넌트를 만들고 실시간으로 그려질 필요 없는 defSlotpreSlot을 그립니다.

Leave: enter와 마찬가지로 해당 상태에서 나갈 때 발동되는 함수입니다.
  • 해당 상태의 충전시간을 다시 0으로 초기화합니다.
  • 만들었던 슬롯들을 제거하고 초기화합니다.
  • 현재 상태의 충전률을 반환합니다.

InputSlot: AF의 입력을 받을 시 실행되는 함수입니다.
  • 상태의 nextSlot 정보와 입력 받은 Slot 정보가 같고, 다음 상태에 대한 정보가 있다면 다음 상태로 변경합니다. 이 과정에서 만약 다음 상태에 대한 실질적인 객체가 아직 생성되지 않았다면 객체를 만들고 이미 객체가 있다면 해당 객체를 사용합니다.

Damaged: 피격 당했을 때 발동되는 함수입니다.
  • 공격을 당할 시 공격자측의 최종대미지구조체를 받아서 상태의 defSlot정보를 읽어 방어가 성공했는지 아닌지 판별하여 반환합니다.
  • 방어가 실패했을 경우 공식에 따라 hpstamina를 변화시킨 후 상태를 변화시킵니다.

*대미지 계산 공식
비트맵월드는 staminahp가 연관되는 대미지 계산방식을 가지고 있습니다.

그리고 그를 위한 대미지 구조체가 필요합니다.




공격방향이 방어방향을 피해 공격에 성공했을 경우 총 3가지 형식의 대미지에 의해 피해가 결정됩니다.

피해량 = 순수 대미지 + (일반 대미지 스태미나/2) 해당 피해를 받은 후 스태미나대미지에 의해 스태미나가 감소하게 됩니다.

피해를 받은 후 stamina0일 경우 넉백 상태로 변하게 되고 hp0일 경우 죽게 됩니다.



ChangeState: 상태를 변경시킬 때 쓰이는 함수입니다. 이 함수 내에서 상태의 enterleave 함수가 구현되어 사용됩니다.

모든 상태의 변경은 이 함수를 통해서만 이루어집니다.


거의 대부분의 상태는 AFstate의 함수에 자신만의 기능을 추가시켜 사용합니다. 몇몇 특정 상태는 함수를 완전히 바꿀 수도 있지만 함수의 호출 목적은 변하지 않습니다.

다음엔 ActionFighterAFstate를 포함해서 어떻게 동작하는지 설명하겠습니다.

댓글 없음:

댓글 쓰기