diff --git a/lib/game/config/app_strings.dart b/lib/game/config/app_strings.dart index 90cedd9..1e0b654 100644 --- a/lib/game/config/app_strings.dart +++ b/lib/game/config/app_strings.dart @@ -61,4 +61,5 @@ class AppStrings { // Settings static const String settings = "Settings"; + static const String enemyAnimations = "Enemy Animations"; } diff --git a/lib/main.dart b/lib/main.dart index 8a5299b..eb33c50 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'game/data/enemy_table.dart'; import 'game/data/player_table.dart'; import 'providers/battle_provider.dart'; import 'providers/shop_provider.dart'; // Import ShopProvider +import 'providers/settings_provider.dart'; // Import SettingsProvider import 'screens/main_menu_screen.dart'; void main() async { @@ -22,6 +23,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MultiProvider( providers: [ + ChangeNotifierProvider(create: (_) => SettingsProvider()), // Register SettingsProvider ChangeNotifierProvider(create: (_) => ShopProvider()), ChangeNotifierProxyProvider( create: (context) => BattleProvider( diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart new file mode 100644 index 0000000..509d109 --- /dev/null +++ b/lib/providers/settings_provider.dart @@ -0,0 +1,27 @@ +import 'package:flutter/foundation.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class SettingsProvider with ChangeNotifier { + static const String _keyEnemyAnim = 'settings_enemy_anim'; + + bool _enableEnemyAnimations = false; // Default: Disabled + + bool get enableEnemyAnimations => _enableEnemyAnimations; + + SettingsProvider() { + _loadSettings(); + } + + Future _loadSettings() async { + final prefs = await SharedPreferences.getInstance(); + _enableEnemyAnimations = prefs.getBool(_keyEnemyAnim) ?? false; + notifyListeners(); + } + + Future toggleEnemyAnimations(bool value) async { + _enableEnemyAnimations = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(_keyEnemyAnim, value); + } +} diff --git a/lib/screens/battle_screen.dart b/lib/screens/battle_screen.dart index 82412a1..5a1c344 100644 --- a/lib/screens/battle_screen.dart +++ b/lib/screens/battle_screen.dart @@ -22,6 +22,7 @@ import 'main_menu_screen.dart'; import '../game/config/battle_config.dart'; import '../game/config/theme_config.dart'; import '../game/config/app_strings.dart'; +import '../providers/settings_provider.dart'; // Import SettingsProvider class BattleScreen extends StatefulWidget { const BattleScreen({super.key}); @@ -293,6 +294,15 @@ class _BattleScreenState extends State { } else if (event.type == ActionType.attack && event.target == EffectTarget.player && event.feedbackType == null) { + + // Check Settings + bool enableAnim = context.read().enableEnemyAnimations; + + if (!enableAnim) { + showEffect(); // Just show effect if anim disabled + return; + } + // 2. Enemy Attack Animation Trigger final RenderBox? playerBox = _playerKey.currentContext?.findRenderObject() as RenderBox?; diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 05889f3..f3f23b6 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/battle_provider.dart'; +import '../providers/settings_provider.dart'; // Import SettingsProvider import 'main_menu_screen.dart'; import '../game/config/theme_config.dart'; import '../game/config/app_strings.dart'; @@ -23,11 +24,27 @@ class SettingsScreen extends StatelessWidget { ), ), const SizedBox(height: 40), - // Placeholder for future settings - const Text( - 'Effect Intensity: Normal', - style: TextStyle(color: ThemeConfig.textColorWhite), + + // Enemy Animation Toggle + Consumer( + builder: (context, settings, child) { + return SizedBox( + width: 300, + child: SwitchListTile( + title: const Text( + AppStrings.enemyAnimations, + style: TextStyle(color: ThemeConfig.textColorWhite), + ), + value: settings.enableEnemyAnimations, + onChanged: (value) { + settings.toggleEnemyAnimations(value); + }, + activeColor: ThemeConfig.btnActionActive, + ), + ); + }, ), + const SizedBox(height: 20), const Text( 'Volume: 100%', diff --git a/prompt/63_settings_enemy_anim.md b/prompt/63_settings_enemy_anim.md new file mode 100644 index 0000000..f8a76a9 --- /dev/null +++ b/prompt/63_settings_enemy_anim.md @@ -0,0 +1,22 @@ +# 63. Implement Settings Provider and Enemy Animation Toggle + +## 1. 목표 (Goal) +- 적 공격 애니메이션을 기본적으로 비활성화하고, 설정 화면에서 유저가 선택적으로 활성화할 수 있도록 합니다. +- 전역 설정을 관리하는 `SettingsProvider`를 도입합니다. + +## 2. 구현 계획 (Implementation Plan) +1. **`SettingsProvider` 구현:** + - `lib/providers/settings_provider.dart` 생성. + - `enableEnemyAnimations` boolean 상태 관리 (기본값 false). + - `SharedPreferences`를 이용한 영구 저장(`settings_enemy_anim`). +2. **`main.dart` 등록:** + - `MultiProvider`에 `SettingsProvider` 추가. +3. **`SettingsScreen` UI:** + - `AppStrings`에 관련 텍스트 추가. + - SwitchListTile 위젯을 사용하여 설정 변경 UI 구현. +4. **`BattleScreen` 로직:** + - `_addFloatingEffect` 메서드 내에서 적 애니메이션 실행 전 `context.read().enableEnemyAnimations` 확인. + +## 3. 기대 효과 (Expected Outcome) +- 유저가 게임의 연출 빈도를 제어할 수 있음. +- 설정 관리의 기반이 마련됨.