feat: endless mode UI - game over card, best score, HUD

This commit is contained in:
2026-06-12 07:06:30 +09:00
parent c5e9029cad
commit fea8336391
8 changed files with 110 additions and 8 deletions
+18
View File
@@ -0,0 +1,18 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'providers.dart';
/// Reactive view over SaveRepository's endless best score.
class EndlessBestNotifier extends Notifier<int> {
@override
int build() => ref.read(saveRepositoryProvider).endlessBest;
/// Records the run; returns true when it set a new best.
Future<bool> record(int score) async {
final repo = ref.read(saveRepositoryProvider);
final isNewBest = score > state;
await repo.recordEndlessScore(score);
state = repo.endlessBest;
return isNewBest;
}
}
+5 -1
View File
@@ -23,6 +23,7 @@ class GameViewState {
required this.objectiveProgress,
required this.lastPlacement,
required this.fxTick,
required this.endless,
});
final GridState grid;
@@ -40,6 +41,8 @@ class GameViewState {
/// Increments on every accepted placement so animations can retrigger.
final int fxTick;
final bool endless;
}
/// Bridges the pure-Dart [GameEngine] to the widget tree. The engine object
@@ -107,7 +110,8 @@ class GameSessionNotifier extends Notifier<GameViewState?> {
score: engine.score,
comboStreak: engine.combo.streak,
movesLeft: engine.movesLeft,
moveLimit: engine.movesLeft + engine.movesUsed,
endless: engine.endless,
moveLimit: engine.endless ? 0 : engine.movesLeft + engine.movesUsed,
phase: engine.phase,
stuckReason: engine.stuckReason,
objectives: engine.objectives,
+5
View File
@@ -5,6 +5,7 @@ import '../data/save_repository.dart';
import '../data/streak.dart';
import '../game/models/season.dart';
import '../services/audio_service.dart';
import 'endless_best_notifier.dart';
import 'game_session_notifier.dart';
import 'progress_notifier.dart';
import 'season_flow_notifier.dart';
@@ -51,6 +52,10 @@ final tutorialProvider = NotifierProvider<TutorialNotifier, TutorialStep?>(
TutorialNotifier.new,
);
final endlessBestProvider = NotifierProvider<EndlessBestNotifier, int>(
EndlessBestNotifier.new,
);
/// The visual theme of whatever season is in play; fallback outside seasons
/// (home, endless). Pure model — UI converts via ThemeColors.
final activeThemeProvider = Provider<SeasonTheme>((ref) {