52 lines
6.3 KiB
Markdown
52 lines
6.3 KiB
Markdown
# Context: Match & UI
|
|
|
|
# Update: Direct Fighter Count Entries And Zone Distribution
|
|
|
|
- Match setup no longer exposes a separate team-size control. Each live entry uses `nickname*N` for that team's assigned fighter count, with plain names defaulting to one fighter.
|
|
- A live match is rejected before replacing the current match only when the participant-assigned count exceeds `SPAWN.MAX_FIGHTER_COUNT`; Slime `spawnMultiplier` and `splitOnDeath` results may grow the actual live population past it.
|
|
- Fighter-count cap validation is reported as a visually distinct warning card below the participant nickname textarea, with requested and allowed counts emphasized separately; it clears when that input changes or a valid live match is submitted.
|
|
- Starting-zone placement assigns one zone per `SPAWN.FIGHTERS_PER_STARTING_ZONE` fighters in each team and puts any remainder in that team's final zone.
|
|
|
|
## 1. 모듈별 상세 역할
|
|
|
|
### 매치 로직 (`src/game/match/`)
|
|
- **`matchSetup.js`**: 매치 초기화, 팀 구성, 스폰 위치 계산을 담당합니다.
|
|
- **`arenaMatchRuntime.js`**: 스폰 클러스터 계산 및 팀 크기 동기화 등 매치 진행 중 헬퍼 기능을 제공합니다.
|
|
|
|
### UI 컴포넌트 (`src/ui/`)
|
|
- **`matchForm.js`**: 설정 폼 제어 및 `localStorage` 설정 유지.
|
|
- **`aboutDialog.js`**: About 버튼/다이얼로그, 개발자정보, 개인정보처리방침 Markdown 표시.
|
|
- **`arenaScoreboard.js`**: 좌측 HUD 레일의 팀 badge 업데이트 및 관전 시점 전환.
|
|
- **`arenaKillLog.js`**: 좌측 하단 킬로그 표시 및 관리.
|
|
- **`battleDeathNotice.js`**: 상단 사망 통계 공지 UI.
|
|
- **`victoryCelebration.js`**: 승리/무승부 축하 연출 (광선, 컨페티, 오디오).
|
|
|
|
## 2. 주요 로직 구현 세부 사항
|
|
|
|
### 매치 설정 및 스폰 배치
|
|
- **닉네임 배수 시스템**: `닉네임*배수` 형식(예: `Alice*2`)을 감지하여 팀 인원을 배수만큼 생성합니다.
|
|
- **구매 배수 보존과 독주 견제**: 배수 팀의 생성 인원과 전투 수치는 결제 이점으로 유지합니다. 월드 이펙트 표적 선정에서는 `team.multiplier`를 구매 지분으로 사용하고, 그 지분을 초과해 생존 중인 팀에만 설정 가능한 추가 표적 가중치를 적용합니다.
|
|
- **스타팅 지점 배치 (멀티 스폰)**: 팀마다 전장 스폰 가능 그리드에서 중심 셀을 무작위로 고르고, 중심 주변 2칸(`5 x 5`)을 해당 팀의 스타팅 영역으로 사용합니다. 배수가 설정된 팀은 배수만큼의 독립적인 스타팅 영역을 할당받아 병력이 분산 배치됩니다. 겹치지 않는 후보가 남아 있는 동안에는 해당 후보를 우선 선택하며, 영역은 매치 시작 후 5초 동안만 팀 색상으로 매우 옅게 표시되고 팀 전투원은 이 안에서만 스폰합니다.
|
|
- **설정 유지**: 닉네임, 인원, 배치 모드는 `localStorage`에 저장되어 재접속 시 복원됩니다.
|
|
|
|
### 전투 화면 레이아웃 (HUD)
|
|
- **팀 Badge**: 좌측 HUD 레일에 배치되며, 클릭 시 해당 팀의 생존 유닛 중 무작위 1명으로 시점을 고정합니다.
|
|
- **팀 Badge 갱신 안정성**: 사망으로 생존 수가 바뀔 때 기존 badge 버튼 DOM을 유지한 채 숫자, 비활성 상태, 선택 강조만 갱신하여 사망 프레임에 겹친 클릭도 시점 고정으로 전달되도록 합니다.
|
|
- **킬로그**: 처치자와 피처치자를 좌우로 배치하고, 피처치자 아이콘에 빨간 X를 겹쳐 사망 관계를 명확히 표시합니다. 캐릭터 idle 시트의 `100x100` 프레임 내 투명 여백을 제외한 중앙 하단 영역을 확대 표시해 작은 아이콘 박스에서도 실루엣이 충분히 보이도록 합니다.
|
|
- **하단 메타 정보**: 전투 화면 우측 하단(`arena-meta` 컨테이너)에 방문자 카운터와 About 버튼이 Pill(알약) 형태로 디자인이 통일되어 나란히 고정 배치됩니다. 드로어가 열려도 동일한 위치를 유지합니다.
|
|
- **모바일 레이아웃**: 실제 전투 시작 시 모바일에서는 옵션 drawer를 자동으로 접고, 상단 팀 HUD는 옵션 버튼 폭을 제외한 영역에 두 줄로 배치됩니다. 이때 데스크톱의 고정 가로폭 상속을 방지(`grid-template-columns: none`)하여 모든 팀 카드가 균일한 가로폭을 유지하도록 하며, 4개 이후 팀도 스크롤을 통해 확인할 수 있습니다. 모바일 팀 카드 선택 표시는 내부 테두리로 처리해 외곽선이 잘려 보이지 않게 합니다. 킬로그는 전투 캔버스 바로 아래에 배치하되 하단 메타 정보(방문자 카운터/About)와 겹치지 않게 안전 여백을 확보합니다.
|
|
- **모바일 옵션 drawer**: 전투 중 펼친 옵션 drawer는 닉네임 입력 높이와 컨트롤 간격을 줄여 전투 시작/재시작/일시정지 버튼이 작은 화면에서도 한 번에 보이도록 합니다.
|
|
- **승리 연출**: 승리 시 Web Audio 기반 팡파르와 CSS 애니메이션(광선, 컨페티)을 결합해 화려하게 연출합니다. 전투 종료 시 옵션 drawer를 접어 결과 배너가 설정 폼과 충돌하지 않게 하며, 결과 배너는 일정 시간 후 자동으로 사라지거나 클릭 시 즉시 닫힙니다. 무승부는 더 차분한 톤을 사용합니다.
|
|
|
|
## 3. UI 개발 규칙
|
|
- **DOM 접근 최소화**: 성능 최적화를 위해 필요한 시점에만 최소한으로 DOM을 업데이트합니다.
|
|
- **반응형 상태**: `#app`의 클래스(`match-live`, `options-open`, `drawer-collapsed`, `match-paused`, `match-ended`)를 통해 전반적인 UI 상태를 제어합니다.
|
|
|
|
## 4. About 다이얼로그
|
|
|
|
- **`src/ui/aboutDialog.js`**:
|
|
- 대기 화면과 전투 화면 우측 하단에 상시 노출되는 `#about-button`과 `#visitor-count`를 관리합니다.
|
|
- 다이얼로그는 개발자정보와 개인정보처리방침 탭으로 구성됩니다.
|
|
- **자체 Markdown 렌더러**: 개인정보처리방침 탭은 자체 구현된 렌더러를 통해 출력되며, 굵게(`**`), 기울임(`*`), 인라인 코드(`` ` ``), 인용구(`>`), 구분선(`---`), 헤딩(`#`) 및 리스트(`-`) 문법을 안전하게(HTML 이스케이프) 지원합니다.
|
|
- 브라우저는 `GET /api/about` API로 서버에 캐시된 콘텐츠를 가져오며, 실패 시 폴백 값을 표시합니다.
|