레이블이 비트맵월드인 게시물을 표시합니다. 모든 게시물 표시
레이블이 비트맵월드인 게시물을 표시합니다. 모든 게시물 표시

2016년 9월 25일 일요일

4)ActionFighter의 상태 구현_2


4) ActionFighter

지금까지 AF(ActionFighter) 안에서 어떻게 이미지가 그려지는지, 그리고 어떻게 상태가 작동되는지를 설명했습니다. 이번엔 AF가 어떻게 상태를 사용하는지 그리고 어떻게 입력을 받아들여서 처리하는지를 설명하겠습니다.



AF는 다양한 상태를 지닐 수 있어야 합니다. 비트맵월드는 마우스 클릭과 드래그로 스킬을 사용합니다. 그리고 각각의 스킬은 한 개 이상의 상태로 구현되어 있습니다. 이 스킬을 저장하기 위해 AFskillMap이라는 클래스를 사용합니다.



-      AFskillMap




SkillMap의 함수와 변수들입니다.
하나의 skillMap 안에는 해당 객체의 소유AF와 스킬의 초기 상태를 저장하는 slot6개 있습니다. (연속된 다음 상태는 해당 상태의 inputSlot 함수를 통해 생성, 호출합니다)

AddSkill 함수는 원하는 슬롯에 스킬을 초기화 하여 덮어씌우고 getSkill을 통해 해당 슬롯의 레퍼런스를 받아옵니다.






이제 ActionFighter의 변수를 살펴보겠습니다.

입력을 통한 상태 변화는 skillMap의 해당 슬롯값에 저장됩니다. 하지만 입력 이외에도 다양한 상태변화가 필요하고 그러한 상태들은 AF에 직접 저장되어 있습니다.
해당 상태들은 AF가 생성될 때 초기화됩니다.

CurState: 현재 AF의 상태입니다.
CurSkillMap: 현재 활성화 되어있는 skillMap 값입니다.
AtkSkillMap: 마우스 왼쪽 클릭으로 활성화되는 공격형 스킬을 저장하는 스킬맵의 값입니다.
DefSkillMap: 마우스 오른쪽 클릭으로 활성화되는 수비형 스킬을 저장하는 스킬맵의 값입니다.
IdleState: 아무런 행동도 취하지 않을 시 진입되는 상태. idle상태에 대해선 나중에 더 설명하겠습니다.
DamagedState: 공격을 당할 시 진입하게 되는 상태입니다.
DeadState: 차가운 시체가 되는 상태입니다.
PushedState: 특정 조건에 의해 밀려나게 되는 상태입니다.
Downstate: 쓰러진 상태입니다.
EventState: 이벤트씬에서 사용되는 상태입니다.






AF는 상황에 따라 저장된 상태들로 상태 변화를 합니다.

저번 AFstate 설명에서 말했듯 모든 상태 변화는 AFstatechangeState()에 의해 변화됩니다. 그리고 changeState는 보통 AFstate의 내부에서 구현됩니다.
AFcurState의 함수를 호출함으로써 상태를 변화시킵니다.



-      damaged
상대의 공격에 의해 대미지를 받게 되면 curStatedamaged함수를 호출하여 현재 상태에서 취해야 할 행동을 처리합니다.



-      update
매 틱마다 curStateUpdate 함수를 호출합니다.






-      inputSlot

비트맵월드의 특수한 입력 형식입니다. 6방향으로 마우스를 드레그 함으로써 각각의 slot값에 접근할 수 있게 됩니다.
슬롯 입력에 따라 curState가 입력받은 slot값에 따라 처리하게 됩니다. 하지만 일단 그 전에 마우스 입력을 슬롯입력으로 바꾸는 작업이 필요합니다.
 우선 마우스 클릭을 통해 마우스 좌표를 초기화하고 skillMap을 활성화 합니다.



















1차적인 입력 처리는 playerController에서 이루어집니다. 이는 나중에 설명하겠습니다.



해당 그래프는 틱 이벤트의 시퀸스2에서 이어져있습니다.

AF는 매순간 curSkillMap이 활성화되어 있는지 확인합니다. 마우스 입력에 의해 curSkillMap이 활성화 되고 마우스 포인터의 드래그 길이가 일정 거리를 초과하게 되면 각도를 계산하여 curStateinputSlot에 계산된 slot값을 전달해 호출한 후 다시 포인터의 위치를 초기화 시킵니다.



정리하자면 ActionFighterdamaged, update, inputSlot 이벤트를 통해 curState에 접근하여 필요한 기능을 구현하게 됩니다.

이로써 ActionFighter의 대부분의 기능에 대한 설명이 끝났습니다.
다음엔 사용자의 입력을 담당하는 playerController에 대하여 설명하겠습니다.



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를 포함해서 어떻게 동작하는지 설명하겠습니다.

