game/prompt/25_battle_visual_effects.md

3.6 KiB

25. 전투 시각 효과 및 로직 개선 (Battle Visual Effects & Logic)

1. 개요 (Overview)

이 작업은 텍스트 로그에만 의존하던 전투 시스템에 시각적 피드백을 추가하여 타격감과 상황 인지력을 높이는 것을 목표로 했습니다. 데미지 수치와 공격/방어 행동에 따른 이펙트를 화면상의 캐릭터 위치에 표시합니다. 또한 적의 방어 로직을 선제적으로 적용하여 전략성을 강화했습니다.

2. 변경 사항 (Changes)

A. 데이터 모델 (Data Models)

  • lib/game/model/damage_event.dart (신규): 데미지 발생 이벤트를 정의 (데미지 양, 대상, 색상).
  • lib/game/model/effect_event.dart (신규): 행동 이펙트 이벤트를 정의 (행동 타입, 리스크 레벨, 대상).

B. 상태 관리 (State Management - BattleProvider)

  • StreamController 도입: damageStreameffectStream을 통해 BattleScreen으로 비동기 이벤트를 전달.
  • 이벤트 발행:
    • playerAction: 플레이어의 공격/방어 성공 시 적절한 EffectEvent 발행.
    • _enemyTurn: 적의 행동 시 EffectEvent 발행.
    • _applyDamage: 데미지 적용 시 DamageEvent 발행.

C. UI 구현 (BattleScreen)

  • 플로팅 위젯 (_FloatingDamageText, _FloatingEffect):
    • AnimationController를 사용하여 위로 떠오르거나(DamageText), 확대/축소되는(Effect) 애니메이션 구현.
    • 애니메이션 종료 시 자동으로 리스트에서 제거되도록 onRemove 콜백 구현.
  • 위치 계산 및 렌더링:
    • GlobalKey를 사용하여 캐릭터(RenderBox)의 화면상 위치를 파악.
    • WidgetsBinding.instance.addPostFrameCallback을 사용하여 빌드 완료 후 안전하게 위치를 계산하고 setState 호출 (빌드 에러 방지).
    • Stack 위젯 내에 Positioned로 이펙트 위젯들을 오버레이.
  • 이펙트 다양화:
    • Attack: 리스크 레벨에 따라 아이콘 변경 (Safe: close, Normal: flash_on, Risky: whatshot) 및 색상/크기 차별화.
    • Defend: 리스크 레벨에 따라 방패 아이콘(shield)의 색상 및 크기 변경.

D. 전투 로직 개선 (Logic Improvements)

  • 선제 방어 (Pre-emptive Defense):
    • 적의 방어 행동(Defend)은 플레이어 턴이 시작되기 전(_generateEnemyIntent)에 미리 적용되도록 변경.
    • 이로 인해 플레이어는 적의 증가된 방어도를 보고 전략을 세울 수 있으며, 공격 시 방어도가 정상적으로 적용됨.
    • _enemyTurn에서는 방어 행동을 다시 수행하지 않고 로그만 출력하도록 수정.

3. 핵심 로직 (Core Logic)

  • Stream 통신: Provider는 로직만 처리하고 UI(이펙트)는 Stream을 통해 BattleScreen이 수동적으로 반응하도록 설계하여 결합도를 낮춤.
  • Safe Rendering: 비동기 이벤트 수신 시 UI 갱신 타이밍 문제(setState during build)를 해결하기 위해 addPostFrameCallback 패턴 적용.
  • Pre-emptive Action: 적의 방어는 의도 생성 시점에 즉시 반영하여 턴제 전투의 전략성을 보강.

4. 결과 (Result)

  • 캐릭터가 데미지를 입으면 붉은색(일반) 또는 보라색(출혈) 숫자가 캐릭터 위로 떠오름.
  • 공격 및 방어 시 행동의 강도(Risk Level)에 따라 다른 시각적 이펙트가 캐릭터 위에 애니메이션으로 표시됨.
  • 적이 방어 행동을 선택하면 즉시 방어도가 올라가고 방어 이펙트가 출력됨.