浏览代码

Fix audio issues and hide support button

- Initialize AudioManager early in main() to ensure menu music plays on app start
- Enhanced app lifecycle management to properly stop music when app exits
- Improved AudioManager.dispose() to immediately stop all audio and clear state
- Added proper audio pause/resume on app focus changes
- Hidden support section from settings screen as requested

Fixes:
- Menu music not playing when app starts
- Music continuing to play after app exit
- Support button visibility in settings
Fszontagh 8 月之前
父节点
当前提交
215c5599ac
共有 4 个文件被更改,包括 59 次插入13 次删除
  1. 14 1
      lib/game/audio/audio_manager.dart
  2. 24 1
      lib/main.dart
  3. 6 6
      lib/ui/settings_screen.dart
  4. 15 5
      lib/utils/app_lifecycle_manager.dart

+ 14 - 1
lib/game/audio/audio_manager.dart

@@ -285,7 +285,10 @@ class AudioManager {
     if (!_isAudioSupported) return;
 
     try {
-      FlameAudio.bgm.stop();
+      await FlameAudio.bgm.stop();
+      _currentMenuMusic = null;
+      _currentIngameMusic = null;
+      _isMenuMusic = false;
     } catch (e) {
       print('Failed to stop background music: $e');
     }
@@ -345,6 +348,9 @@ class AudioManager {
   }
 
   Future<void> dispose() async {
+    // Stop all audio immediately
+    await stopBackgroundMusic();
+
     try {
       await FlameAudio.bgm.dispose();
     } catch (e) {
@@ -353,15 +359,22 @@ class AudioManager {
 
     try {
       await _popPool?.dispose();
+      _popPool = null;
     } catch (e) {
       print('Failed to dispose popPool: $e');
     }
 
     try {
       await _popAltPool?.dispose();
+      _popAltPool = null;
     } catch (e) {
       print('Failed to dispose popAltPool: $e');
     }
+
+    // Clear all state
+    _currentMenuMusic = null;
+    _currentIngameMusic = null;
+    _isMenuMusic = false;
   }
 
   // Utility method to get platform info for debugging

+ 24 - 1
lib/main.dart

@@ -9,6 +9,7 @@ import 'utils/score_manager.dart';
 import 'utils/google_play_games_manager.dart';
 import 'utils/locale_manager.dart';
 import 'utils/app_lifecycle_manager.dart';
+import 'game/audio/audio_manager.dart';
 
 void main() async {
   WidgetsFlutterBinding.ensureInitialized();
@@ -16,6 +17,9 @@ void main() async {
   await ScoreManager.initialize();
   await LocaleManager.init();
 
+  // Initialize audio manager early
+  await AudioManager().initialize();
+
   // Initialize Google Play Games (silent init, don't require sign-in)
   await GooglePlayGamesManager.instance.initialize();
 
@@ -32,7 +36,7 @@ class ZenTapApp extends StatefulWidget {
   State<ZenTapApp> createState() => _ZenTapAppState();
 }
 
-class _ZenTapAppState extends State<ZenTapApp> {
+class _ZenTapAppState extends State<ZenTapApp> with WidgetsBindingObserver {
   @override
   void initState() {
     super.initState();
@@ -40,13 +44,32 @@ class _ZenTapAppState extends State<ZenTapApp> {
     LocaleManager.setLocaleChangeCallback(() {
       setState(() {});
     });
+    // Add observer for app lifecycle
+    WidgetsBinding.instance.addObserver(this);
   }
 
   @override
   void dispose() {
+    // Remove observer
+    WidgetsBinding.instance.removeObserver(this);
+    // Dispose audio manager when app is being terminated
+    AudioManager().dispose();
+    // Dispose app lifecycle manager
+    AppLifecycleManager.instance.dispose();
     super.dispose();
   }
 
+  @override
+  void didChangeAppLifecycleState(AppLifecycleState state) {
+    super.didChangeAppLifecycleState(state);
+
+    // Handle app termination
+    if (state == AppLifecycleState.detached) {
+      // App is being completely terminated, dispose audio immediately
+      AudioManager().dispose();
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     return MaterialApp(

+ 6 - 6
lib/ui/settings_screen.dart

@@ -182,13 +182,13 @@ class _SettingsScreenState extends State<SettingsScreen> {
 
                           const SizedBox(height: 30),
 
-                          // Support Section
-                          _buildSectionHeader(
-                            AppLocalizations.of(context)!.supportZenTap,
-                          ),
-                          _buildDonationTile(),
+                          // Support Section - Hidden as requested
+                          // _buildSectionHeader(
+                          //   AppLocalizations.of(context)!.supportZenTap,
+                          // ),
+                          // _buildDonationTile(),
 
-                          const SizedBox(height: 30),
+                          // const SizedBox(height: 30),
 
                           // About Section
                           Padding(

+ 15 - 5
lib/utils/app_lifecycle_manager.dart

@@ -1,5 +1,6 @@
 import 'package:flutter/material.dart';
 import '../game/zentap_game.dart';
+import '../game/audio/audio_manager.dart';
 
 /// Manages app lifecycle events for game suspension and resumption
 class AppLifecycleManager with WidgetsBindingObserver {
@@ -37,21 +38,30 @@ class AppLifecycleManager with WidgetsBindingObserver {
   @override
   void didChangeAppLifecycleState(AppLifecycleState state) {
     super.didChangeAppLifecycleState(state);
-    
-    // Handle app lifecycle changes for game suspension
+
+    // Handle app lifecycle changes for game suspension and audio management
     switch (state) {
       case AppLifecycleState.resumed:
         // App came back to foreground, resume game if there's an active game
         _currentGame?.resumeGame();
+        // Resume background music if enabled
+        AudioManager().resumeBackgroundMusic();
         break;
       case AppLifecycleState.inactive:
       case AppLifecycleState.paused:
+        // App went to background, screen turned off
+        // Suspend the game to save battery and resources
+        _currentGame?.pauseGame();
+        // Pause background music to save battery
+        AudioManager().pauseBackgroundMusic();
+        break;
       case AppLifecycleState.detached:
       case AppLifecycleState.hidden:
-        // App went to background, screen turned off, or app is being closed
-        // Suspend the game to save battery and resources
+        // App is being closed or hidden
+        // Stop all audio immediately
+        AudioManager().stopBackgroundMusic();
         _currentGame?.pauseGame();
         break;
     }
   }
-}
+}