arena/context/arena.md

7.5 KiB

Update: Special Effect Camera Focus

  • ArenaScene preloads and creates special-effect animations beside the existing fighter and world-effect assets, then starts startSpecialEffects() for live matches only.
  • During a special cast, beginSpecialEffectCameraFocus() zooms toward the caster, zoomOutSpecialEffectCameraFocus() zooms back out in place when the projectile starts moving, and clearSpecialEffectCameraFocus() restores the previous camera after the configured hold/outro timing.
  • Special focus temporarily takes priority over selected-fighter, spectator, and meteor focus so the Hurt-frame pose and projectile launch are visible.
  • When SPECIAL_EFFECT.CAMERA.CENTER_ON_CASTER_AT_START is enabled, special focus centers the main camera on the caster's location immediately and keeps it snapped there until projectile handoff, then continues the slower follow motion.
  • The Hurt-frame preparation window sets scene.specialEffectPreparationPaused, pauses the scene clock and Arcade Physics, freezes living fighter animations, pauses active combat-object tweens/animations/velocities, and places a blurred battlefield snapshot plus dim layer beneath the raised caster. Camera focus tweening stays active so the zoom-in can complete while combat and world-effect progression are stopped.
  • The projectile is not used as a camera target. Special camera targets are still clamped against the current zoom viewport so the focus stack cannot drag the camera outside the arena bounds.
  • Match restart and match finish both call clearSpecialEffects() so pending timers, projectile objects, caster locks, and special camera tweens do not leak into the next battle.

Update: Elite-Weighted Scene Counts

  • ArenaScene.recordDeath() records an elite death as its represented stackCount, keeping persisted species death totals aligned with the displayed army size.
  • arenaSpectatorCamera.js uses summed stackCount for late/final thresholds, underdog comparison, and weighted team center positions. A match containing two large compressed armies therefore does not enter final-combat camera mode at match start.
  • Minimap dots remain physical fighter markers; an elite is visible as its single large battlefield representative while numeric population remains in the scoreboard.

Update: Graphics Minimap And HUD Candidates

  • The minimap is drawn during live matches by ArenaScene as a lightweight Graphics overlay through a dedicated minimap-hud camera instead of reusing the field camera. Presentation/waiting mode hides it.
  • The main camera ignores the minimap graphics object, and the HUD camera ignores field objects as they are added to the scene. Minimap rendering uses team-colored living fighter dots and the main camera viewport rectangle, so the minimap frame stays fixed while the main camera follows combat or meteor focus.
  • ArenaScene refreshes HUD candidates on an interval, choosing selected fighters plus nearby visible fighters when zoomed in, then releases unused health-bar HUD pool slots. Battlefield name text is not shown.

Context: Arena & Scene

1. 모듈별 상세 역할 (src/game/arena/)

  • ArenaScene.js: Phaser 씬의 생명주기와 전반적인 오케스트레이션을 담당합니다. update() 매 프레임마다 전투원 상태를 체크하고, 카메라 이동 및 UI 모듈 호출을 조율합니다.
  • arenaRenderer.js: 아레나 배경 그래픽, 타일 및 팀별 스타팅 영역 오버레이 렌더링을 담당합니다.
  • arenaSpectatorCamera.js: 관전 모드 시점 계산 및 카메라 포커싱 로직을 담당합니다. 생존 인원에 따른 지능형 카메라 추적 알고리즘이 구현되어 있습니다.

2. 주요 로직 구현 세부 사항

지능형 카메라 추적 (Lerp & Jittering 방지)

카메라가 소수점 단위의 평균 좌표를 즉시 따라가면 화면이 떨려 보일 수 있습니다. 이를 방지하기 위해:

  1. 목표 좌표(targetX, targetY)를 Math.round()로 정수화합니다.
  2. 현재 카메라 위치에서 목표 지점까지 매 프레임 0.1의 배율로 거리를 좁혀나가는 Lerp 연산을 수행합니다.
this.cameras.main.scrollX += (targetX - this.cameras.main.midPoint.x) * CAMERA.SPECTATOR_LERP;

