feat(app): 오디오 및 설정 시스템 통합

- AudioService 앱 수준 초기화 및 dispose
- 게임 화면에서 오디오/설정 연동
This commit is contained in:
JiWoong Sul
2025-12-30 14:22:50 +09:00
parent 0ccd1bd007
commit 8f011689fb
2 changed files with 24 additions and 51 deletions

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:askiineverdie/data/game_text_l10n.dart' as game_l10n; import 'package:askiineverdie/data/game_text_l10n.dart' as game_l10n;
import 'package:askiineverdie/l10n/app_localizations.dart'; import 'package:askiineverdie/l10n/app_localizations.dart';
import 'package:askiineverdie/src/core/audio/audio_service.dart';
import 'package:askiineverdie/src/core/engine/game_mutations.dart'; import 'package:askiineverdie/src/core/engine/game_mutations.dart';
import 'package:askiineverdie/src/core/engine/progress_service.dart'; import 'package:askiineverdie/src/core/engine/progress_service.dart';
import 'package:askiineverdie/src/core/engine/reward_service.dart'; import 'package:askiineverdie/src/core/engine/reward_service.dart';
@@ -30,6 +31,7 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
late final GameSessionController _controller; late final GameSessionController _controller;
late final NotificationService _notificationService; late final NotificationService _notificationService;
late final SettingsRepository _settingsRepository; late final SettingsRepository _settingsRepository;
late final AudioService _audioService;
bool _isCheckingSave = true; bool _isCheckingSave = true;
bool _hasSave = false; bool _hasSave = false;
ThemeMode _themeMode = ThemeMode.system; ThemeMode _themeMode = ThemeMode.system;
@@ -51,9 +53,11 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
); );
_notificationService = NotificationService(); _notificationService = NotificationService();
_settingsRepository = SettingsRepository(); _settingsRepository = SettingsRepository();
_audioService = AudioService(settingsRepository: _settingsRepository);
// 초기 설정 로드 // 초기 설정 및 오디오 서비스 로드
_loadSettings(); _loadSettings();
_audioService.init();
// 세이브 파일 존재 여부 확인 // 세이브 파일 존재 여부 확인
_checkForExistingSave(); _checkForExistingSave();
} }
@@ -87,6 +91,7 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
void dispose() { void dispose() {
_controller.dispose(); _controller.dispose();
_notificationService.dispose(); _notificationService.dispose();
_audioService.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -31,6 +31,8 @@ import 'package:askiineverdie/src/features/game/widgets/potion_inventory_panel.d
import 'package:askiineverdie/src/features/game/widgets/task_progress_panel.dart'; import 'package:askiineverdie/src/features/game/widgets/task_progress_panel.dart';
import 'package:askiineverdie/src/features/game/widgets/active_buff_panel.dart'; import 'package:askiineverdie/src/features/game/widgets/active_buff_panel.dart';
import 'package:askiineverdie/src/features/game/layouts/mobile_carousel_layout.dart'; import 'package:askiineverdie/src/features/game/layouts/mobile_carousel_layout.dart';
import 'package:askiineverdie/src/features/settings/settings_screen.dart';
import 'package:askiineverdie/src/core/storage/settings_repository.dart';
/// 게임 진행 화면 (Main.dfm 기반 3패널 레이아웃) /// 게임 진행 화면 (Main.dfm 기반 3패널 레이아웃)
/// ///
@@ -463,51 +465,17 @@ class _GamePlayScreenState extends State<GamePlayScreen>
return platform == TargetPlatform.iOS || platform == TargetPlatform.android; return platform == TargetPlatform.iOS || platform == TargetPlatform.android;
} }
/// 현재 언어명 가져오기 /// 설정 화면 표시
String _getCurrentLanguageName() { void _showSettingsScreen(BuildContext context) {
final locale = game_l10n.currentGameLocale; final settingsRepo = SettingsRepository();
if (locale == 'ko') return game_l10n.languageKorean; SettingsScreen.show(
if (locale == 'ja') return game_l10n.languageJapanese; context,
return game_l10n.languageEnglish; settingsRepository: settingsRepo,
} currentThemeMode: widget.currentThemeMode,
onThemeModeChange: (mode) {
/// 언어 선택 다이얼로그 표시 widget.onThemeModeChange?.call(mode);
void _showLanguageDialog(BuildContext context) { },
showDialog<void>( onLocaleChange: (locale) async {
context: context,
builder: (context) => AlertDialog(
title: Text(game_l10n.menuLanguage),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildLanguageOption(context, 'en', game_l10n.languageEnglish),
_buildLanguageOption(context, 'ko', game_l10n.languageKorean),
_buildLanguageOption(context, 'ja', game_l10n.languageJapanese),
],
),
),
);
}
Widget _buildLanguageOption(
BuildContext context,
String locale,
String label,
) {
final isSelected = game_l10n.currentGameLocale == locale;
return ListTile(
leading: Icon(
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
color: isSelected ? Theme.of(context).colorScheme.primary : null,
),
title: Text(
label,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
onTap: () async {
Navigator.pop(context); // 다이얼로그 닫기
// 안전한 언어 변경: 전체 화면 재생성 // 안전한 언어 변경: 전체 화면 재생성
final navigator = Navigator.of(this.context); final navigator = Navigator.of(this.context);
await widget.controller.pause(saveOnStop: true); await widget.controller.pause(saveOnStop: true);
@@ -698,11 +666,11 @@ class _GamePlayScreenState extends State<GamePlayScreen>
onPressed: () => widget.controller.loop?.cheatCompletePlot(), onPressed: () => widget.controller.loop?.cheatCompletePlot(),
), ),
], ],
// 언어 변경 버튼 // 설정 버튼
TextButton.icon( IconButton(
onPressed: () => _showLanguageDialog(context), icon: const Icon(Icons.settings),
icon: const Icon(Icons.language, size: 18), tooltip: game_l10n.uiSettings,
label: Text(_getCurrentLanguageName()), onPressed: () => _showSettingsScreen(context),
), ),
], ],
), ),