2016년 9월 1일 목요일

2)ActionFighter 와 이미지 드로잉


가장 먼저 비트맵월드에서 가장 중요한 ActinFighter(AF)들을 살펴보겠습니다.


AF PaperCharacter를 상속받아 만든 블루프린트 클래스입니다.


AF는 아주 많은 걸 구현합니다. 하지만 가장 먼저 외부적으로 나타나는 이미지의 변화를 어떻게 구현하는지 소개하겠습니다.



-      캐릭터 플립북



우선 캐릭터의 플립북을 변화시키는 동작을 살펴보겠습니다.

2D 캐릭터는 3D캐릭터와 달리 애니메이션을 저장시켜 하나의 모델을 이동시킬 수 없습니다. 사실 그런 식으로 쓸 수도 있지만 전 별로 마음에 들지 않더군요. 비트맵월드의 AF는 각각의 모션 하나하나 각자의 플립북이 있습니다.



이미지를 그리고 플립북을 만드는 것까진 괜찮습니다. 하지만 이걸 어떻게 AF와 연결할까요?

AF Sprite컴포넌트에 해당 플립북을 대입시키면 됩니다.


이런 식으로.



하지만 이게 그렇게 간단하게 생각할 문제가 아닙니다! 현재는 비트 하나뿐이지만 캐릭터 하나만으로 게임을 완성시킬 순 없습니다. 다양한 캐릭터는 각자 독자적인 이미지를 가지고 있을 겁니다. 그리고 다양한 상황에서 이미지가 바뀌게 될 겁니다.

이렇게 하나하나 플립북을 대입시키기보단 AF의 플립북을 변화시키는 것을 전문적으로 하는 컴포넌트를 만들고 이 컴포넌트가 가진 함수를 통해 AF는 각자 자기가 가지고 있는 플립북 데이터를 불러와 플립북을 변화시키는 편이 효율적일거라 생각했습니다.

그를 위해 필요한 것들이 있습니다.



FlipbookMotionGuide







플립북모션가이드는 AF가 가질 수 있는 모든 모션(플립북)에 대한 열거형입니다.
각각의 AF들은 이 열거형에 맞는 모션에 따른 플립북 값을 가지고 있습니다.
 















AFflipbookComponent




AF의 플립북을 변화시키기 위해 만든 플립북 변화 컴포넌트입니다.


아주 복잡해보이지만 컴포넌트의 이 함수를 통해 AF는 자신이 가진 플립북 값을 간단하게 불러와 플립북을 바꿀 수 있습니다. 최소한 이 복잡한 걸 몇 번이고 반복해서 만들지 않아도 됩니다.

결과적으로 AF는 자신의 모션 플립북 변수값을 변경하는 것만으로 얼마든지 다른 캐릭터를 만들어낼 수 있게 됩니다.
물론 그 리소스는 하나하나 그려야겠지만요. 시무륵
-      ActionMap


해당 장면엔 현재 연출 할 수 있는 이미지가 거의 다 나타나 있습니다.

보시는 것처럼 비트맵월드는 캐릭터의 주변에 원형의 인터페이스인 ActionMap을 가지고 있습니다.


액션맵은 6개의 방향에 슬롯을 가지고 있고 각 방향마다 상황에 맞게 4가지 타입의 이미지를 그릴 수 있어야 합니다.
또한 각 타입의 슬롯들은 서로 겹쳐져서도 그려질 수 있어야 하고 다수가 한번에 그려질 수 도 있어야 합니다.








이제 슬롯을 그리는 방법을 구현할 차례입니다.

슬롯의 구현은 AF안에 집중되어 있습니다. 사실대로 말하면 캐릭터 플립북 변화도 AF안에 있었지만 나중에 컴포넌트의 존재를 알게 되어서 따로 분리시켰습니다. 슬롯의 구현도 분리시키는게 좋지 않을까생각하는데 실행으로 옮기진 않네요.





어찌되었든 슬롯을 구현은 매우 동적으로 이루어집니다. 슬롯은 필요한 때에 새로운 페이퍼 스프라이트 컴포넌트로써 생성되어 그려졌다가 다시 파괴합니다. 이로써 다양한 슬롯들을 자유롭게 그릴 수 있게 됩니다.



CreateSlot

AF의 슬롯을 만드는 함수는 각 타입마다 개별적으로 만들어 각각의 슬롯을 저장하는 배열에 저장하게 됩니다.


CreateSlot함수는 매개변수로 받아들인 슬롯정보값을 분석해 필요한 슬롯의 숫자를 계산한 후 새로운 페이퍼 스프라이트 컴포넌트를 만든 후(예를 들어 123 값을 받으면 3개의 슬롯을 만들어냅니다.)  actionMap에 붙입니다. 이로써 actionMap위에 해당 슬롯이 그려질 수 있게 합니다.



DrawSlot

