diff --git a/.gitignore b/.gitignore index 674d7e1..aa6fef4 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ app.*.map.json # Generated localizations lib/l10n/gen/ +.superpowers/ diff --git a/docs/superpowers/specs/2026-06-11-commercial-polish-design.md b/docs/superpowers/specs/2026-06-11-commercial-polish-design.md new file mode 100644 index 0000000..59d76b5 --- /dev/null +++ b/docs/superpowers/specs/2026-06-11-commercial-polish-design.md @@ -0,0 +1,159 @@ +# Block Seasons — 상용 품질 폴리시 라운드 (Phase 3.5) 설계 + +날짜: 2026-06-11 +상태: 승인됨 (오너 시뮬레이터 플레이 피드백 기반) + +## 배경 + +오너가 Phase 3 빌드를 iOS 시뮬레이터에서 플레이한 뒤 피드백: + +1. 인트로가 없어 실제 앱스토어 게임이라는 느낌이 안 듦 +2. 그래픽이 더 화려하거나 예뻐야 함 +3. 게임성은 만족 +4. 결론: 더 상업적이고 전문적으로 발전 필요 +5. Firebase/AdMob 계정은 준비됐으나, 수익화 전에 게임성과 UI/UX 발전 우선 + +비주얼 컴패니언(브라우저 목업)으로 방향을 합의했다. 이 라운드는 **Phase 3.5**로, +완료 후 Phase 4(원격 시즌/분석) → Phase 5(수익화)로 진행한다. 예상 기간 약 1주. + +## 합의된 방향 (목업 선택 결과) + +| 주제 | 선택 | 비고 | +|---|---|---| +| 비주얼 스타일 | 글로시 타일 + 시즌 일러스트 배경 | Block Blast식 광택 타일 + 시즌마다 배경/팔레트 교체 | +| 시즌 1 배경 톤 | 딥 네이비 + 벚꽃 포인트 | 핑크 배경은 기각 — 대중적인 네이비, 벚꽃은 포인트 파티클만 | +| 인트로 범위 | 표준 상용 | 스플래시 + 시즌 타이틀 카드 + 인터랙티브 튜토리얼. 시네마틱은 보류 | +| 시즌 맵 | 여정 경로 맵 | Candy Crush식 지그재그 경로, 그리드 기각 | +| 게임성 확장 | 엔드리스(클래식) 모드 추가 | 데일리 챌린지는 보류 | + +## 1. 비주얼 시스템 + +### 타일 렌더링 업그레이드 (에셋 불필요) + +`board_painter.dart` / `piece_painter.dart` 의 단색 사각형을 광택 타일로 교체: + +- 셀마다 선형 그라데이션: 밝은 톤(좌상) → 기본색(중앙) → 어두운 톤(우하) +- 상단 안쪽 하이라이트 (흰색 반투명, 유리 광택 느낌) +- 타일 색상 글로우 (바깥 box-shadow 느낌의 blur 페인트) +- 클리어 애니메이션 시 글로우 강도 상승 → 번쩍이며 소멸 +- 모서리 라운딩 유지, 보석(gem) 셀은 더 강한 발광 + +### SeasonTheme 모델 + +시즌 팩 JSON에서 테마를 읽어 그래픽 전체를 갈아입히는 구조. + +``` +SeasonTheme { + backgroundGradient: [Color, Color, Color], // 상→하 + accentColor: Color, + particleType: petals | snow | leaves | none, + tilePalette: [8 colors], // 생략 시 기본 팔레트 + boardTint: Color, +} +``` + +- `pack.json` 의 `theme` 키에서 파싱 (없으면 시즌 1 기본값). 스키마 버전 유지(additive 변경). +- 시즌 1 기본값: 딥 네이비 그라데이션(#0E1430 → #16204A → #2A2E5E), 벚꽃 파티클, 기존 캔디 팔레트. +- 순수 Dart 모델 (`lib/game/models/`), 색은 int ARGB로 저장해 Flutter 비의존 유지. + +### 배경 레이어 (프로시저럴 우선) + +- `SeasonBackground` 위젯: 그라데이션 + 떠다니는 파티클(꽃잎)을 CustomPainter로 그림. +- 꽃잎은 벡터로 그림(타원 2개 회전 조합), 느리게 낙하+좌우 흔들림, 6~10개, 저사양 부담 없음. +- 홈 / 시즌 맵 / 게임 화면 공통 적용. +- **AI 일러스트는 선택적 강화**: 나중에 배경 이미지 에셋이 생기면 그라데이션 위 레이어로 끼움. + 에셋이 없어도 완성 상태여야 한다. (오너용 이미지 프롬프트는 Phase 6에 제공) + +## 2. 인트로 + +### 스플래시 (Flutter 측, 약 2초) + +- 네이티브 스플래시 배경색을 #0E1430으로 통일 (iOS LaunchScreen / Android styles). +- Flutter 첫 화면: 블록 4개(핑크/골드/시안/그린)가 화면 밖에서 날아와 2×2 로고로 조립 → + "BLOCK SEASONS" 텍스트 페이드인 → 홈으로 전환. +- SaveRepository 로딩을 이 시간에 겹쳐 수행 (이미 main에서 비동기 오픈 — 체감 로딩 0초). + +### 시즌 타이틀 카드 (1.5초, 탭 스킵) + +- 콜드 스타트마다 스플래시 직후 표시: 시즌 그라데이션 배경 + "SEASON 1 / 첫 개화 / 60 스테이지". +- 탭하면 즉시 홈으로. 세션당 1회. + +### 인터랙티브 튜토리얼 (첫 플레이 1회) + +- 발동 조건: 저장 데이터에 `tutorialDone` 플래그 없음 + 스테이지 1 진입. +- 3스텝: + 1. 보드 일부 칸 하이라이트 + 손가락 아이콘이 트레이→보드로 드래그 경로 반복 재생. + 해당 위치에 놓을 때까지 다른 입력 무시(스킵 제외). + 2. 줄이 완성되도록 유도 → 클리어 순간 축하 연출 + "줄을 채우면 사라져요!" + 3. HUD 스포트라이트: 목표(보석)와 이동 횟수 설명 말풍선 → "이제 직접 해보세요!" +- 우상단 스킵 버튼 항상 표시. 완료/스킵 시 `tutorialDone=true` 저장. +- 구현: `TutorialController` 상태머신(순수 Dart, 유닛 테스트) + `TutorialOverlay` 위젯. +- 튜토리얼 전용 고정 시드: 스테이지 1을 결정적 트레이로 시작해 1·2스텝 배치가 항상 성립. + +### 다국어 + +신규 문자열 전부 EN/KO ARB 추가 (튜토리얼 문구, 클래식 모드, 게임오버, 최고 점수 등). + +## 3. 여정 경로 맵 (시즌 맵 리디자인) + +- 세로 스크롤(아래=스테이지 1, 위=60), 진입 시 현재 스테이지 노드로 자동 스크롤. +- 노드 위치는 스테이지 인덱스의 결정적 함수: x = 중앙 ± 사인파 지그재그, y = 인덱스 × 간격. + 스테이지 수와 무관하게 자동 배치. +- 노드 사이 점선 경로를 CustomPainter로 드로잉 (부드러운 베지어 곡선). +- 노드 상태: 완료=금색 글로시 + 별(0~3), 현재=핑크 발광 + "PLAY" 라벨 + 펄스 애니메이션, + 잠김=어두운 원 + 자물쇠. +- 상단 고정 헤더: 시즌명 + 총 별 (★ n/180). +- 배경: SeasonBackground 공유 + 위로 갈수록 밝아지는 그라데이션(여정 느낌). +- 기존 `season_map_screen.dart` 교체, 위젯 테스트 갱신. + +## 4. 타격감 주스 키트 (게임 화면) + +| 요소 | 연출 | +|---|---| +| 블록 배치 | 스케일 1.06→1.0 살짝 눌리는 바운스 (90ms) | +| 줄 클리어 | 셀마다 타일색 스파크 파티클 6~8개 방사 + 셀 축소 소멸 | +| 점수 팝업 | "+250"이 클리어 위치에서 떠오르며 페이드아웃 | +| 콤보 배너 | ×2~3: 골드 텍스트 팝 / ×4~5: 화면 미세 흔들림 + 주황 / ×6+: 무지개 그라데이션 + 강한 흔들림 | +| 승리 | 별 1~3개 순차 등장(스케일 바운스 + 사운드) + 컨페티 낙하 | +| 근접 실패 | 목표 달성률 프로그레스 링 ("87% 달성!") — 기존 설계 항목 구현 | +| 햅틱 | 배치=light, 클리어=medium, 콤보 ×4+=heavy (`HapticFeedback`, 플러그인 불필요) | + +- 파티클/팝업은 게임 화면 Stack 위 단일 `EffectsOverlay`로 관리 (fxTick 트리거 재사용). +- 모든 연출은 60fps 유지 검증 (시뮬레이터 + 가능하면 실기기). + +## 5. 엔드리스(클래식) 모드 + +- 홈 버튼 2개: **어드벤처**(주 버튼, 시즌 맵으로) + **클래식**(보조 버튼, 즉시 게임). +- 규칙: 이동 제한·목표 없음. 트레이를 둘 곳이 없으면 게임 오버. 콤보/점수 규칙 동일. +- 엔진: `StageConfig`에 무목표·무제한 설정 추가 (기존 엔진 재사용, 분기 최소). + rescue(보상형 이어하기) 슬롯은 유지 — Phase 5에서 광고 연결. +- 저장: `endless: {bestScore}` 를 세이브 블롭에 추가 (saveVersion 유지, additive). +- 게임 오버 화면: 이번 점수 + 최고 점수 (신기록 시 "NEW BEST!" 연출) + 다시 하기. +- 홈에 최고 점수 표시. + +## 6. 이번에 만들지 않는 것 + +- BGM (저작권 무료 음원 도입은 추후 검토) +- 시즌 오프닝 시네마틱 (시즌 2~3쯤 여유 시) +- 부스터/파워업 +- 데일리 챌린지 +- AI 일러스트 에셋 자체 (구조만 준비, 제작은 Phase 6) + +## 7. 검증 + +- **유닛**: TutorialController 상태 전이, 엔드리스 게임오버/베스트 갱신, SeasonTheme JSON + 라운드트립(테마 누락 시 기본값), 경로 맵 노드 좌표 함수. +- **위젯**: 스플래시→홈 전환, 튜토리얼 오버레이 스텝 진행/스킵, 경로 맵 노드 상태 렌더, + 홈 클래식 버튼 → 게임 진입, 게임오버 화면. +- **아키텍처 가드**: `lib/game/` Flutter import 금지 유지 (SeasonTheme는 int ARGB). +- **수동**: 시뮬레이터에서 신규 설치 전체 흐름 — 스플래시 → 시즌 카드 → 홈 → 튜토리얼 → + 스테이지 1 클리어 → 맵 복귀 → 클래식 한 판. 60fps, 햅틱은 실기기에서. + +## 8. 구현 순서 (계획 문서에서 상세화) + +1. 비주얼 시스템 (타일 글로시 + SeasonTheme + 배경 레이어) — 모든 화면의 토대 +2. 주스 키트 (파티클/팝업/콤보/햅틱) +3. 인트로 (스플래시 → 시즌 카드 → 튜토리얼) +4. 여정 경로 맵 +5. 엔드리스 모드 + 홈 리디자인 +6. 통합 검증 + 시뮬레이터 빌드