probe 완료: ScreenTouchEvent/ScreenToUIPosition 실측, UITouchReceiveComponent 드래그 이벤트 확인. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.4 KiB
5.4 KiB
전투 연출 (P3) — 설계
- 날짜: 2026-06-11
- 대상:
tools/deck/gen-slaydeck.mjs(카드 드래그·연출·적 턴 시퀀스), 생성물 - 상태: 승인됨(사용자 사전 위임 — P2~P5 일괄 진행 지시). 로드맵 P3/5.
1. 목표 (사용자 요구)
- 카드 드래그→몬스터 지정: 카드를 끌어 특정 몬스터에 놓아 사용(클릭 대체).
- 공격 모션 후 데미지: 공격 카드 사용 시 연출(스킬 이펙트) 후 몬스터가 피해.
- 몬스터 개별 차례: 적 턴에 몬스터가 한 마리씩 순서대로 행동(행동자 표시).
- 데미지 숫자 표시·사망 연출 등 게임필 보강.
2. 타당성 (probe 완료)
maker_mouse_inputdown →ScreenTouchEvent발화 +ScreenToUIPosition변환 실측 일치(카드2 위치).MOD.Core.UITouchReceiveComponent: UI 엔티티에 부착 시UITouchBeginDragEvent/UITouchDragEvent/UITouchEndDragEvent/UITouchDownEvent/UITouchUpEvent제공(공식, Client). 드래그는 이걸 사용.- 몬스터 world→screen(
_UILogic:WorldToScreenPosition)은 P1에서 검증됨 — 드롭 판정에 재사용.
3. 설계
3.1 카드 드래그 타겟팅
- 손패 Card1~5 엔티티에
MOD.Core.UITouchReceiveComponent추가(생성기 componentNames+컴포넌트). - 컨트롤러 상태:
DragSlot(0=없음),DragOrigin(원위치 Vector2),DragMoved(boolean). BindButtons에서 카드별로 connect:UITouchBeginDragEvent→ CombatOver 아니고 손패에 카드 있으면DragSlot=i, 원위치 저장(CARD_XS[i]상수로 복원 가능하므로 저장은 단순화 가능 — 원위치 = (CARD_XS[i], 0)).UITouchDragEvent→ 카드anchoredPosition = ScreenToUIPosition(TouchPoint) - CardHandOffset(CardHand 부모 중심의 UI 좌표 보정값은 런타임 계산: 카드 부모 CardHand의 화면상 중심 = UI(0, -360) → 보정 상수로 굽기).UITouchEndDragEvent→ResolveCardDrop(i, TouchPoint)후 카드 위치 복원.
ResolveCardDrop(slot, screenPoint):- 카드 kind 조회. Attack: 생존 몬스터 중 화면 거리(몬스터 world→screen vs screenPoint) 최소이고 임계(예: 200px) 이내인 몬스터 →
SetTarget(그 몬스터)후PlayCard(slot). 임계 밖이면 취소(복귀만). - Skill: 드롭 위치가 손패 위(화면 y 기준 카드 영역 위쪽, 예: screen y > 화면 40%)면
PlayCard(slot), 아니면 취소.
- 카드 kind 조회. Attack: 생존 몬스터 중 화면 거리(몬스터 world→screen vs screenPoint) 최소이고 임계(예: 200px) 이내인 몬스터 →
- 기존 카드 ButtonComponent 클릭
PlayCard바인딩 제거(드래그와 충돌 방지, 사용은 드래그로 일원화 — STS 방식). 몬스터 슬롯 클릭 SetTarget은 유지(타겟만 바꾸는 보조 수단).
3.2 공격 연출 → 데미지 (PlayCard Attack 시퀀스)
CombatHud/SkillFx엔티티 1개(96×96 이미지 스프라이트, 평소 숨김).- PlayCard(Attack) 흐름 변경: 에너지 차감·손패 제거·렌더는 즉시, 데미지는 지연:
ShowSkillFx(targetIndex, c.image): 타겟 몬스터 world→screen 위치에 SkillFx 표시(ImageRUID=카드 이미지).- 0.35s 타이머 → SkillFx 숨김 +
DealDamageToTarget(damage)+ 데미지 팝업 + RenderCombat + CheckCombatEnd.
- 연출 중 입력 보호:
FxBusy=true동안 PlayCard/EndPlayerTurn 무시(0.35s).
3.3 데미지 숫자 팝업
MonsterSlot{i}/DmgPop(텍스트, 숨김 기본):ShowDmgPop(slot, amount)— "-N" 표시 → 0.6s 후 숨김(타이머; 위치 고정 단순화).PlayerPanel/DmgPop동일(적 공격 시 "-N", 방어 흡수로 0이면 "막음").
3.4 적 개별 차례 (EnemyTurn 시퀀스화)
EnemyTurn→ 비동기 체인으로 재작성:EnemyActIndex=0;EnemyActStep(): 다음 생존 몬스터 찾기 → 없으면FinishEnemyTurn().- 행동 몬스터 슬롯에
ActFrame(적색 하이라이트 — TargetFrame과 별도 자식, 156×108 적색 a0.3) 표시 → 0.45s 타이머 → 의도 적용(Attack: DealDamageToPlayer+플레이어 DmgPop / Defend: block+슬롯 의도 갱신) → ActFrame 숨김 → 다음EnemyActStep()(0.15s 간격). - 플레이어 사망 시 즉시
FinishEnemyTurn().
FinishEnemyTurn():CheckCombatEnd후 미종료면 0.45s 뒤StartPlayerTurn(기존 EndPlayerTurn 후반부 이동).EndPlayerTurn: 손패 버림+렌더 후EnemyTurn()호출로 종료(후속 로직은 FinishEnemyTurn으로 이동).TurnBusy=true로 적 턴 중 입력 차단(FxBusy와 함께 가드).
3.5 사망 연출
KillMonster: 즉시 SetVisible(false) → 0.4s 지연으로 변경(DmgPop과 겹쳐 보이게), 슬롯 비활성은 즉시 유지.
4. 검증
- 생성 결정성·dup 0·sim 14/14(규칙 불변 — 연출 지연만 추가, 데미지 계산 동일).
- 메이커: ①카드를 몬스터2에 드래그→타겟 변경+이펙트→데미지 팝업→HP 감소 ②Skill 카드 위로 드래그→방어 ③드롭 취소(빈 곳) ④턴 종료→적들이 한 마리씩 순차 행동(ActFrame 이동)+플레이어 팝업 ⑤전체 처치 승리 정상.
5. 리스크
- UITouchReceiveComponent와 ButtonComponent 공존(슬롯 클릭/드래그 간섭) — 카드에서 Button 제거하므로 카드는 안전; 몬스터 슬롯은 Button 유지(드래그 없음).
- UITouchDragEvent 빈도/좌표계 — 구현 후 메이커 검증(§4①). 드래그 좌표 보정 상수는 실측 튜닝.
- 비동기 체인 중 상태 변화(연출 중 사망 등) — FxBusy/TurnBusy 가드 + 각 스텝에서 alive/CombatOver 재확인.