mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
Upgrade game_template's dependencies (#1426)
This commit is contained in:
@@ -256,6 +256,7 @@ class MyApp extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
routeInformationProvider: _router.routeInformationProvider,
|
||||||
routeInformationParser: _router.routeInformationParser,
|
routeInformationParser: _router.routeInformationParser,
|
||||||
routerDelegate: _router.routerDelegate,
|
routerDelegate: _router.routerDelegate,
|
||||||
scaffoldMessengerKey: scaffoldMessengerKey,
|
scaffoldMessengerKey: scaffoldMessengerKey,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart' hide Logger;
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
@@ -17,18 +17,10 @@ import 'sounds.dart';
|
|||||||
class AudioController {
|
class AudioController {
|
||||||
static final _log = Logger('AudioController');
|
static final _log = Logger('AudioController');
|
||||||
|
|
||||||
late AudioCache _musicCache;
|
|
||||||
|
|
||||||
late AudioCache _sfxCache;
|
|
||||||
|
|
||||||
final AudioPlayer _musicPlayer;
|
final AudioPlayer _musicPlayer;
|
||||||
|
|
||||||
/// This is a list of [AudioPlayer] instances which are rotated to play
|
/// This is a list of [AudioPlayer] instances which are rotated to play
|
||||||
/// sound effects.
|
/// sound effects.
|
||||||
///
|
|
||||||
/// Normally, we would just call [AudioCache.play] and let it procure its
|
|
||||||
/// own [AudioPlayer] every time. But this seems to lead to errors and
|
|
||||||
/// bad performance on iOS devices.
|
|
||||||
final List<AudioPlayer> _sfxPlayers;
|
final List<AudioPlayer> _sfxPlayers;
|
||||||
|
|
||||||
int _currentSfxPlayer = 0;
|
int _currentSfxPlayer = 0;
|
||||||
@@ -49,26 +41,15 @@ class AudioController {
|
|||||||
/// of [_sfxPlayers] to learn why this is the case.
|
/// of [_sfxPlayers] to learn why this is the case.
|
||||||
///
|
///
|
||||||
/// Background music does not count into the [polyphony] limit. Music will
|
/// Background music does not count into the [polyphony] limit. Music will
|
||||||
/// never be overridden by sound effects.
|
/// never be overridden by sound effects because that would be silly.
|
||||||
AudioController({int polyphony = 2})
|
AudioController({int polyphony = 2})
|
||||||
: assert(polyphony >= 1),
|
: assert(polyphony >= 1),
|
||||||
_musicPlayer = AudioPlayer(playerId: 'musicPlayer'),
|
_musicPlayer = AudioPlayer(playerId: 'musicPlayer'),
|
||||||
_sfxPlayers = Iterable.generate(
|
_sfxPlayers = Iterable.generate(
|
||||||
polyphony,
|
polyphony, (i) => AudioPlayer(playerId: 'sfxPlayer#$i'))
|
||||||
(i) => AudioPlayer(
|
.toList(growable: false),
|
||||||
playerId: 'sfxPlayer#$i',
|
|
||||||
mode: PlayerMode.LOW_LATENCY)).toList(growable: false),
|
|
||||||
_playlist = Queue.of(List<Song>.of(songs)..shuffle()) {
|
_playlist = Queue.of(List<Song>.of(songs)..shuffle()) {
|
||||||
_musicCache = AudioCache(
|
_musicPlayer.onPlayerComplete.listen(_changeSong);
|
||||||
fixedPlayer: _musicPlayer,
|
|
||||||
prefix: 'assets/music/',
|
|
||||||
);
|
|
||||||
_sfxCache = AudioCache(
|
|
||||||
fixedPlayer: _sfxPlayers.first,
|
|
||||||
prefix: 'assets/sfx/',
|
|
||||||
);
|
|
||||||
|
|
||||||
_musicPlayer.onPlayerCompletion.listen(_changeSong);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables the [AudioController] to listen to [AppLifecycleState] events,
|
/// Enables the [AudioController] to listen to [AppLifecycleState] events,
|
||||||
@@ -127,8 +108,10 @@ class AudioController {
|
|||||||
// This assumes there is only a limited number of sound effects in the game.
|
// This assumes there is only a limited number of sound effects in the game.
|
||||||
// If there are hundreds of long sound effect files, it's better
|
// If there are hundreds of long sound effect files, it's better
|
||||||
// to be more selective when preloading.
|
// to be more selective when preloading.
|
||||||
await _sfxCache
|
await AudioCache.instance.loadAll(SfxType.values
|
||||||
.loadAll(SfxType.values.expand(soundTypeToFilename).toList());
|
.expand(soundTypeToFilename)
|
||||||
|
.map((path) => 'sfx/$path')
|
||||||
|
.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Plays a single sound effect, defined by [type].
|
/// Plays a single sound effect, defined by [type].
|
||||||
@@ -153,9 +136,11 @@ class AudioController {
|
|||||||
final options = soundTypeToFilename(type);
|
final options = soundTypeToFilename(type);
|
||||||
final filename = options[_random.nextInt(options.length)];
|
final filename = options[_random.nextInt(options.length)];
|
||||||
_log.info(() => '- Chosen filename: $filename');
|
_log.info(() => '- Chosen filename: $filename');
|
||||||
_sfxCache.play(filename, volume: soundTypeToVolume(type));
|
|
||||||
|
final currentPlayer = _sfxPlayers[_currentSfxPlayer];
|
||||||
|
currentPlayer.play(AssetSource('sfx/$filename'),
|
||||||
|
volume: soundTypeToVolume(type));
|
||||||
_currentSfxPlayer = (_currentSfxPlayer + 1) % _sfxPlayers.length;
|
_currentSfxPlayer = (_currentSfxPlayer + 1) % _sfxPlayers.length;
|
||||||
_sfxCache.fixedPlayer = _sfxPlayers[_currentSfxPlayer];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeSong(void _) {
|
void _changeSong(void _) {
|
||||||
@@ -163,8 +148,7 @@ class AudioController {
|
|||||||
// Put the song that just finished playing to the end of the playlist.
|
// Put the song that just finished playing to the end of the playlist.
|
||||||
_playlist.addLast(_playlist.removeFirst());
|
_playlist.addLast(_playlist.removeFirst());
|
||||||
// Play the next song.
|
// Play the next song.
|
||||||
_log.info(() => 'Playing ${_playlist.first} now.');
|
_playFirstSongInPlaylist();
|
||||||
_musicCache.play(_playlist.first.filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleAppLifecycle() {
|
void _handleAppLifecycle() {
|
||||||
@@ -208,41 +192,46 @@ class AudioController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _playFirstSongInPlaylist() async {
|
||||||
|
_log.info(() => 'Playing ${_playlist.first} now.');
|
||||||
|
await _musicPlayer.play(AssetSource('music/${_playlist.first.filename}'));
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _resumeMusic() async {
|
Future<void> _resumeMusic() async {
|
||||||
_log.info('Resuming music');
|
_log.info('Resuming music');
|
||||||
switch (_musicPlayer.state) {
|
switch (_musicPlayer.state) {
|
||||||
case PlayerState.PAUSED:
|
case PlayerState.paused:
|
||||||
_log.info('Calling _musicPlayer.resume()');
|
_log.info('Calling _musicPlayer.resume()');
|
||||||
try {
|
try {
|
||||||
await _musicPlayer.resume();
|
await _musicPlayer.resume();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Sometimes, resuming fails with an "Unexpected" error.
|
// Sometimes, resuming fails with an "Unexpected" error.
|
||||||
_log.severe(e);
|
_log.severe(e);
|
||||||
await _musicCache.play(_playlist.first.filename);
|
await _playFirstSongInPlaylist();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PlayerState.STOPPED:
|
case PlayerState.stopped:
|
||||||
_log.info("resumeMusic() called when music is stopped. "
|
_log.info("resumeMusic() called when music is stopped. "
|
||||||
"This probably means we haven't yet started the music. "
|
"This probably means we haven't yet started the music. "
|
||||||
"For example, the game was started with sound off.");
|
"For example, the game was started with sound off.");
|
||||||
await _musicCache.play(_playlist.first.filename);
|
await _playFirstSongInPlaylist();
|
||||||
break;
|
break;
|
||||||
case PlayerState.PLAYING:
|
case PlayerState.playing:
|
||||||
_log.warning('resumeMusic() called when music is playing. '
|
_log.warning('resumeMusic() called when music is playing. '
|
||||||
'Nothing to do.');
|
'Nothing to do.');
|
||||||
break;
|
break;
|
||||||
case PlayerState.COMPLETED:
|
case PlayerState.completed:
|
||||||
_log.warning('resumeMusic() called when music is completed. '
|
_log.warning('resumeMusic() called when music is completed. '
|
||||||
"Music should never be 'completed' as it's either not playing "
|
"Music should never be 'completed' as it's either not playing "
|
||||||
"or looping forever.");
|
"or looping forever.");
|
||||||
await _musicCache.play(_playlist.first.filename);
|
await _playFirstSongInPlaylist();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _soundsOnHandler() {
|
void _soundsOnHandler() {
|
||||||
for (final player in _sfxPlayers) {
|
for (final player in _sfxPlayers) {
|
||||||
if (player.state == PlayerState.PLAYING) {
|
if (player.state == PlayerState.playing) {
|
||||||
player.stop();
|
player.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,11 +239,11 @@ class AudioController {
|
|||||||
|
|
||||||
void _startMusic() {
|
void _startMusic() {
|
||||||
_log.info('starting music');
|
_log.info('starting music');
|
||||||
_musicCache.play(_playlist.first.filename);
|
_playFirstSongInPlaylist();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _stopAllSound() {
|
void _stopAllSound() {
|
||||||
if (_musicPlayer.state == PlayerState.PLAYING) {
|
if (_musicPlayer.state == PlayerState.playing) {
|
||||||
_musicPlayer.pause();
|
_musicPlayer.pause();
|
||||||
}
|
}
|
||||||
for (final player in _sfxPlayers) {
|
for (final player in _sfxPlayers) {
|
||||||
@@ -264,7 +253,7 @@ class AudioController {
|
|||||||
|
|
||||||
void _stopMusic() {
|
void _stopMusic() {
|
||||||
_log.info('Stopping music');
|
_log.info('Stopping music');
|
||||||
if (_musicPlayer.state == PlayerState.PLAYING) {
|
if (_musicPlayer.state == PlayerState.playing) {
|
||||||
_musicPlayer.pause();
|
_musicPlayer.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import audioplayers
|
import audioplayers_darwin
|
||||||
import firebase_core
|
import firebase_core
|
||||||
import firebase_crashlytics
|
import firebase_crashlytics
|
||||||
import games_services
|
import games_services
|
||||||
@@ -13,7 +13,7 @@ import path_provider_macos
|
|||||||
import shared_preferences_macos
|
import shared_preferences_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
AudioplayersPlugin.register(with: registry.registrar(forPlugin: "AudioplayersPlugin"))
|
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||||
FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin"))
|
FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin"))
|
||||||
GamesServicesPlugin.register(with: registry.registrar(forPlugin: "GamesServicesPlugin"))
|
GamesServicesPlugin.register(with: registry.registrar(forPlugin: "GamesServicesPlugin"))
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
audioplayers: ^0.20.1
|
audioplayers: ^1.0.1
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
go_router: ^3.0.1
|
go_router: ^4.4.1
|
||||||
logging: ^1.0.2
|
logging: ^1.0.2
|
||||||
provider: ^6.0.2
|
provider: ^6.0.2
|
||||||
shared_preferences: ^2.0.13
|
shared_preferences: ^2.0.13
|
||||||
@@ -26,14 +26,14 @@ dependencies:
|
|||||||
firebase_core: ^1.15.0 # Needed for Crashlytics below
|
firebase_core: ^1.15.0 # Needed for Crashlytics below
|
||||||
firebase_crashlytics: ^2.8.1 # Error reporting
|
firebase_crashlytics: ^2.8.1 # Error reporting
|
||||||
games_services: ^3.0.0 # Achievements and leaderboards
|
games_services: ^3.0.0 # Achievements and leaderboards
|
||||||
google_mobile_ads: ^1.1.0 # Ads
|
google_mobile_ads: ^2.0.1 # Ads
|
||||||
in_app_purchase: ^3.0.1 # In-app purchases
|
in_app_purchase: ^3.0.1 # In-app purchases
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
flutter_launcher_icons: ^0.9.2
|
flutter_launcher_icons: ^0.10.0
|
||||||
flutter_lints: ^2.0.1
|
flutter_lints: ^2.0.1
|
||||||
test: ^1.19.0
|
test: ^1.19.0
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
audioplayers_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
Reference in New Issue
Block a user