🎯 Цель урока
В этом уроке мы создадим увлекательную систему достижений для игры "Угадай число". Изучим, как мотивировать игроков через награды, очки и прогресс.
Ты узнаешь, как правильно спроектировать систему достижений, которая будет мотивировать игроков возвращаться и улучшать свои результаты.
🎖️ Интерактивная система достижений
Попробуй разблокировать достижения:
🏆 Типы достижений
Хорошая система достижений включает разнообразные цели, которые подходят для разных типов игроков и стилей игры.
🎨 Категории достижений
// Конфигурация системы достижений const ACHIEVEMENTS = { // Достижения точности accuracy: { perfectGuess: { id: 'perfect-guess', name: '🎯 Снайпер', description: 'Угадай число с первой попытки', condition: (stats) => stats.lastGameAttempts === 1, points: 100, rarity: 'legendary' }, sharpshooter: { id: 'sharpshooter', name: '🏹 Меткий стрелок', description: 'Угадай число за 3 попытки или меньше', condition: (stats) => stats.lastGameAttempts <= 3 && stats.lastGameAttempts > 1, points: 50, rarity: 'epic' }, efficient: { id: 'efficient', name: '⚡ Эффективный', description: 'Угадай число за 5 попыток или меньше', condition: (stats) => stats.lastGameAttempts <= 5, points: 25, rarity: 'rare' } }, // Серии побед streaks: { hotStreak: { id: 'hot-streak', name: '🔥 Горячая серия', description: 'Выиграй 3 игры подряд', condition: (stats) => stats.winStreak >= 3, points: 75, rarity: 'epic' }, unstoppable: { id: 'unstoppable', name: '🚀 Неудержимый', description: 'Выиграй 5 игр подряд', condition: (stats) => stats.winStreak >= 5, points: 150, rarity: 'legendary' }, champion: { id: 'champion', name: '👑 Чемпион', description: 'Выиграй 10 игр подряд', condition: (stats) => stats.winStreak >= 10, points: 500, rarity: 'mythic' } }, // Статистические достижения milestones: { firstWin: { id: 'first-win', name: '🌟 Первая победа', description: 'Выиграй свою первую игру', condition: (stats) => stats.totalWins === 1, points: 20, rarity: 'common' }, veteran: { id: 'veteran', name: '🎖️ Ветеран', description: 'Сыграй 25 игр', condition: (stats) => stats.totalGames >= 25, points: 100, rarity: 'rare' }, master: { id: 'master', name: '🏆 Мастер', description: 'Выиграй 50 игр', condition: (stats) => stats.totalWins >= 50, points: 300, rarity: 'legendary' } } }; // Редкость достижений const RARITY_CONFIG = { common: { color: '#95a5a6', multiplier: 1 }, rare: { color: '#3498db', multiplier: 1.5 }, epic: { color: '#9b59b6', multiplier: 2 }, legendary: { color: '#f39c12', multiplier: 3 }, mythic: { color: '#e74c3c', multiplier: 5 } };
Каждое достижение имеет условие проверки, количество очков и редкость, которая влияет на ценность награды.
💰 Система очков
Очки мотивируют игроков и показывают прогресс:
| Действие | Базовые очки | Бонус за сложность | Итого |
|---|---|---|---|
| Победа (лёгкий) | +10 | ×1.0 | 10 |
| Победа (средний) | +10 | ×1.5 | 15 |
| Победа (сложный) | +10 | ×2.0 | 20 |
| Победа (экстрим) | +10 | ×3.0 | 30 |
| Быстрая победа (≤3 попытки) | +25 | ×1.5 | 37.5 |
| Идеальная игра (1 попытка) | +100 | ×2.0 | 200 |
// Система подсчёта очков class ScoreSystem { constructor() { this.basePoints = { win: 10, quickWin: 25, // ≤ 3 попытки perfectGame: 100, // 1 попытка streakBonus: 5, // за каждую игру в серии difficultyBonus: 10 // за каждый уровень сложности }; this.difficultyMultipliers = { easy: 1.0, medium: 1.5, hard: 2.0, extreme: 3.0 }; } // Вычисляем очки за игру calculateGameScore(gameResult) { const { won, attempts, difficulty, maxAttempts, winStreak } = gameResult; if (!won) return 0; // Нет очков за поражение let score = this.basePoints.win; // Бонус за быстроту if (attempts === 1) { score += this.basePoints.perfectGame; } else if (attempts <= 3) { score += this.basePoints.quickWin; } // Бонус за эффективность (процент от максимальных попыток) const efficiency = (1 - (attempts / maxAttempts)) * 50; score += Math.floor(efficiency); // Бонус за серию побед if (winStreak > 1) { score += (winStreak - 1) * this.basePoints.streakBonus; } // Множитель за сложность score *= this.difficultyMultipliers[difficulty]; return Math.floor(score); } // Вычисляем очки за достижение calculateAchievementScore(achievement) { const basePoints = achievement.points || 10; const rarity = achievement.rarity || 'common'; const multiplier = RARITY_CONFIG[rarity].multiplier; return Math.floor(basePoints * multiplier); } // Форматируем отображение очков formatScore(score) { if (score >= 1000000) { return (score / 1000000).toFixed(1) + 'M'; } else if (score >= 1000) { return (score / 1000).toFixed(1) + 'K'; } return score.toString(); } }
⚙️ Реализация системы достижений
Создаём класс для управления достижениями и их проверки:
// Менеджер системы достижений class AchievementManager { constructor(scoreSystem) { this.scoreSystem = scoreSystem; this.unlockedAchievements = new Set(); this.playerStats = { totalGames: 0, totalWins: 0, winStreak: 0, maxWinStreak: 0, totalScore: 0, lastGameAttempts: 0, bestTime: Infinity, perfectGames: 0 }; this.onAchievementUnlocked = null; // Колбэк } // Обновляем статистику после игры updateStats(gameResult) { const { won, attempts, timeSpent, difficulty } = gameResult; this.playerStats.totalGames++; this.playerStats.lastGameAttempts = attempts; if (won) { this.playerStats.totalWins++; this.playerStats.winStreak++; this.playerStats.maxWinStreak = Math.max( this.playerStats.maxWinStreak, this.playerStats.winStreak ); if (attempts === 1) { this.playerStats.perfectGames++; } if (timeSpent < this.playerStats.bestTime) { this.playerStats.bestTime = timeSpent; } // Добавляем очки const gameScore = this.scoreSystem.calculateGameScore({ won, attempts, difficulty, maxAttempts: 7, // Предполагаем стандарт winStreak: this.playerStats.winStreak }); this.playerStats.totalScore += gameScore; } else { this.playerStats.winStreak = 0; // Сброс серии } // Проверяем новые достижения this.checkAchievements(); } // Проверяем все достижения checkAchievements() { const newAchievements = []; // Проходим по всем категориям достижений for (const category of Object.values(ACHIEVEMENTS)) { for (const achievement of Object.values(category)) { // Пропускаем уже разблокированные if (this.unlockedAchievements.has(achievement.id)) { continue; } // Проверяем условие if (achievement.condition(this.playerStats)) { this.unlockAchievement(achievement); newAchievements.push(achievement); } } } return newAchievements; } // Разблокируем достижение unlockAchievement(achievement) { this.unlockedAchievements.add(achievement.id); // Добавляем очки за достижение const points = this.scoreSystem.calculateAchievementScore(achievement); this.playerStats.totalScore += points; // Уведомляем об разблокировке if (this.onAchievementUnlocked) { this.onAchievementUnlocked(achievement, points); } console.log(`🏆 Достижение разблокировано: ${achievement.name} (+${points} очков)`); } // Получаем прогресс для достижений с прогрессом getAchievementProgress(achievementId) { const achievement = this.findAchievementById(achievementId); if (!achievement || !achievement.progressTracker) { return { current: 0, target: 1, percentage: 0 }; } return achievement.progressTracker(this.playerStats); } // Получаем статистику игрока getPlayerStats() { return { ...this.playerStats, achievementsCount: this.unlockedAchievements.size, winRate: this.playerStats.totalGames > 0 ? (this.playerStats.totalWins / this.playerStats.totalGames) * 100 : 0 }; } }
🏆 Твоё задание
Создай систему достижений для игры "Угадай число":
- Спроектируй разнообразные достижения по категориям
- Реализуй систему редкости и ценности наград
- Создай алгоритм подсчёта очков
- Добавь класс AchievementManager
- Реализуй автоматическую проверку условий
- Создай систему уведомлений о разблокировке
- Добавь визуальные эффекты для наград
- Реализуй сохранение прогресса в localStorage
- Протестируй все типы достижений
💡 Помни: хорошие достижения мотивируют и создают долгосрочные цели!