Delegate all audio management to the new audio package, then manage that through a new wolf3d class
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -17,21 +17,19 @@ import 'package:wolf_dart/features/player/player.dart';
|
|||||||
import 'package:wolf_dart/features/renderer/raycast_painter.dart';
|
import 'package:wolf_dart/features/renderer/raycast_painter.dart';
|
||||||
import 'package:wolf_dart/features/renderer/weapon_painter.dart';
|
import 'package:wolf_dart/features/renderer/weapon_painter.dart';
|
||||||
import 'package:wolf_dart/features/ui/hud.dart';
|
import 'package:wolf_dart/features/ui/hud.dart';
|
||||||
import 'package:wolf_dart/sprite_gallery.dart';
|
import 'package:wolf_dart/wolf_3d.dart';
|
||||||
|
|
||||||
class WolfRenderer extends StatefulWidget {
|
class WolfRenderer extends StatefulWidget {
|
||||||
const WolfRenderer(
|
const WolfRenderer(
|
||||||
this.data, {
|
this.data, {
|
||||||
|
required this.difficulty,
|
||||||
|
required this.startingEpisode,
|
||||||
super.key,
|
super.key,
|
||||||
this.difficulty = Difficulty.bringEmOn,
|
|
||||||
this.showSpriteGallery = false,
|
|
||||||
this.isShareware = true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final WolfensteinData data;
|
final WolfensteinData data;
|
||||||
final Difficulty difficulty;
|
final Difficulty difficulty;
|
||||||
final bool showSpriteGallery;
|
final int startingEpisode;
|
||||||
final bool isShareware;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WolfRenderer> createState() => _WolfRendererState();
|
State<WolfRenderer> createState() => _WolfRendererState();
|
||||||
@@ -56,6 +54,9 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
|
|
||||||
double damageFlashOpacity = 0.0;
|
double damageFlashOpacity = 0.0;
|
||||||
|
|
||||||
|
late int _currentMapIndex;
|
||||||
|
late WolfLevel _currentLevel;
|
||||||
|
|
||||||
List<Entity> entities = [];
|
List<Entity> entities = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -64,7 +65,38 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
_initGame();
|
_initGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _loadLevel(int mapIndex) {
|
||||||
|
// Grab the specific level from the singleton
|
||||||
|
_currentLevel = Wolf3d.I.levels[mapIndex];
|
||||||
|
|
||||||
|
// TODO: Initialize player position, spawn enemies based on difficulty, etc.
|
||||||
|
debugPrint("Loaded Level: ${_currentLevel.name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLevelCompleted() {
|
||||||
|
// When the player hits the elevator switch, advance the map
|
||||||
|
setState(() {
|
||||||
|
_currentMapIndex++;
|
||||||
|
|
||||||
|
// Check if they beat the episode (each episode is 10 levels)
|
||||||
|
int maxLevelForEpisode = (widget.startingEpisode * 10) + 9;
|
||||||
|
|
||||||
|
if (_currentMapIndex > maxLevelForEpisode) {
|
||||||
|
// TODO: Handle episode completion (show victory screen, return to menu)
|
||||||
|
debugPrint("Episode Completed!");
|
||||||
|
} else {
|
||||||
|
_loadLevel(_currentMapIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _initGame() async {
|
Future<void> _initGame() async {
|
||||||
|
// 1. Calculate the starting index
|
||||||
|
_currentMapIndex = widget.startingEpisode * 10;
|
||||||
|
|
||||||
|
// 2. Load the initial level data
|
||||||
|
_loadLevel(_currentMapIndex);
|
||||||
|
|
||||||
// Get the first level out of the data class
|
// Get the first level out of the data class
|
||||||
activeLevel = widget.data.levels.first;
|
activeLevel = widget.data.levels.first;
|
||||||
|
|
||||||
@@ -109,7 +141,7 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
y + 0.5,
|
y + 0.5,
|
||||||
widget.difficulty,
|
widget.difficulty,
|
||||||
widget.data.sprites.length,
|
widget.data.sprites.length,
|
||||||
isSharewareMode: widget.isShareware,
|
isSharewareMode: widget.data.version == GameVersion.shareware,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (newEntity != null) {
|
if (newEntity != null) {
|
||||||
@@ -402,10 +434,6 @@ class _WolfRendererState extends State<WolfRenderer>
|
|||||||
return const Center(child: CircularProgressIndicator(color: Colors.teal));
|
return const Center(child: CircularProgressIndicator(color: Colors.teal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widget.showSpriteGallery) {
|
|
||||||
return SpriteGallery(sprites: widget.data.sprites);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
body: KeyboardListener(
|
body: KeyboardListener(
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_soloud/flutter_soloud.dart';
|
|
||||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||||
import 'package:wolf_3d_synth/wolf_3d_synth.dart';
|
|
||||||
import 'package:wolf_dart/features/difficulty/difficulty.dart';
|
import 'package:wolf_dart/features/difficulty/difficulty.dart';
|
||||||
import 'package:wolf_dart/features/renderer/renderer.dart';
|
import 'package:wolf_dart/features/renderer/renderer.dart';
|
||||||
import 'package:wolf_dart/wolf_3d.dart';
|
import 'package:wolf_dart/wolf_3d.dart';
|
||||||
@@ -16,77 +14,23 @@ class DifficultyScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DifficultyScreenState extends State<DifficultyScreen> {
|
class _DifficultyScreenState extends State<DifficultyScreen> {
|
||||||
AudioSource? _menuMusicSource;
|
|
||||||
SoundHandle? _menuMusicHandle;
|
|
||||||
|
|
||||||
bool get isShareware => Wolf3d.I.activeGame.version == GameVersion.shareware;
|
bool get isShareware => Wolf3d.I.activeGame.version == GameVersion.shareware;
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_playMenuMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _playMenuMusic() async {
|
|
||||||
final soloud = SoLoud.instance;
|
|
||||||
|
|
||||||
if (!soloud.isInitialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. We only want to play music if the IMF data actually exists
|
|
||||||
if (Wolf3d.I.music.isNotEmpty) {
|
|
||||||
// Get the first track (usually the menu theme "Wondering About My Loved Ones")
|
|
||||||
final music = Wolf3d.I.music.first;
|
|
||||||
|
|
||||||
// Render the hardware instructions into PCM and wrap in a WAV header
|
|
||||||
final pcmSamples = ImfRenderer.render(music);
|
|
||||||
|
|
||||||
final wavBytes = ImfRenderer.createWavFile(pcmSamples);
|
|
||||||
|
|
||||||
// 3. Load the bytes into SoLoud's memory
|
|
||||||
// The 'menu_theme.wav' string is just a dummy name to tell SoLoud it's dealing with a WAV format
|
|
||||||
_menuMusicSource = await soloud.loadMem('menu_theme.wav', wavBytes);
|
|
||||||
|
|
||||||
// 4. Play the source and tell it to loop continuously!
|
|
||||||
_menuMusicHandle = await soloud.play(
|
|
||||||
_menuMusicSource!,
|
|
||||||
looping: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_cleanupAudio();
|
Wolf3d.I.audio.stopMusic();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cleanupAudio() {
|
|
||||||
final soloud = SoLoud.instance;
|
|
||||||
|
|
||||||
// Stop the playback
|
|
||||||
if (_menuMusicHandle != null) {
|
|
||||||
soloud.stop(_menuMusicHandle!);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the raw WAV data from C++ memory
|
|
||||||
if (_menuMusicSource != null) {
|
|
||||||
soloud.disposeSource(_menuMusicSource!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _startGame(Difficulty difficulty, {bool showGallery = false}) {
|
void _startGame(Difficulty difficulty, {bool showGallery = false}) {
|
||||||
// Stop the music and clear memory right before we push the new route
|
Wolf3d.I.audio.stopMusic();
|
||||||
_cleanupAudio();
|
|
||||||
|
|
||||||
Navigator.of(context).pushReplacement(
|
Navigator.of(context).pushReplacement(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) => WolfRenderer(
|
builder: (_) => WolfRenderer(
|
||||||
Wolf3d.I.activeGame,
|
Wolf3d.I.activeGame,
|
||||||
difficulty: difficulty,
|
difficulty: difficulty,
|
||||||
isShareware: isShareware,
|
startingEpisode: Wolf3d.I.activeEpisode,
|
||||||
showSpriteGallery: showGallery,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
97
lib/features/screens/episode_screen.dart
Normal file
97
lib/features/screens/episode_screen.dart
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:wolf_dart/features/screens/difficulty_screen.dart';
|
||||||
|
import 'package:wolf_dart/wolf_3d.dart';
|
||||||
|
|
||||||
|
class EpisodeScreen extends StatefulWidget {
|
||||||
|
const EpisodeScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<EpisodeScreen> createState() => _EpisodeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EpisodeScreenState extends State<EpisodeScreen> {
|
||||||
|
final List<String> _episodeNames = [
|
||||||
|
"Episode 1\nEscape from Wolfenstein",
|
||||||
|
"Episode 2\nOperation: Eisenfaust",
|
||||||
|
"Episode 3\nDie, Fuhrer, Die!",
|
||||||
|
"Episode 4\nA Dark Secret",
|
||||||
|
"Episode 5\nTrail of the Madman",
|
||||||
|
"Episode 6\nConfrontation",
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
if (Wolf3d.I.music.isNotEmpty) {
|
||||||
|
Wolf3d.I.audio.playMusic(Wolf3d.I.music.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _selectEpisode(int index) {
|
||||||
|
Wolf3d.I.setActiveEpisode(index);
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
// We pass the audio handles so the next screen can stop them when the game starts
|
||||||
|
builder: (context) => DifficultyScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Determine how many episodes are available (10 levels per episode)
|
||||||
|
final int numberOfEpisodes = (Wolf3d.I.levels.length / 10).floor().clamp(
|
||||||
|
1,
|
||||||
|
6,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
body: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'WHICH EPISODE TO PLAY?',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.red,
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Courier',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 40),
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: numberOfEpisodes,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0,
|
||||||
|
horizontal: 32.0,
|
||||||
|
),
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blueGrey[900],
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
minimumSize: const Size(300, 60),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () => _selectEpisode(index),
|
||||||
|
child: Text(
|
||||||
|
_episodeNames[index],
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||||
import 'package:wolf_dart/features/difficulty/difficulty_screen.dart';
|
import 'package:wolf_dart/features/screens/episode_screen.dart';
|
||||||
import 'package:wolf_dart/wolf_3d.dart';
|
import 'package:wolf_dart/wolf_3d.dart';
|
||||||
|
|
||||||
class GameSelectScreen extends StatelessWidget {
|
class GameSelectScreen extends StatelessWidget {
|
||||||
@@ -22,7 +22,7 @@ class GameSelectScreen extends StatelessWidget {
|
|||||||
Wolf3d.I.setActiveGame(data);
|
Wolf3d.I.setActiveGame(data);
|
||||||
Navigator.of(context).push(
|
Navigator.of(context).push(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => DifficultyScreen(),
|
builder: (context) => const EpisodeScreen(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_soloud/flutter_soloud.dart';
|
|
||||||
import 'package:wolf_dart/game_select_screen.dart';
|
import 'package:wolf_dart/game_select_screen.dart';
|
||||||
import 'package:wolf_dart/wolf_3d.dart';
|
import 'package:wolf_dart/wolf_3d.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
await SoLoud.instance.init(
|
|
||||||
sampleRate: 44100, // Audio quality
|
|
||||||
bufferSize: 2048, // Buffer size affects latency
|
|
||||||
channels: Channels.stereo,
|
|
||||||
);
|
|
||||||
|
|
||||||
await Wolf3d.I.init();
|
await Wolf3d.I.init();
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:wolf_3d_data/wolf_3d_data.dart';
|
import 'package:wolf_3d_data/wolf_3d_data.dart';
|
||||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||||
|
import 'package:wolf_3d_synth/wolf_3d_synth.dart';
|
||||||
|
|
||||||
class Wolf3d {
|
class Wolf3d {
|
||||||
Wolf3d._();
|
Wolf3d._();
|
||||||
@@ -12,6 +13,9 @@ class Wolf3d {
|
|||||||
final List<WolfensteinData> availableGames = [];
|
final List<WolfensteinData> availableGames = [];
|
||||||
WolfensteinData? _activeGame;
|
WolfensteinData? _activeGame;
|
||||||
|
|
||||||
|
// --- Core Systems ---
|
||||||
|
final WolfAudio audio = WolfAudio();
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
WolfensteinData get activeGame {
|
WolfensteinData get activeGame {
|
||||||
if (_activeGame == null) {
|
if (_activeGame == null) {
|
||||||
@@ -20,6 +24,15 @@ class Wolf3d {
|
|||||||
return _activeGame!;
|
return _activeGame!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Episode ---
|
||||||
|
int _activeEpisode = 0;
|
||||||
|
|
||||||
|
int get activeEpisode => _activeEpisode;
|
||||||
|
|
||||||
|
void setActiveEpisode(int episodeIndex) {
|
||||||
|
_activeEpisode = episodeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience getters for the active game's assets
|
// Convenience getters for the active game's assets
|
||||||
List<WolfLevel> get levels => activeGame.levels;
|
List<WolfLevel> get levels => activeGame.levels;
|
||||||
List<Sprite> get walls => activeGame.walls;
|
List<Sprite> get walls => activeGame.walls;
|
||||||
@@ -36,6 +49,7 @@ class Wolf3d {
|
|||||||
|
|
||||||
/// Initializes the engine by loading available game data.
|
/// Initializes the engine by loading available game data.
|
||||||
Future<void> init({String? directory}) async {
|
Future<void> init({String? directory}) async {
|
||||||
|
await audio.init();
|
||||||
availableGames.clear();
|
availableGames.clear();
|
||||||
|
|
||||||
// 1. Bundle asset loading (migrated from GameSelectScreen)
|
// 1. Bundle asset loading (migrated from GameSelectScreen)
|
||||||
|
|||||||
92
packages/wolf_3d_synth/lib/src/wolf_3d_audio.dart
Normal file
92
packages/wolf_3d_synth/lib/src/wolf_3d_audio.dart
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import 'package:flutter_soloud/flutter_soloud.dart';
|
||||||
|
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||||
|
import 'package:wolf_3d_synth/src/imf_renderer.dart';
|
||||||
|
|
||||||
|
class WolfAudio {
|
||||||
|
bool _isInitialized = false;
|
||||||
|
|
||||||
|
// --- Music State ---
|
||||||
|
AudioSource? _currentMusicSource;
|
||||||
|
SoundHandle? _currentMusicHandle;
|
||||||
|
|
||||||
|
/// Initializes the SoLoud audio engine.
|
||||||
|
Future<void> init() async {
|
||||||
|
if (_isInitialized) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await SoLoud.instance.init(
|
||||||
|
sampleRate: 44100,
|
||||||
|
bufferSize: 2048,
|
||||||
|
channels: Channels.stereo,
|
||||||
|
);
|
||||||
|
_isInitialized = true;
|
||||||
|
print("WolfAudio: SoLoud initialized successfully.");
|
||||||
|
} catch (e) {
|
||||||
|
print("WolfAudio: Failed to initialize SoLoud - $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disposes of the audio engine and frees resources.
|
||||||
|
void dispose() {
|
||||||
|
stopMusic();
|
||||||
|
SoLoud.instance.deinit();
|
||||||
|
_isInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// MUSIC MANAGEMENT
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
/// Renders and plays a specific IMF music track.
|
||||||
|
Future<void> playMusic(ImfMusic track, {bool looping = true}) async {
|
||||||
|
if (!_isInitialized) return;
|
||||||
|
|
||||||
|
// Stop currently playing music to prevent overlap
|
||||||
|
stopMusic();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Render hardware instructions into PCM and wrap in WAV
|
||||||
|
final pcmSamples = ImfRenderer.render(track);
|
||||||
|
final wavBytes = ImfRenderer.createWavFile(pcmSamples);
|
||||||
|
|
||||||
|
_currentMusicSource = await SoLoud.instance.loadMem(
|
||||||
|
'track.wav',
|
||||||
|
wavBytes,
|
||||||
|
);
|
||||||
|
_currentMusicHandle = await SoLoud.instance.play(
|
||||||
|
_currentMusicSource!,
|
||||||
|
looping: looping,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print("WolfAudio: Error playing music track - $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Halts playback and frees memory for the current track.
|
||||||
|
void stopMusic() {
|
||||||
|
if (!_isInitialized) return;
|
||||||
|
|
||||||
|
if (_currentMusicHandle != null) {
|
||||||
|
SoLoud.instance.stop(_currentMusicHandle!);
|
||||||
|
_currentMusicHandle = null;
|
||||||
|
}
|
||||||
|
if (_currentMusicSource != null) {
|
||||||
|
SoLoud.instance.disposeSource(_currentMusicSource!);
|
||||||
|
_currentMusicSource = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pauses the current track.
|
||||||
|
void pauseMusic() {
|
||||||
|
if (_isInitialized && _currentMusicHandle != null) {
|
||||||
|
SoLoud.instance.setPause(_currentMusicHandle!, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resumes a paused track.
|
||||||
|
void resumeMusic() {
|
||||||
|
if (_isInitialized && _currentMusicHandle != null) {
|
||||||
|
SoLoud.instance.setPause(_currentMusicHandle!, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,4 +3,4 @@
|
|||||||
/// More dartdocs go here.
|
/// More dartdocs go here.
|
||||||
library;
|
library;
|
||||||
|
|
||||||
export 'src/imf_renderer.dart' show ImfRenderer;
|
export 'src/wolf_3d_audio.dart' show WolfAudio;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ environment:
|
|||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
flutter_soloud: ^3.5.1
|
||||||
wolf_3d_data_types:
|
wolf_3d_data_types:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ dependencies:
|
|||||||
wolf_3d_synth: any
|
wolf_3d_synth: any
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_soloud: ^3.5.1
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user