Add synthesized SFX and audio wiring
Pure-Dart WAV synthesizer (tool/gen_sfx.dart) generates place/clear/ combo/win/lose effects; AudioService player pool fires on placement, line clears, combo streaks, and phase transitions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../game/engine/game_engine.dart';
|
||||
import '../../game/models/stage.dart';
|
||||
import '../../l10n/gen/app_localizations.dart';
|
||||
import '../../services/audio_service.dart';
|
||||
import '../../state/game_session_notifier.dart';
|
||||
import '../../state/providers.dart';
|
||||
import '../theme/palette.dart';
|
||||
@@ -124,8 +125,26 @@ class _GameScreenState extends ConsumerState<GameScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
void _playSfx(GameViewState? prev, GameViewState? next) {
|
||||
if (next == null) return;
|
||||
final audio = ref.read(audioServiceProvider);
|
||||
if (prev?.fxTick != next.fxTick && next.lastPlacement != null) {
|
||||
final placement = next.lastPlacement!;
|
||||
if (placement.linesCleared > 0) {
|
||||
audio.play(placement.comboStreak >= 2 ? Sfx.combo : Sfx.clear);
|
||||
} else {
|
||||
audio.play(Sfx.place);
|
||||
}
|
||||
}
|
||||
if (prev?.phase != next.phase) {
|
||||
if (next.phase == GamePhase.won) audio.play(Sfx.win);
|
||||
if (next.phase == GamePhase.lost) audio.play(Sfx.lose);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ref.listen<GameViewState?>(gameSessionProvider, _playSfx);
|
||||
final view = ref.watch(gameSessionProvider);
|
||||
if (view == null) {
|
||||
return const Scaffold(body: Center(child: CircularProgressIndicator()));
|
||||
|
||||
Reference in New Issue
Block a user