mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-02 11:43:19 +08:00
Removing audio stuff in favor of flame_audio
This commit is contained in:
70
doc/examples/sound/.gitignore
vendored
70
doc/examples/sound/.gitignore
vendored
@ -1,70 +0,0 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# Visual Studio Code related
|
||||
.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Android related
|
||||
**/android/**/gradle-wrapper.jar
|
||||
**/android/.gradle
|
||||
**/android/captures/
|
||||
**/android/gradlew
|
||||
**/android/gradlew.bat
|
||||
**/android/local.properties
|
||||
**/android/**/GeneratedPluginRegistrant.java
|
||||
|
||||
# iOS/XCode related
|
||||
**/ios/**/*.mode1v3
|
||||
**/ios/**/*.mode2v3
|
||||
**/ios/**/*.moved-aside
|
||||
**/ios/**/*.pbxuser
|
||||
**/ios/**/*.perspectivev3
|
||||
**/ios/**/*sync/
|
||||
**/ios/**/.sconsign.dblite
|
||||
**/ios/**/.tags*
|
||||
**/ios/**/.vagrant/
|
||||
**/ios/**/DerivedData/
|
||||
**/ios/**/Icon?
|
||||
**/ios/**/Pods/
|
||||
**/ios/**/.symlinks/
|
||||
**/ios/**/profile
|
||||
**/ios/**/xcuserdata
|
||||
**/ios/.generated/
|
||||
**/ios/Flutter/App.framework
|
||||
**/ios/Flutter/Flutter.framework
|
||||
**/ios/Flutter/Generated.xcconfig
|
||||
**/ios/Flutter/app.flx
|
||||
**/ios/Flutter/app.zip
|
||||
**/ios/Flutter/flutter_assets/
|
||||
**/ios/ServiceDefinitions.json
|
||||
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!**/ios/**/default.mode1v3
|
||||
!**/ios/**/default.mode2v3
|
||||
!**/ios/**/default.pbxuser
|
||||
!**/ios/**/default.perspectivev3
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
@ -1,10 +0,0 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 7fc14a55af64462763d28abfb4e610086c6e0f39
|
||||
channel: dev
|
||||
|
||||
project_type: app
|
||||
@ -1,3 +0,0 @@
|
||||
# sound
|
||||
|
||||
Flame example application showcasing the audio features
|
||||
Binary file not shown.
Binary file not shown.
@ -1,57 +0,0 @@
|
||||
import 'package:flame/flame.dart';
|
||||
import 'package:flame/game.dart';
|
||||
import 'package:flame/extensions/vector2.dart';
|
||||
import 'package:flame/components/position_component.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
final Vector2 size = await Flame.util.initialDimensions();
|
||||
runApp(MyGame(size).widget);
|
||||
}
|
||||
|
||||
class Ball extends PositionComponent {
|
||||
final Vector2 gameSize;
|
||||
final paint = Paint()..color = const Color(0xFFFFFFFF);
|
||||
|
||||
bool forward = true;
|
||||
|
||||
Ball(this.gameSize);
|
||||
|
||||
@override
|
||||
void render(Canvas c) {
|
||||
super.render(c);
|
||||
c.drawOval(size.toRect(), paint);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(double dt) {
|
||||
super.update(dt);
|
||||
x += (forward ? 1 : -1) * 100 * dt;
|
||||
|
||||
if (x <= 0 || x + width >= gameSize.x) {
|
||||
if (forward) {
|
||||
x = gameSize.x - width - 1;
|
||||
} else {
|
||||
x = 1;
|
||||
}
|
||||
|
||||
forward = !forward;
|
||||
Flame.audio.play('boin.mp3', volume: 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyGame extends BaseGame {
|
||||
MyGame(Vector2 screenSize) {
|
||||
size = screenSize;
|
||||
|
||||
Flame.audio.disableLog();
|
||||
Flame.audio.load('boin.mp3');
|
||||
Flame.audio.loop('music.mp3', volume: 0.4);
|
||||
|
||||
add(Ball(size)
|
||||
..y = (size.y / 2) - 50
|
||||
..size = Vector2.all(100));
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
name: sound
|
||||
description: Flame example application showcasing the audio features
|
||||
version: 0.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flame:
|
||||
path: ../../../
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter:
|
||||
assets:
|
||||
- assets/audio/music.mp3
|
||||
- assets/audio/boin.mp3
|
||||
@ -23,6 +23,9 @@ The file structure would have to be:
|
||||
└── player.png
|
||||
```
|
||||
|
||||
Optionally you can split your `audio` folder into two subfolders, one for `music` and one for `sfx`.
|
||||
Be mindful of configuring the `prefix` property correctly if you are changing this structure.
|
||||
|
||||
Don't forget to add these files to your `pubspec.yaml` file:
|
||||
|
||||
```
|
||||
@ -31,4 +34,4 @@ flutter:
|
||||
- assets/audio/explosion.mp3
|
||||
- assets/images/player.png
|
||||
- assets/images/enemy.png
|
||||
```
|
||||
```
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:audioplayers/audio_cache.dart';
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
|
||||
typedef void Stoppable();
|
||||
|
||||
/// An AudioPool is a provider of AudioPlayers that leaves them pre-loaded to minimize delays.
|
||||
///
|
||||
/// All AudioPlayers loaded are for the same [sound]. If you want multiple sounds use multiple [AudioPool].
|
||||
/// Use this class if you'd like have extremely quick firing, repetitive and simultaneous sounds, like shooting a laser in a fast-paced spaceship game.
|
||||
class AudioPool {
|
||||
AudioCache cache;
|
||||
Map<String, AudioPlayer> currentPlayers = {};
|
||||
List<AudioPlayer> availablePlayers = [];
|
||||
|
||||
String sound;
|
||||
bool repeating;
|
||||
int minPlayers, maxPlayers;
|
||||
|
||||
final Lock _lock = Lock();
|
||||
|
||||
AudioPool(this.sound,
|
||||
{this.repeating = false,
|
||||
this.maxPlayers = 1,
|
||||
this.minPlayers = 1,
|
||||
String prefix = 'audio/sfx/'}) {
|
||||
cache = AudioCache(prefix: prefix);
|
||||
}
|
||||
|
||||
Future init() async {
|
||||
for (int i = 0; i < minPlayers; i++) {
|
||||
availablePlayers.add(await _createNewAudioPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
Future<Stoppable> start({double volume = 1.0}) async {
|
||||
return _lock.synchronized(() async {
|
||||
if (availablePlayers.isEmpty) {
|
||||
availablePlayers.add(await _createNewAudioPlayer());
|
||||
}
|
||||
final AudioPlayer player = availablePlayers.removeAt(0);
|
||||
currentPlayers[player.playerId] = player;
|
||||
await player.setVolume(volume);
|
||||
await player.resume();
|
||||
|
||||
StreamSubscription<void> subscription;
|
||||
|
||||
final Stoppable stop = () {
|
||||
_lock.synchronized(() async {
|
||||
final AudioPlayer p = currentPlayers.remove(player.playerId);
|
||||
subscription?.cancel();
|
||||
await p.stop();
|
||||
if (availablePlayers.length >= maxPlayers) {
|
||||
await p.release();
|
||||
} else {
|
||||
availablePlayers.add(p);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
subscription = player.onPlayerCompletion.listen((_) {
|
||||
if (repeating) {
|
||||
player.resume();
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
});
|
||||
|
||||
return stop;
|
||||
});
|
||||
}
|
||||
|
||||
Future<AudioPlayer> _createNewAudioPlayer() async {
|
||||
final AudioPlayer player = AudioPlayer();
|
||||
final String url = (await cache.load(sound)).path;
|
||||
await player.setUrl(url);
|
||||
await player.setReleaseMode(ReleaseMode.STOP);
|
||||
return player;
|
||||
}
|
||||
}
|
||||
118
lib/bgm.dart
118
lib/bgm.dart
@ -1,118 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'flame.dart';
|
||||
|
||||
/// The looping background music class.
|
||||
///
|
||||
/// This class helps with looping background music management that reacts to
|
||||
/// application lifecycle state changes. On construction, the instance is added
|
||||
/// as an observer to the [WidgetsBinding] instance. A [dispose] function is
|
||||
/// provided in case this functionality needs to be unloaded but the app needs
|
||||
/// to keep running.
|
||||
class Bgm extends WidgetsBindingObserver {
|
||||
bool _isRegistered = false;
|
||||
AudioPlayer audioPlayer;
|
||||
bool isPlaying = false;
|
||||
|
||||
/// Registers a [WidgetsBinding] observer.
|
||||
///
|
||||
/// This must be called for auto-pause and resume to work properly.
|
||||
void initialize() {
|
||||
if (_isRegistered) {
|
||||
return;
|
||||
}
|
||||
_isRegistered = true;
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
}
|
||||
|
||||
/// Dispose the [WidgetsBinding] observer.
|
||||
void dispose() {
|
||||
if (!_isRegistered) {
|
||||
return;
|
||||
}
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_isRegistered = false;
|
||||
}
|
||||
|
||||
/// Plays and loops a background music file specified by [filename].
|
||||
///
|
||||
/// The volume can be specified in the optional named parameter [volume]
|
||||
/// where `0` means off and `1` means max.
|
||||
///
|
||||
/// It is safe to call this function even when a current BGM track is
|
||||
/// playing.
|
||||
Future<void> play(String filename, {double volume}) async {
|
||||
volume ??= 1;
|
||||
|
||||
if (audioPlayer != null && audioPlayer.state != AudioPlayerState.STOPPED) {
|
||||
audioPlayer.stop();
|
||||
}
|
||||
|
||||
isPlaying = true;
|
||||
audioPlayer = await Flame.audio.loopLongAudio(filename, volume: volume);
|
||||
}
|
||||
|
||||
/// Stops the currently playing background music track (if any).
|
||||
Future<void> stop() async {
|
||||
isPlaying = false;
|
||||
if (audioPlayer != null) {
|
||||
await audioPlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// Resumes the currently played (but resumed) background music.
|
||||
Future<void> resume() async {
|
||||
if (audioPlayer != null) {
|
||||
isPlaying = true;
|
||||
await audioPlayer.resume();
|
||||
}
|
||||
}
|
||||
|
||||
/// Pauses the background music without unloading or resetting the audio
|
||||
/// player.
|
||||
Future<void> pause() async {
|
||||
if (audioPlayer != null) {
|
||||
isPlaying = false;
|
||||
await audioPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
/// Pre-fetch an audio and store it in the cache.
|
||||
///
|
||||
/// Alias of `FlameAudio.load();`.
|
||||
Future<File> load(String file) => Flame.audio.load(file);
|
||||
|
||||
/// Pre-fetch a list of audios and store them in the cache.
|
||||
///
|
||||
/// Alias of `FlameAudio.loadAll();`.
|
||||
Future<List<File>> loadAll(List<String> files) => Flame.audio.loadAll(files);
|
||||
|
||||
/// Clears the file in the cache.
|
||||
///
|
||||
/// Alias of `FlameAudio.clear();`.
|
||||
void clear(String file) => Flame.audio.clear(file);
|
||||
|
||||
/// Clears all the audios in the cache.
|
||||
///
|
||||
/// Alias of `FlameAudio.clearAll();`.
|
||||
void clearAll() => Flame.audio.clearAll();
|
||||
|
||||
/// Handler for AppLifecycleState changes.
|
||||
///
|
||||
/// This function handles the automatic pause and resume when the app
|
||||
/// lifecycle state changes. There is NO NEED to call this function directly
|
||||
/// directly.
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (isPlaying && audioPlayer?.state == AudioPlayerState.PAUSED) {
|
||||
audioPlayer.resume();
|
||||
}
|
||||
} else {
|
||||
audioPlayer?.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,19 +12,15 @@ import 'util.dart';
|
||||
|
||||
/// This class holds static references to some useful objects to use in your game.
|
||||
///
|
||||
/// You can access shared instances of [AudioCache], [Images] and [Util].
|
||||
/// You can access shared instances of [AssetsCache], [Images] and [Util].
|
||||
/// Most games should need only one instance of each, and should use this class to manage that reference.
|
||||
class Flame {
|
||||
// Flame asset bundle, defaults to root
|
||||
static AssetBundle _bundle;
|
||||
static AssetBundle get bundle => _bundle == null ? rootBundle : _bundle;
|
||||
|
||||
/// Access a shared instance of the [FlameAudio] class.
|
||||
static FlameAudio audio = FlameAudio();
|
||||
|
||||
/// Access a shared instance of the [Bgm] class.
|
||||
static Bgm _bgm;
|
||||
static Bgm get bgm => _bgm ??= Bgm();
|
||||
/// Access a shard instance of [AssetsCache] class.
|
||||
static AssetsCache assets = AssetsCache();
|
||||
|
||||
/// Access a shared instance of the [Images] class.
|
||||
static Images images = Images();
|
||||
@ -32,9 +28,6 @@ class Flame {
|
||||
/// Access a shared instance of the [Util] class.
|
||||
static Util util = Util();
|
||||
|
||||
/// Access a shard instance of [AssetsCache] class.
|
||||
static AssetsCache assets = AssetsCache();
|
||||
|
||||
static Future<void> init(
|
||||
{AssetBundle bundle,
|
||||
bool fullScreen = true,
|
||||
|
||||
@ -6,10 +6,7 @@ homepage: https://github.com/flame-engine/flame
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
audioplayers: ^0.15.1
|
||||
ordered_set: ^2.0.0
|
||||
path_provider: ^1.6.0
|
||||
synchronized: ^2.1.0
|
||||
convert: ^2.0.1
|
||||
flare_flutter: ^2.0.1
|
||||
meta: ^1.1.8
|
||||
|
||||
Reference in New Issue
Block a user