feat(combat-ui): 전투 UI/HUD 정비 — STS2 배치 (배포 퀄리티 P1) #34

Merged
gahusb merged 10 commits from feature/p1-combat-ui into main 2026-06-11 02:29:52 +09:00
Showing only changes of commit 2265bd7fa1 - Show all commits

View File

@@ -0,0 +1,84 @@
# 전투 화면 UI/HUD 전면 정비 (P1) — 설계
- 날짜: 2026-06-11
- 대상: `tools/deck/gen-slaydeck.mjs`(UI 좌표·신규 엔티티·SlayDeckController 표시 로직), 생성물(`ui/DefaultGroup.ui`·`SlayDeckController.codeblock`)
- 상태: 승인됨 (배포 퀄리티 로드맵 P1/5)
- 로드맵: P1 UI 정비(본 문서) → P2 카드 비주얼(메이플 스킬) → P3 전투 연출(드래그 타겟·개별 턴·공격 모션) → P4 맵 차별화 → P5 시스템 갭
## 1. 배경 / 문제
전투 화면 HUD가 기능별로 따로 추가되며 겹침·산만함 발생. 정량 확인된 문제:
- `DeckHud/EndTurnButton`(y106~164) ↔ `DeckHud/Energy`(y69~111) **5px 겹침** (둘 다 중앙 상단)
- `DeckHud/AllDeckButton`(모든덱보기, x376~564·y106~164)이 버린덱(x524~656·y-85~101)과 5px 간격으로 답답
- 막/골드가 화면 모서리(±820, 480) — MSW 시스템 크롬(좌상 채팅, 우상 메뉴)과 시각 충돌
- 플레이어 HP/방어가 좌하단 텍스트 2줄(패널감 없음)
- 타겟 표시가 의도 텍스트의 `[타겟]` 프리픽스뿐, 몬스터 슬롯 이름/HP 가독성 낮음
- 메뉴/캐릭터선택 화면 뒤로 전투 HUD가 비치는 흐름 버그(가시성 호출 산발)
## 2. 목표
STS2 스타일 배치로 전투 화면을 재구성해 겹침 0·시각 위계 확립. 기능 변경 없음(레이아웃·시각·표시 로직만).
## 3. 설계
### 3.1 하단 HUD 재배치 (DeckHud, parent 1280×330)
| 요소 | 현재 | 변경 |
|---|---|---|
| 에너지 | 중앙 (0,90) 텍스트 | **좌측 오브 패널** (-560,40) 96×96 어두운 원형 패널 + "3/3" 대형(36) + "에너지" 소라벨 |
| 턴 종료 | 중앙 (0,135) 170×58 | **우측 대형 버튼** (560,40) 200×64, fontSize 28 |
| 뽑을덱 | (-590,8) | 유지, 라벨 위치 정리 |
| 버린덱 | (590,8) | 유지 |
| 모든덱보기 | (470,135) | **상단 바로 이동** (§3.2) |
- 에너지 오브(-560±48=-608~-512)와 뽑을덱(-590±66=-656~-524)은 y로 분리: 뽑을덱 y8±93=-85~101, 오브 y40±48=-8~88 → x 겹침 구간에서 y도 겹침 → **오브를 (-560, 130)으로** 배치(뽑을덱 위). 같은 식으로 턴종료 (560, 130)(버린덱 위). 카드(CardHand y180 중심, 카드 h250 → y55~305)와 x 비겹침(카드 x -500~500, 오브/버튼 x>±512).
### 3.2 상단 HUD 바 (CombatHud 신규 `TopBar`)
- 반투명 패널 1200×52, (0, 486). 자식: `Floor`(좌, x -540), `Gold`(좌, x -380), `Relics`(중앙, 폭 560), `AllDeckButton`(우, x 520, 150×40).
- 기존 CombatHud의 Floor(±820,480)·Gold·Relics(0,430) 엔티티를 TopBar 자식으로 대체(기존 경로 제거, 컨트롤러 SetText 경로 갱신).
- AllDeckButton은 DeckHud에서 TopBar로 이동(바인딩 경로 갱신).
### 3.3 플레이어 패널 (CombatHud `PlayerPanel`, 좌하)
- 패널 300×96, (-760, -480) [화면 좌하단, DeckHud 영역 밖]. 자식: 이름라벨("플레이어"), HP바(HpBarBg/HpBarFill, 폭 220 — `SetHpBar` 재사용, 폭 파라미터화), HP 텍스트("71/80"), 방어 뱃지(56×40 청색 패널+숫자, 방어 0이면 숨김).
- 기존 PlayerHp/PlayerBlock 텍스트 엔티티 제거, RenderCombat 갱신.
- ⚠️ SetHpBar가 현재 HP_BAR_W=120 고정 → `SetHpBar(path, hp, maxHp, width)`로 폭 인자 추가(몬스터 120/140, 플레이어 220).
### 3.4 몬스터 슬롯 가독성 + 타겟 프레임
- `MonsterSlot{i}``TargetFrame` 자식 추가: 슬롯보다 약간 큰 **단일 반투명 골드 패널**(156×108, displayOrder 최하 — 슬롯 내용 뒤 배경 하이라이트). RenderCombat에서 `i==TargetIndex`인 슬롯만 enable.
- 의도 텍스트에서 `[타겟] ` 프리픽스 제거.
- 이름 fontSize 20→22, Hp 18→20, HP바 폭 120→140(HpBarBg/Fill·SetHpBar 호출 일치), Intent 색상: kind=Attack→(1,0.45,0.35), Defend→(0.5,0.75,1).
### 3.5 HUD 가시성 상태 통일 (`ShowState`)
- 컨트롤러에 `ShowState(state)` 단일 메서드: state별 HUD on/off 표.
| state | 켜짐 |
|---|---|
| `menu` | MainMenu |
| `charselect` | CharacterSelectHud |
| `map` | MapHud만 (층/골드는 MapHud 진입 전 RenderRun으로 갱신된 TopBar가 꺼져도 무방 — 맵 화면 자체 표시는 현행 유지) |
| `combat` | CombatHud, DeckHud, CardHand |
| `reward` | RewardHud (+CombatHud 유지) |
| `shop` / `rest` | ShopHud / RestHud |
- `OnBeginPlay` 시작 시 전 HUD off → `ShowState("menu")`. 기존 산발적 `SetEntityEnabled` 호출을 ShowState 호출로 치환(ShowMainMenu/StartNewGame/ShowMap/PickNode/StartCombat/OfferReward/PickReward/ShowShop/ShowRest/LeaveNode/CheckCombatEnd).
- 흐름 버그(메뉴 뒤 카드 비침)는 이걸로 해소.
### 3.6 시스템 UI
- 조이스틱/공격·점프 버튼: 기존 숨김 유지(upsertUi).
- 채팅/우상단 메뉴 숨김은 구현 단계에서 MSW API(`_UIService`/WorldConfig) 확인, 불가하면 본 레이아웃(모서리 회피)으로 충분 — 실패해도 P1 완료 조건에 미포함.
## 4. 변경 파일
| 파일 | 변경 |
|---|---|
| `tools/deck/gen-slaydeck.mjs` | upsertUi 좌표/엔티티 재구성(TopBar·PlayerPanel·TargetFrame·오브·버튼 이동), SlayDeckController(ShowState·RenderCombat·SetHpBar(width)·바인딩 경로) |
| 생성물 | `ui/DefaultGroup.ui`·`SlayDeckController.codeblock` 재생성. `common.gamelogic` 불변 예상 |
## 5. 범위 제외 (후속 페이즈)
카드 아트/스킬 아이콘·의도 아이콘(P2), 드래그 타겟·공격 모션·개별 턴·부채꼴 손패(P3), 맵(P4), 시스템(P5).
## 6. 검증
- 생성기 2회 실행 동일(결정적), JSON·중복 id 없음, sim 14/14(불변).
- **좌표 겹침 정적 검사**: 하단 HUD 요소 AABB 페어와이즈 겹침 0 (검증 스크립트로 확인).
- 메이커 플레이테스트: 메뉴→캐릭터선택→맵→전투(타겟 프레임 이동·에너지/턴종료 위치)→보상→상점→휴식 전 화면 스크린샷, 겹침·비침 0 확인.
## 7. 리스크
- SetHpBar 시그니처 변경 → 호출 3곳(몬스터·플레이어) 일치 필요.
- 기존 경로 제거(Floor/Gold/Relics/PlayerHp/PlayerBlock/AllDeckButton) 시 컨트롤러 SetText/바인딩 경로 누락 주의(grep로 구경로 0 확인).
- 사용자 PR(deck inspector·character select)이 추가한 UI와의 상호작용 — DeckAll/DeckInspect sortingOrder 오버라이드(2000/1900) 유지.