【问题标题】:How to play Background Music on loop in a game with Flutter?如何在使用 Flutter 的游戏中循环播放背景音乐?
【发布时间】:2022-01-12 17:41:53
【问题描述】:

在 Flutter 上编写游戏,想要在应用程序启动时在后台循环播放音乐播放器:^0.20.1 包和 WidgetsBindingObserver,不起作用!音频不播放。

另一种“.wav”格式适用于“AudioCache”。但是“AudioCache”没有暂停和恢复属性。厌倦了“AudioPlayer”,无法播放“.mp3”扩展名音频。但同样的“.mp3”扩展音频与“AudioCache”一起播放。

检查下面的代码

import 'dart:async';
import 'package:bugbee2/barrier.dart';
import 'package:bugbee2/bee.dart';
import 'package:bugbee2/coverScreen.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  // bee variables
  static double beeY = 0;
  double initialPos = beeY;
  double height = 0;
  double time = 0;
  double gravity = -4.9; // how strong the gravity is
  double velocity = 3.5; // how strong the jump is
  double beeWidth = 0.1; // out of 2, 2 being the entire width of the screen
  double beeHeight = 0.1; // out of 2, 2 being the entire height of the screen
  // inciment score
  int score = 0;
  int bestScore = 0;

  // game settings
  bool gameHasStarted = false;

  // Best Score Value Update
  @override
  void initState() {
    super.initState();
    checkBestScore();
    WidgetsBinding.instance?.addObserver(this);
  }

