feat(story): Phase 9 스토리/엔딩 시스템 구현
- story_data.dart: 5개 Act 스토리 텍스트 및 ASCII 아트 - story_service.dart: Act 전환/보스 조우/엔딩 이벤트 관리 - cinematic_view.dart: 풀스크린 시네마틱 UI (페이드, 스킵) - game_play_screen.dart: 레벨 기반 Act 전환 시 시네마틱 재생
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:askiineverdie/data/story_data.dart';
|
||||
import 'package:askiineverdie/l10n/app_localizations.dart';
|
||||
import 'package:askiineverdie/src/core/animation/ascii_animation_type.dart';
|
||||
import 'package:askiineverdie/src/core/engine/story_service.dart';
|
||||
import 'package:askiineverdie/src/core/l10n/game_data_l10n.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/notification/notification_service.dart';
|
||||
import 'package:askiineverdie/src/core/util/pq_logic.dart' as pq_logic;
|
||||
import 'package:askiineverdie/src/features/game/game_session_controller.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/cinematic_view.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/notification_overlay.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/stats_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/task_progress_panel.dart';
|
||||
@@ -30,6 +33,11 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
// Phase 8: 알림 서비스 (Notification Service)
|
||||
late final NotificationService _notificationService;
|
||||
|
||||
// Phase 9: 스토리 서비스 (Story Service)
|
||||
late final StoryService _storyService;
|
||||
StoryAct _lastAct = StoryAct.prologue;
|
||||
bool _showingCinematic = false;
|
||||
|
||||
// 이전 상태 추적 (레벨업/퀘스트/Act 완료 감지용)
|
||||
int _lastLevel = 0;
|
||||
int _lastQuestCount = 0;
|
||||
@@ -41,6 +49,13 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
_specialAnimation = AsciiAnimationType.levelUp;
|
||||
_notificationService.showLevelUp(state.traits.level);
|
||||
_resetSpecialAnimationAfterFrame();
|
||||
|
||||
// Phase 9: Act 변경 감지 (레벨 기반)
|
||||
final newAct = getActForLevel(state.traits.level);
|
||||
if (newAct != _lastAct && !_showingCinematic) {
|
||||
_lastAct = newAct;
|
||||
_showCinematicForAct(newAct);
|
||||
}
|
||||
}
|
||||
_lastLevel = state.traits.level;
|
||||
|
||||
@@ -68,6 +83,25 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
_lastPlotStageCount = state.progress.plotStageCount;
|
||||
}
|
||||
|
||||
/// Phase 9: Act 시네마틱 표시 (Show Act Cinematic)
|
||||
Future<void> _showCinematicForAct(StoryAct act) async {
|
||||
if (_showingCinematic) return;
|
||||
|
||||
_showingCinematic = true;
|
||||
// 게임 일시 정지
|
||||
await widget.controller.pause(saveOnStop: false);
|
||||
|
||||
if (mounted) {
|
||||
await showActCinematic(context, act);
|
||||
}
|
||||
|
||||
// 게임 재개
|
||||
if (mounted) {
|
||||
await widget.controller.resume();
|
||||
}
|
||||
_showingCinematic = false;
|
||||
}
|
||||
|
||||
void _resetSpecialAnimationAfterFrame() {
|
||||
// 다음 프레임에서 리셋 (AsciiAnimationCard가 값을 받은 후)
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -83,6 +117,7 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
void initState() {
|
||||
super.initState();
|
||||
_notificationService = NotificationService();
|
||||
_storyService = StoryService();
|
||||
widget.controller.addListener(_onControllerChanged);
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
@@ -92,12 +127,14 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
_lastLevel = state.traits.level;
|
||||
_lastQuestCount = state.progress.questCount;
|
||||
_lastPlotStageCount = state.progress.plotStageCount;
|
||||
_lastAct = getActForLevel(state.traits.level);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_notificationService.dispose();
|
||||
_storyService.dispose();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
widget.controller.removeListener(_onControllerChanged);
|
||||
super.dispose();
|
||||
|
||||
Reference in New Issue
Block a user