← Вернуться к урокам

🎮 Система квестов и геймификация

Урок 4 из 5

🎯 Цель урока

В этом уроке мы превратим обычный калькулятор в увлекательную игру! Создадим систему математических квестов с разными уровнями сложности, добавим подсчёт очков, статистику игрока и систему прогрессии.

💡 Что вы узнаете:

• Генерацию случайных математических задач
• Систему уровней сложности
• Подсчёт очков и статистики
• Проверку правильности ответов
• Игровую механику прогрессии

📚 Игровые концепции

Math.random()

Генерация случайных чисел для создания уникальных математических задач

Math.floor()

Округление вниз до целого числа для получения целых чисел в задачах

switch statement

Конструкция для выбора математической операции в зависимости от условий

Объекты настроек

Хранение параметров уровней сложности в удобной структуре данных

Игровые переменные

Отслеживание состояния игры: очки, уровень, серии правильных ответов

🎮 Игровые переменные

Создаём переменные для хранения состояния игры:

// Игровые переменные
let difficulty = 'easy';
let currentProblem = {};
let level = 1;
let score = 0;
let streak = 0;
let totalSolved = 0;

// Настройки уровней сложности
const difficultySettings = {
    easy: { 
        min: 1, 
        max: 10, 
        operations: ['+', '-'] 
    },
    medium: { 
        min: 1, 
        max: 50, 
        operations: ['+', '-', '*'] 
    },
    hard: { 
        min: 1, 
        max: 100, 
        operations: ['+', '-', '*', '/'] 
    }
};
Объект настроек

Каждый уровень имеет min/max значения чисел и доступные операции. Это позволяет легко изменять сложность

🎲 Генерация задач

Создаём функцию для генерации случайных математических задач:

function generateProblem() {
    const settings = difficultySettings[difficulty];
    
    // Выбираем случайную операцию
    const operation = settings.operations[
        Math.floor(Math.random() * settings.operations.length)
    ];
    
    // Генерируем случайные числа
    let num1 = Math.floor(Math.random() * (settings.max - settings.min + 1)) + settings.min;
    let num2 = Math.floor(Math.random() * (settings.max - settings.min + 1)) + settings.min;
    
    // Для деления делаем так, чтобы результат был целым
    if (operation === '/') {
        num1 = num2 * Math.floor(Math.random() * 10 + 1);
    }
    
    // Вычисляем правильный ответ
    let answer;
    switch (operation) {
        case '+': answer = num1 + num2; break;
        case '-': answer = num1 - num2; break;
        case '*': answer = num1 * num2; break;
        case '/': answer = num1 / num2; break;
    }
    
    // Сохраняем задачу
    currentProblem = { num1, num2, operation, answer };
    
    // Отображаем задачу
    const displayOp = operation === '*' ? '×' : operation;
    document.getElementById('mathProblem').textContent = `${num1} ${displayOp} ${num2} = ?`;
    
    // Очищаем поле ввода и сообщения
    document.getElementById('answerInput').value = '';
    document.getElementById('feedback').textContent = 'Введи ответ и нажми "Проверить"!';
    document.getElementById('feedback').className = 'feedback';
}

🧮 Логика генерации:

• Выбираем случайную операцию из доступных для уровня
• Для деления создаём числа так, чтобы результат был целым
• Заменяем * на × для красивого отображения
• Сохраняем правильный ответ для проверки

✅ Проверка ответов

Создаём систему проверки ответов и начисления очков:

function checkAnswer() {
    const userAnswer = parseFloat(document.getElementById('answerInput').value);
    const feedback = document.getElementById('feedback');
    
    // Проверяем, что введено число
    if (isNaN(userAnswer)) {
        feedback.textContent = '❌ Введи число!';
        feedback.className = 'feedback wrong';
        return;
    }
    
    // Проверяем правильность ответа (с небольшой погрешностью для дробей)
    if (Math.abs(userAnswer - currentProblem.answer) < 0.01) {
        // Правильный ответ!
        streak++;
        totalSolved++;
        
        // Начисляем очки в зависимости от сложности и серии
        const basePoints = {
            easy: 10,
            medium: 25,
            hard: 50
        };
        
        const points = basePoints[difficulty] + (streak * 5);
        score += points;
        
        feedback.textContent = `🎉 Правильно! +${points} очков! Серия: ${streak}`;
        feedback.className = 'feedback correct';
        
        // Проверяем повышение уровня
        checkLevelUp();
        
        // Генерируем новую задачу через 1.5 секунды
        setTimeout(() => generateProblem(), 1500);
        
    } else {
        // Неправильный ответ
        streak = 0;
        feedback.textContent = `❌ Неверно! Правильный ответ: ${currentProblem.answer}`;
        feedback.className = 'feedback wrong';
    }
    
    // Обновляем статистику
    updateStats();
}