자동 관전은 월드 이펙트 임시 시점, 후반 진입과 최종교전 세부 포커싱으로 나뉩니다.

  • 메테오 임시 포커싱: 자동 관전 진입 전 화염 또는 냉기 포격이 시작되면 가장 밀집한 큰 경고 구역의 중심을 임시로 확대 추적합니다. 큰 경고 표시 자체는 WORLD_EFFECT.WARNING_DURATION_MS 이후 사라지며, 카메라는 내부 소형 탄착들이 종료된 뒤 CAMERA.METEOR_FOCUS_HOLD_DURATION만큼 유지한 다음 이전 시점으로 복귀합니다. CAMERA.METEOR_FOCUS_ENABLEDfalse로 설정하면 끌 수 있으며, 수동 선택 시점과 아래 자동 관전 시점이 우선합니다.
  • 후반 자동 관전 진입: 생존 캐릭터가 30명 미만(CAMERA.SPECTATOR_LATE_FIGHTER_THRESHOLD)이 되면 교전 중심(가장 가까운 적 대항쌍)을 포커싱하는 후반 줌을 적용합니다. (2팀만 남았더라도 인원이 많으면 어지러움을 방지하기 위해 자동 관전으로 바로 진입하지 않습니다.)
  • 생존 4명 이하: CAMERA.SPECTATOR_RANDOM_FOCUS_INTERVAL마다 생존 캐릭터 중 한 명을 무작위로 포커싱합니다.
  • 2팀 잔여 & 합계 8명 이하: 더 적은 생존 수를 가진 팀의 중앙을 포커싱하며, 동률이면 기존 교전쌍 중심 포커싱으로 되돌아갑니다.

미니맵 가이드라인

미니맵은 전장 전체를 축소하여 보여주는 독립된 카메라입니다. 주 카메라가 비추는 영역을 계산하여 미니맵 위에 사각형(graphics)을 그려줍니다.

  • camera.displayWidth / zoom 등을 이용하여 현재 월드에서 보이는 실제 영역 크기를 계산합니다.
  • 뷰포트 사각형 좌표는 미니맵 픽셀 격자에 맞춰 반올림하고, 외곽 stroke가 겹쳐 검게 깨지지 않도록 노란 내부 선을 채운 직사각형으로 렌더링합니다.

스타팅 영역 오버레이

스타팅 지점 배치 매치에서는 matchSetup.js가 전장 그리드에서 팀별 중심 셀을 무작위로 뽑아 만든 영역을 ArenaScenearenaRenderer.js에 전달합니다. 렌더러는 각 팀 색상을 낮은 투명도로 채우고 얇게 둘러 실제 스폰 후보 영역을 표시하며, 이 오버레이는 매치 시작 후 5초 동안만 보입니다. 숨김 예약은 Phaser 씬 타이머를 사용하므로 일시정지 시간은 표시 시간에 포함되지 않고, 새 매치가 시작되면 이전 예약을 취소합니다.

씬 상태 관리

  • 프리뷰 모드 (presentationMode): 최초 로드 시 조용히 실행되는 배경 전투입니다. 로컬 저장 옵션과 무관하게 10팀 x 5명 고정 규모로 동작합니다.
  • 일시정지 (setPaused): 실제 전투에서 물리, Phaser 타이머, tween, 스프라이트 애니메이션을 함께 제어합니다. 프리뷰 및 종료된 전투는 제외됩니다.
  • 월드 이펙트 주기: 실제 전투 생성 시 startWorldEffects()를 시작하고, 첫 포격은 WORLD_EFFECT.INTERVAL, 이후 일반 포격은 WORLD_EFFECT.REPEAT_INTERVAL을 사용합니다. 새 매치/종료 때 clearWorldEffects()로 주기 타이머, 잔여 냉각 구역, 메테오 임시 포커스, 캐릭터 감속 배율을 정리합니다. Phaser 타이머를 사용하므로 일시정지 시간은 이 간격과 냉각 지속시간에 포함되지 않습니다.