저번 일지에서는 턴(페이즈) 시스템을 만들고, 각자의 턴에 이동을 하도록 만들었습니다. 이번 일지에서는 그리드를 만들고, 그 안에 좌표값과 유닛을 할당하여서 플레이어와 적 유닛이 그리드를 참조해 상호작용하도록 만들었습니다. 이런 류의 게임은 처음 만들다보니 매 순간이 도전이군요. 원래라면 그냥 포기했을지도 모르지만, AI 덕분에 아이디어를 얻고 구현까지 할 수 있어서 다행입니다.
그리드 시스템
지금까지 턴에 따라 유닛이 이동하는 시스템은 만들었지만, 문제는 공격을 어떻게 처리해야 할지 감이 잡히질 않았습니다. 다른 게임이었다면 Area나 Body 같은 물리 엔진을 사용했겠지만, 그리드 턴제 게임에서는 그 방식이 많은 문제를 일으킬 것 같았습니다. 이전에 정지 시스템을 구현할 때 사용한 RayCast2D나 현재 이동 방식인 CharacterBody2D의 move_and_slide()을 겪어보았을 때, 이건 추구할 방향이 아닙니다. 어색한 부분이 꽤 많거든요.
그래서 자료를 찾다보니 그리드 시스템에 유닛과 유닛의 타일 좌표값을 저장해놓고, 그걸 참조해서 상호작용하는 방식이 있었습니다. 그래서 저도 GridManager 클래스를 만들고, 딕셔너리에 타일 좌표값과 유닛 오브젝트를 저장했습니다. 유닛이 움직이면 그에 맞게 좌표값을 변경하고, 특정 좌표에 있는 유닛을 가져와 상호작용할 수도 있습니다.

<전투 흐름>
1. 적 유닛
- 가까운 플레이어에게 이동
- 주변 타일을 체크해서 플레이어가 있는 타일에 공격 예고
2. 플레이어
- 이동 및 카드 사용 (미구현)
3. 적 유닛
- 예고한 타일에 공격 모션 출력 (미구현)
- 해당 타일에 플레이어가 있으면 데미지 주기
카드 시스템

적 유닛의 공격 시스템을 만들었으니 이번에는 플레이어의 공격을 구현할 차례입니다. 저는 카드 형식의 스킬을 사용할 예정이므로 카드 시스템을 만들어보겠습니다. 가장 먼저 카드를 만들고, 그걸 드래그 앤 드랍할 수 있도록 해야 합니다. 방법은 두 가지인데, Control 노드나 Area2D 중 하나를 사용하면 됩니다. 이전에 Control 노드를 사용해서 드래그 앤 드랍을 만든 적이 있는데, 확장성이 나빠서 좀 골머리를 앓았습니다. 그래서 이번에는 Area2D 노드를 사용했습니다.
방법은 대충 마우스 위치에 있는 카드의 Collision을 감지하고 해당 오브젝트를 가져와서 위치를 바꾸는 방식입니다. 이제 카드를 드래그한 상태로 타일맵 그리드 위에 마우스를 가져다 대면 카드의 공격 범위를 표시합니다. 공격 범위 안에 카드를 드랍하면 타일 위 유닛을 체크해서 데미지를 줍니다. 다만, 컨트롤 미스를 고려해서 공격 범위 안에 드랍했지만 타일에 유닛이 없으면 카드가 돌아오도록 설정했습니다.

이번 주는 딱히 기획 고민 없이 기능을 구현하는데 시간을 썼습니다. 솔직히 그리드 시스템 같은 건 너무 막막해서 자료를 찾고 공부하는데 난항을 겪으면서 만들었는데, 막상 만들고보니 설명할 말이 많지 않네요. 카드 시스템은 이후에 카드 리소스를 구성하고 덱을 짤 예정입니다. 그리고 이전에 제가 플레이어블 캐릭터를 두 개 만든다고 했었죠? 생각해보니 최근에 플레이하고 있는 <택티컬 브리치 위자드>와 비슷한 구성이었습니다. 이 게임도 참고해서 기능을 만들어 봐야 겠습니다.
참고자료
[1] Managing unit data in my turn-based strategy game │The Shaggy Dev
https://www.youtube.com/watch?v=dE6oFnyILKY
[2] Unto Deepest Depths Prototype │The Shaggy Dev
https://github.com/theshaggydev/unto-deepest-depths-prototype
[3] Tactical RPG Movement series │GDQuest
https://www.gdquest.com/tutorial/godot/2d/tactical-rpg-movement/
[4] Godot 4 CARD GAME Tutorial #1 Dragging Cards │Barry's Development Hell
https://www.youtube.com/watch?v=2jMcuKdRh2w