슬롯을 그리는 것은 위에서 저장한 슬롯셋에 동일한 슬롯정보값을 이용해 해당 위치에 맞는 슬롯 리소스를 컴포넌트에 대입시킵니다. 이 중 충전시간이 그려지는 nextSlot의 경우 현재 충전량을 가져와 해당 충전량에 맞는 리소스를 그립니다.



ClearSlotSet

슬롯이 필요한 상황이 끝나게 되면 해당 슬롯정보들을 전부 삭제하고 초기화 합니다. 초기화는 모든 슬롯타입이 한번에 이루어집니다.





위의 함수들을 이용해 AF는 게임에 필요한 이미지 드로잉을 구현하게 됩니다.


다음엔 AF가 어떻게 게임 행동을 구현하는지 알아보겠습니다.


2016년 8월 30일 화요일

1) 비트맵월드에 대하여


시작하기 전에 일단 비트맵월드가 어떤 게임인지 소개하도록 하겠습니다.





비트맵월드는 (그리기 쉬운) 초록색 내모난 친구 비트가 다양한 사람들과 싸우며 세상을 구하기 위해 나아가는 이야기입니다.



일단 비트맵월드의 전투 시스템적 기획에 대하여 구체적으로 정리해보겠습니다.



비트맵월드는 1:1 전투를 기본으로 하는 2d액션 게임입니다.
비트맵월드에서 전투를 할 수 있는 캐릭터들을 ActionFighter(AF)라고 칭합니다.
AF들은 몇가지 규칙들을 가지고 전투를 하게 됩니다.


  • 점프는 존재하지 않고 오직 좌우 횡이동만 가능합니다.
  • AF들은 서로 관통해 통과할 수 있습니다.
  • 6개 방향의 스킬이 저장된 ACTIONMAP이 있고 마우스 드래그를 통해 커서를 시작점에서 특정 거리 이동시키면 해당 각도에 맞는 스킬을 사용하게 된다.
  • 적에게 경직을 주는 주 공격은 상, , 3개 중 하나의 공격방향을 가지고 이는 대응되는 방어방향으로 막을 수 있습니다.
  • 적에게 경직을 주는 주 공격은 반드시 준비 단계가 있고 공격 준비에는 일정 시간이 필요합니다.
  • 공격 방향, 충전시간, 방어 방향은 모두에게 보여집니다.
  • 특정 기술은 자동으로 이동하는 기능을 가질 수 있습니다.
  • 특정 기술은 오브젝트를 소환 할 수 있습니다.




  • AF들은 HPSTAMINA를 가지고 있습니다.
  • 특정 입력을 통해 바라보는 방향을 바꿀 수 있고 바라보는 방향에 적이 있을 경우 적의 HPSTAMINA를 알 수 있습니다.
  • 당연히 HP는 공격을 당하면 감소하며 0이 되면 죽습니다. STAMINA가 낮은 상태에서 공격을 당하면 더 많은 HP가 감소합니다.
  • 행동을 하게 되면 STAMINA가 감소합니다. 아무 행동도 하지 않고 있으면 회복됩니다.
  • 공격을 당하면 STAMINA가 감소합니다. 공격을 당해 STAMINA0이 되면 넉백 당하게 됩니다.



// 글로 쓰니 뭔가 복잡해 보이네요, 한번 플래이해보세요! 뭔지 대충 알 수 있을겁니다..



전투를 하는데 필요한 기획은 이 정도인 것 같습니다.
다음부터 위에서 정리한 기능들을 하나하나 어떻게 구현했는지 살펴보겠습니다.


p.s 사실 이렇게 정리 해본 적이 처음이에요. 잘 하고 있는건지 모르겠네요. 어버버버버버

p.s.2 사실 인터넷에 글 쓰는 것도 어제가 처음이에요. @_@ 혹시 제가 뭔가 치명적이고 끔찍한 실수를 하고 있진 않나요?

비트맵월드: 소스 how to make


안녕하세요? 아트정키입니다!
이제부터 언리얼엔진을 이용해 제작 중에 있는 '비트맵월드'라는 이름의 2d액션 게임을 어떻게 만들고 있는지 소개하려고 합니다.

아직 학생이고 배우는 단계에 있기에 여러모로 부족한 점이 많겠지만 앞으로 잘 부탁드립니다. 혹시 궁금한 점이나 더 좋은 방법을 알고 계신다면 댓글로 남겨주세요!



비트맵월드는 오픈소스 프로젝트입니다.

https://www.dropbox.com/s/st3xxshdqez6umd/BitmapWorld.zip?dl=0 에서 언리얼엔진4 프로젝트를 무료로 다운 받을 수 있습니다.

비트맵월드: 소스는 현재 제작 중에 있는 프로젝트로써 기초적인 틀이 다 갖추어지기 전까지 지속적으로
업데이트 할 것입니다.