积分、成就系统
This commit is contained in:
111
lib/services/achievement_service.dart
Normal file
111
lib/services/achievement_service.dart
Normal file
@@ -0,0 +1,111 @@
|
||||
import '../models/user_progress.dart';
|
||||
import '../models/achievement_config.dart';
|
||||
|
||||
/// Service for managing achievements
|
||||
class AchievementService {
|
||||
/// Check for newly unlocked achievements asynchronously
|
||||
/// Returns list of newly unlocked achievement IDs
|
||||
Future<List<String>> checkAchievementsAsync(UserProgress progress) async {
|
||||
List<String> newlyUnlocked = [];
|
||||
|
||||
for (var achievement in AchievementConfig.all) {
|
||||
// Skip if already unlocked
|
||||
if (progress.unlockedAchievements.containsKey(achievement.id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if requirement is met
|
||||
bool unlocked = false;
|
||||
switch (achievement.type) {
|
||||
case AchievementType.sessionCount:
|
||||
unlocked = progress.totalSessions >= achievement.requiredValue;
|
||||
break;
|
||||
case AchievementType.distractionCount:
|
||||
unlocked = progress.totalDistractions >= achievement.requiredValue;
|
||||
break;
|
||||
case AchievementType.totalMinutes:
|
||||
unlocked = progress.totalFocusMinutes >= achievement.requiredValue;
|
||||
break;
|
||||
case AchievementType.consecutiveDays:
|
||||
unlocked = progress.consecutiveCheckIns >= achievement.requiredValue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlocked) {
|
||||
// Mark as unlocked with timestamp
|
||||
progress.unlockedAchievements[achievement.id] = DateTime.now();
|
||||
|
||||
// Award bonus points
|
||||
progress.totalPoints += achievement.bonusPoints;
|
||||
progress.currentPoints += achievement.bonusPoints;
|
||||
|
||||
newlyUnlocked.add(achievement.id);
|
||||
}
|
||||
}
|
||||
|
||||
return newlyUnlocked;
|
||||
}
|
||||
|
||||
/// Get progress towards a specific achievement (0.0 - 1.0)
|
||||
double getAchievementProgress(
|
||||
UserProgress progress,
|
||||
AchievementConfig achievement,
|
||||
) {
|
||||
int currentValue = 0;
|
||||
|
||||
switch (achievement.type) {
|
||||
case AchievementType.sessionCount:
|
||||
currentValue = progress.totalSessions;
|
||||
break;
|
||||
case AchievementType.distractionCount:
|
||||
currentValue = progress.totalDistractions;
|
||||
break;
|
||||
case AchievementType.totalMinutes:
|
||||
currentValue = progress.totalFocusMinutes;
|
||||
break;
|
||||
case AchievementType.consecutiveDays:
|
||||
currentValue = progress.consecutiveCheckIns;
|
||||
break;
|
||||
}
|
||||
|
||||
return (currentValue / achievement.requiredValue).clamp(0.0, 1.0);
|
||||
}
|
||||
|
||||
/// Get current value for achievement type
|
||||
int getAchievementCurrentValue(
|
||||
UserProgress progress,
|
||||
AchievementConfig achievement,
|
||||
) {
|
||||
switch (achievement.type) {
|
||||
case AchievementType.sessionCount:
|
||||
return progress.totalSessions;
|
||||
case AchievementType.distractionCount:
|
||||
return progress.totalDistractions;
|
||||
case AchievementType.totalMinutes:
|
||||
return progress.totalFocusMinutes;
|
||||
case AchievementType.consecutiveDays:
|
||||
return progress.consecutiveCheckIns;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all achievements with their current progress
|
||||
Map<AchievementConfig, double> getAllAchievementsWithProgress(
|
||||
UserProgress progress,
|
||||
) {
|
||||
final result = <AchievementConfig, double>{};
|
||||
for (var achievement in AchievementConfig.all) {
|
||||
result[achievement] = getAchievementProgress(progress, achievement);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Get newly unlocked achievements since last check
|
||||
/// This can be used to show notifications for achievements unlocked in background
|
||||
List<String> getNewlyUnlockedAchievements(
|
||||
UserProgress progress,
|
||||
Set<String> previouslyUnlocked,
|
||||
) {
|
||||
final currentlyUnlocked = progress.unlockedAchievements.keys.toSet();
|
||||
return currentlyUnlocked.difference(previouslyUnlocked).toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user