Feat: Add SettingsProvider and Toggle for Enemy Animations

This commit is contained in:
Horoli 2025-12-07 19:20:43 +09:00
parent 78267b7e47
commit e6facc41f8
6 changed files with 83 additions and 4 deletions

View File

@ -61,4 +61,5 @@ class AppStrings {
// Settings // Settings
static const String settings = "Settings"; static const String settings = "Settings";
static const String enemyAnimations = "Enemy Animations";
} }

View File

@ -5,6 +5,7 @@ import 'game/data/enemy_table.dart';
import 'game/data/player_table.dart'; import 'game/data/player_table.dart';
import 'providers/battle_provider.dart'; import 'providers/battle_provider.dart';
import 'providers/shop_provider.dart'; // Import ShopProvider import 'providers/shop_provider.dart'; // Import ShopProvider
import 'providers/settings_provider.dart'; // Import SettingsProvider
import 'screens/main_menu_screen.dart'; import 'screens/main_menu_screen.dart';
void main() async { void main() async {
@ -22,6 +23,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider(create: (_) => SettingsProvider()), // Register SettingsProvider
ChangeNotifierProvider(create: (_) => ShopProvider()), ChangeNotifierProvider(create: (_) => ShopProvider()),
ChangeNotifierProxyProvider<ShopProvider, BattleProvider>( ChangeNotifierProxyProvider<ShopProvider, BattleProvider>(
create: (context) => BattleProvider( create: (context) => BattleProvider(

View File

@ -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<void> _loadSettings() async {
final prefs = await SharedPreferences.getInstance();
_enableEnemyAnimations = prefs.getBool(_keyEnemyAnim) ?? false;
notifyListeners();
}
Future<void> toggleEnemyAnimations(bool value) async {
_enableEnemyAnimations = value;
notifyListeners();
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_keyEnemyAnim, value);
}
}

View File

@ -22,6 +22,7 @@ import 'main_menu_screen.dart';
import '../game/config/battle_config.dart'; import '../game/config/battle_config.dart';
import '../game/config/theme_config.dart'; import '../game/config/theme_config.dart';
import '../game/config/app_strings.dart'; import '../game/config/app_strings.dart';
import '../providers/settings_provider.dart'; // Import SettingsProvider
class BattleScreen extends StatefulWidget { class BattleScreen extends StatefulWidget {
const BattleScreen({super.key}); const BattleScreen({super.key});
@ -293,6 +294,15 @@ class _BattleScreenState extends State<BattleScreen> {
} else if (event.type == ActionType.attack && } else if (event.type == ActionType.attack &&
event.target == EffectTarget.player && event.target == EffectTarget.player &&
event.feedbackType == null) { event.feedbackType == null) {
// Check Settings
bool enableAnim = context.read<SettingsProvider>().enableEnemyAnimations;
if (!enableAnim) {
showEffect(); // Just show effect if anim disabled
return;
}
// 2. Enemy Attack Animation Trigger // 2. Enemy Attack Animation Trigger
final RenderBox? playerBox = final RenderBox? playerBox =
_playerKey.currentContext?.findRenderObject() as RenderBox?; _playerKey.currentContext?.findRenderObject() as RenderBox?;

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../providers/battle_provider.dart'; import '../providers/battle_provider.dart';
import '../providers/settings_provider.dart'; // Import SettingsProvider
import 'main_menu_screen.dart'; import 'main_menu_screen.dart';
import '../game/config/theme_config.dart'; import '../game/config/theme_config.dart';
import '../game/config/app_strings.dart'; import '../game/config/app_strings.dart';
@ -23,11 +24,27 @@ class SettingsScreen extends StatelessWidget {
), ),
), ),
const SizedBox(height: 40), const SizedBox(height: 40),
// Placeholder for future settings
const Text( // Enemy Animation Toggle
'Effect Intensity: Normal', Consumer<SettingsProvider>(
style: TextStyle(color: ThemeConfig.textColorWhite), 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 SizedBox(height: 20),
const Text( const Text(
'Volume: 100%', 'Volume: 100%',

View File

@ -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<SettingsProvider>().enableEnemyAnimations` 확인.
## 3. 기대 효과 (Expected Outcome)
- 유저가 게임의 연출 빈도를 제어할 수 있음.
- 설정 관리의 기반이 마련됨.