// Remove Observer
  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  // Background Music

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    AudioPlayer player = AudioPlayer();
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed) {
      player.play("sounds/tea-ceremony.mp3");
    } else if (state == AppLifecycleState.paused) {
      player.pause();
    } else if (state == AppLifecycleState.inactive) {
      player.pause();
    } else if (state == AppLifecycleState.detached) {
      player.stop();
    }
  }

  // Saving Best Score
  getBestScore() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    int bestScore = prefs.getInt('bestScore') ?? 0;
    return bestScore;
  }

  setBestScore() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setInt('bestScore', bestScore);
  }

  // barrier variables
  static List<double> barrierX = [2, 2 + 1.5];
  static double barrierWidth = 0.5; // out of 2
  List<List<double>> barrierHeight = [
    // out of 2, where 2 is the entire height of the screen
    // [topHeight, bottomHeight]
    [0.6, 0.4],
    [0.4, 0.6],
  ];

  void startGame() {
    final player = AudioCache();
    player.play(
      "sounds/jump.wav",
    );
    gameHasStarted = true;
    Timer.periodic(Duration(milliseconds: 10), (timer) {
      // a real physical jump is the same as an upside down parabola
      // so this is a simple quadratic equation
      height = gravity * time * time + velocity * time;

      setState(() {
        beeY = initialPos - height;
      });

      // check if bird is dead
      if (beeIsDead()) {
        timer.cancel();
        _showDialog();
        final player = AudioCache();
        player.play(
          "sounds/slide-hit.wav",
        );
      }

      // keep the map moving (move barriers)
      moveMap();

      // keep the time going!
      time += 0.01;
    });
  }

  void moveMap() {
    for (int i = 0; i < barrierX.length; i++) {
      // keep barriers moving
      setState(() {
        barrierX[i] -= 0.005;
      });

      // if barrier exits the left part of the screen, keep it looping
      if (barrierX[i] < -1.5) {
        barrierX[i] += 3;
        score++;
        final player = AudioCache();
        player.play(
          "sounds/coin-touch.wav",
        );
        setBestScore();
        if (score > bestScore) {
          bestScore = score;
        }
      }
    }
  }

  checkBestScore() async {
    int tempBestScore = await getBestScore() ?? 0;
    setState(() {
      bestScore = tempBestScore;
    });
  }

  void resetGame() {
    Navigator.pop(context); // dismisses the alert dialog
    setState(() {
      beeY = 0;
      gameHasStarted = false;
      time = 0;
      initialPos = beeY;
      barrierX = [2, 2 + 1.5];
      score = 0;
    });
  }

  void _showDialog() {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return AlertDialog(
            backgroundColor: Colors.brown,
            title: Center(
              child: Text(
                "G A M E  O V E R",
                style: TextStyle(color: Colors.white),
              ),
            ),
            actions: [
              GestureDetector(
                onTap: resetGame,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(5),
                  child: Container(
                    padding: EdgeInsets.all(7),
                    color: Colors.white,
                    child: Text(
                      'PLAY AGAIN',
                      style: TextStyle(color: Colors.brown),
                    ),
                  ),
                ),
              ),
            ],
          );
        });
  }

  void jump() {
    final player = AudioCache();
    player.play(
      "sounds/jump.wav",
    );
    setState(() {
      time = 0;
      initialPos = beeY;
    });
  }

  bool beeIsDead() {
    // check if the bird is hitting the top or the bottom of the screen
    if (beeY < -1 || beeY > 1) {
      return true;
    }

    // hits barriers
    // checks if bird is within x coordinates and y coordinates of barriers
    for (int i = 0; i < barrierX.length; i++) {
      if (barrierX[i] <= beeWidth &&
          barrierX[i] + barrierWidth >= -beeWidth &&
          (beeY <= -1 + barrierHeight[i][0] ||
              beeY + beeHeight >= 1 - barrierHeight[i][1])) {
        return true;
      }
    }

    return false;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: gameHasStarted ? jump : startGame,
      child: Scaffold(
        body: Column(
          children: [
            Expanded(
              flex: 3,
              child: Container(
                color: Colors.blue.shade500,
                child: Center(
                  child: Stack(
                    children: [
                      // bird
                      MyBee(
                        beeY: beeY,
                        beeWidth: beeWidth,
                        beeHeight: beeHeight,
                      ),

                      // tap to play
                      MyCoverScreen(gameHasStarted: gameHasStarted),

                      MyBarrier(
                        barrierX: barrierX[0],
                        barrierWidth: barrierWidth,
                        barrierHeight: barrierHeight[0][0],
                        isThisBottomBarrier: false,
                      ),

                      // Bottom barrier 0
                      MyBarrier(
                        barrierX: barrierX[0],
                        barrierWidth: barrierWidth,
                        barrierHeight: barrierHeight[0][1],
                        isThisBottomBarrier: true,
                      ),

                      // Top barrier 1
                      MyBarrier(
                        barrierX: barrierX[1],
                        barrierWidth: barrierWidth,
                        barrierHeight: barrierHeight[1][0],
                        isThisBottomBarrier: false,
                      ),

                      // Bottom barrier 1
                      MyBarrier(
                        barrierX: barrierX[1],
                        barrierWidth: barrierWidth,
                        barrierHeight: barrierHeight[1][1],
                        isThisBottomBarrier: true,
                      ),
                    ],
                  ),
                ),
              ),
            ),
            SizedBox(
              height: 10,
              child: Container(
                color: Colors.green,
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.brown,
                child: Center(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            score.toString(),
                            style: TextStyle(color: Colors.white, fontSize: 35),
                          ),
                          SizedBox(
                            height: 15,
                          ),
                          Text(
                            'S C O R E',
                            style: TextStyle(color: Colors.white, fontSize: 20),
                          ),
                        ],
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            bestScore.toString(),
                            style: TextStyle(color: Colors.white, fontSize: 35),
                          ),
                          SizedBox(
                            height: 15,
                          ),
                          Text(
                            'B E S T',
                            style: TextStyle(color: Colors.white, fontSize: 20),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter loops audio background playback


    【解决方案1】:

    我正在使用音频播放器:^ 0.19.1

      AudioPlayer advancedPlayer;
      AudioCache audioCache;
      String audioCorrect = "audio/access_granted.mp3";
    

    我有这个调用 initState() 的方法

     void initPlayer() {
        advancedPlayer = new AudioPlayer();
        audioCache = new AudioCache(fixedPlayer: advancedPlayer);
      }
    

    我用这种方式播放音频

      audioCache.play(audioCorrect);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多