This commit is contained in:
2025-11-24 17:53:00 +09:00
parent e992a5ca5e
commit dde81cab65
34 changed files with 3718 additions and 469 deletions
@@ -0,0 +1,65 @@
import 'package:audioplayers/audioplayers.dart';
/// 사운드 키 상수 (오타 방지용)
class SoundKey {
static const String bgm = 'bgm';
static const String correct = 'correct';
static const String wrong = 'wrong';
static const String win = 'win';
static const String click = 'click';
}
class SoundManager {
static final SoundManager _instance = SoundManager._internal();
factory SoundManager() => _instance;
SoundManager._internal();
final AudioPlayer _bgmPlayer = AudioPlayer();
final AudioPlayer _sfxPlayer = AudioPlayer();
// [핵심] 키-경로 매핑 저장소
final Map<String, String> _soundPaths = {};
bool _isInitialized = false;
/// 앱 시작 시 사운드 경로 주입 (Dependency Injection)
void initialize({required Map<String, String> soundPaths}) {
_soundPaths.addAll(soundPaths);
_isInitialized = true;
print('[SoundManager] Initialized with ${_soundPaths.length} sounds');
}
/// BGM 재생
Future<void> playBgm(String key) async {
if (!_isInitialized) return;
final path = _soundPaths[key];
if (path != null) {
await _bgmPlayer.setReleaseMode(ReleaseMode.loop);
await _bgmPlayer.setVolume(0.3);
// AssetSource는 'assets/'를 생략하고 그 하위 경로를 입력받습니다.
// 예: assets/audio/bgm.mp3 -> AssetSource('audio/bgm.mp3')
await _bgmPlayer.play(AssetSource(path));
} else {
print('[SoundManager] BGM Key not found: $key');
}
}
Future<void> stopBgm() async {
await _bgmPlayer.stop();
}
/// 효과음 재생
Future<void> playSfx(String key) async {
if (!_isInitialized) return;
final path = _soundPaths[key];
if (path != null) {
// 효과음은 겹칠 수 있으므로 매번 stop 하거나 모드 설정
await _sfxPlayer.stop();
await _sfxPlayer.setVolume(1.0);
await _sfxPlayer.play(AssetSource(path));
} else {
print('[SoundManager] SFX Key not found: $key');
}
}
}