📊 Система прогрессии

Добавляем повышение уровня и обновление статистики:

function checkLevelUp() {
    // Каждые 10 решённых задач - новый уровень
    const newLevel = Math.floor(totalSolved / 10) + 1;
    
    if (newLevel > level) {
        level = newLevel;
        
        // Показываем поздравление
        setTimeout(() => {
            alert(`🚀 Поздравляем! Ты достиг ${level} уровня!`);
        }, 200);
        
        // Можно добавить особые эффекты
        createLevelUpEffect();
    }
}

function updateStats() {
    // Обновляем отображение статистики
    document.getElementById('level').textContent = level;
    document.getElementById('score').textContent = score;
    document.getElementById('streak').textContent = streak;
    document.getElementById('total').textContent = totalSolved;
}

function createLevelUpEffect() {
    // Создаём визуальный эффект повышения уровня
    const effect = document.createElement('div');
    effect.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 2rem;
        color: #00b894;
        font-weight: bold;
        z-index: 1000;
        animation: levelUp 2s ease-out forwards;
    `;
    effect.textContent = `LEVEL UP! 🚀`;
    document.body.appendChild(effect);
    
    setTimeout(() => effect.remove(), 2000);
}

⚙️ Управление сложностью

Функция для переключения уровней сложности:

function setDifficulty(newDifficulty) {
    difficulty = newDifficulty;
    
    // Обновляем активную кнопку
    document.querySelectorAll('.difficulty-btn').forEach(btn => {
        btn.classList.remove('active');
    });
    document.getElementById(newDifficulty).classList.add('active');
    
    // Генерируем новую задачу с новой сложностью
    generateProblem();
    
    // Показываем уведомление
    const difficultyNames = {
        easy: 'Лёгкий',
        medium: 'Средний', 
        hard: 'Сложный'
    };
    
    const feedback = document.getElementById('feedback');
    feedback.textContent = `🎯 Установлен ${difficultyNames[newDifficulty]} уровень сложности!`;
    feedback.className = 'feedback';
    
    setTimeout(() => {
        feedback.textContent = 'Введи ответ и нажми "Проверить"!';
    }, 2000);
}

⌨️ Поддержка Enter

Добавляем удобство - проверку ответа по нажатию Enter:

function handleKeyPress(event) {
    if (event.key === 'Enter') {
        checkAnswer();
    }
}

// Добавляем обработчик в HTML поле ввода:
// <input onkeypress="handleKeyPress(event)">

🎮 Интерактивная демонстрация

Попробуй нашу систему квестов в действии:

🎯 Математические квесты

1
Уровень
0
Очки
0
Серия
0
Всего
🎯 Твоя задача:
2 + 3 = ?
Введи ответ и нажми "Проверить"!

📈 Расширенная статистика

Добавим более детальную статистику игрока:

// Дополнительные статистические переменные
let correctAnswers = 0;
let wrongAnswers = 0;
let bestStreak = 0;
let timeSpent = 0;
let sessionStart = Date.now();

function updateDetailedStats() {
    // Обновляем лучшую серию
    if (streak > bestStreak) {
        bestStreak = streak;
    }
    
    // Подсчитываем время сессии
    timeSpent = Math.floor((Date.now() - sessionStart) / 1000);
    
    // Можно добавить отображение дополнительной статистики
    const accuracy = totalSolved > 0 ? Math.round((correctAnswers / totalSolved) * 100) : 0;
    
    console.log(`Точность: ${accuracy}%, Лучшая серия: ${bestStreak}, Время: ${timeSpent}с`);
}

function getPlayerRank() {
    // Система рангов основанная на очках
    if (score < 100) return { rank: 'Новичок', icon: '🔰' };
    if (score < 500) return { rank: 'Ученик', icon: '📚' };
    if (score < 1000) return { rank: 'Математик', icon: '🧮' };
    if (score < 2000) return { rank: 'Эксперт', icon: '⭐' };
    return { rank: 'Гений', icon: '👑' };
}

🎓 Итоги урока

  • Генерация задач: Создали систему случайных математических примеров
  • Уровни сложности: Настроили разные параметры для каждого уровня
  • Система очков: Реализовали подсчёт очков с бонусами за серии
  • Прогрессия: Добавили повышение уровня игрока
  • Статистика: Отслеживаем детальную информацию о игре
  • Интерактивность: Обработали пользовательский ввод и обратную связь

🚀 Что дальше?

В финальном уроке мы добавим систему достижений, визуальные эффекты, анимации и сделаем последние штрихи для создания полноценного игрового приложения!