Найти в Дзене

Урок создания игры "Кликер" на HTML5. Получится, даже если раньше не писал код

Мы вместе напишем простой, но увлекательный кликер на чистом
HTML и JavaScript без сложных фреймворков. Даже если ты никогда не
программировал — не переживай: я объясню каждую строчку кода так, что ты не только повторишь за мной, но и поймешь, как это работает. К концу урока у тебя будет готовая игра, которую можно сразу показать друзьям. Кликеры (или "idle-игры") — это жанр игр, где основной механикой является простое нажатие кнопки, приносящее игровую валюту, очки или ресурсы. Самый известный пример — Cookie Clicker, где игрок кликает по гигантскому печенью, чтобы получать больше печенек. ✅ Простота — не нужны сложные навыки, только клики.
✅ Прогресс — даже без активных действий игра "сама зарабатывает" очки (автокликеры).
✅ Удовольствие от роста — апгрейды делают процесс наглядным и приятным. 🔹 Идеальны для обучения — учат основам JavaScript, работе с DOM и логике игр.
🔹 Быстрый результат — за час можно сделать работающий прототип.
🔹 Бесконечно улучшаемы — можно добавлять новые
Оглавление
Создаем игру "Кликер" на HTML 5
Создаем игру "Кликер" на HTML 5

Мы вместе напишем простой, но увлекательный кликер на чистом
HTML и JavaScript без сложных фреймворков. Даже если ты никогда не
программировал — не переживай: я объясню каждую строчку кода так, что ты не только повторишь за мной, но и поймешь, как это работает. К концу урока у тебя будет готовая игра, которую можно сразу показать друзьям.

Что такое кликер-игры и почему они так популярны?

Кликеры (или "idle-игры") — это жанр игр, где основной механикой является простое нажатие кнопки, приносящее игровую валюту, очки или ресурсы. Самый известный пример — Cookie Clicker, где игрок кликает по гигантскому печенью, чтобы получать больше печенек.

Почему они затягивают?

Простота — не нужны сложные навыки, только клики.
Прогресс — даже без активных действий игра "сама зарабатывает" очки (автокликеры).
Удовольствие от роста — апгрейды делают процесс наглядным и приятным.

Зачем их программировать?

🔹 Идеальны для обучения — учат основам JavaScript, работе с DOM и логике игр.
🔹
Быстрый результат — за час можно сделать работающий прототип.
🔹
Бесконечно улучшаемы — можно добавлять новые фичи без предела.

Наш кликер — упрощённый, но он содержит все ключевые элементы жанра! Попробуйте — и вы поймёте, как создаются такие игры.

Как создать HTML-файл в Windows

Если ты никогда не создавал HTML-файлы, не переживай — это очень просто! Вот пошаговая инструкция:

Способ 1: Через "Текстовый документ"

  1. Открой "Проводник" (Win + E) и зайди в папку, где хочешь создать файл.
  2. Кликни правой кнопкой"Создать""Текстовый документ".
  3. Переименуй файл в index.html (важно, чтобы в конце было .html, а не .txt).
  4. Windows спросит: "Вы действительно хотите изменить расширение?""Да".
  5. Теперь файл можно открыть в браузере!

Способ 2: Через "Блокнот" (или другой текстовый редактор)

  1. Открой "Блокнот" (Win + R → введи notepad → Enter).
  2. Напиши HTML-код (например, <h1>Привет, мир!</h1>).
  3. Нажми "Файл" → "Сохранить как...".
  4. В поле "Тип файла" выбери "Все файлы (.)".
  5. Назови файл index.html (следи, чтобы не было .txt в конце).
  6. Выбери папку и нажми "Сохранить".

Проверяем результат

  • Найди свой index.html в папке.
  • Кликни по нему 2 раза — он откроется в браузере.
  • Если видишь текст из кода — всё получилось!

Важные моменты

  • Расширение .html обязательно (не index.html.txt!).
  • Редактировать код можно в Notepad++, VS Code или даже в обычном Блокноте.
  • Если файл не открывается в браузере → проверь, что сохранил его правильно.

Копируем и проверяем игру — это просто!

Вот полный код игры, который нужно вставить в ваш index.html. Просто скопируйте его целиком (Ctrl + C / Ctrl + V), сохраните файл и откройте в браузере — игра сразу заработает!

<!-- Объявление типа документа - HTML5 -->
<!DOCTYPE html>
<!-- Начало HTML-документа с указанием языка (русский) -->
<html lang="ru">
<!-- Head - служебная часть документа, не отображается на странице -->
<head>
<!-- Указание кодировки символов (UTF-8 поддерживает русские буквы) -->
<meta charset="UTF-8">
<!-- Настройка адаптивности для мобильных устройств -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Заголовок страницы (отображается во вкладке браузера) -->
<title>Эмодзи-кликер</title>
<!-- Подключение шрифта Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Comic+Neue:wght@400;700&display=swap" rel="stylesheet">
</head>
<!-- Body - видимая часть страницы -->
<body>
<!-- Основной контейнер игры -->
<div class="game-container">
<!-- Главный заголовок игры -->
<h1>Эмодзи-кликер</h1>
<!-- Блок с отображением счета -->
<div class="score-container">
<!-- Текущее количество очков (будет меняться через JS) -->
<p>Очки: <span id="score">0</span></p>
<!-- Количество автоматических кликов в секунду -->
<p>Кликов в секунду: <span id="cps">0</span></p>
</div>
<!-- Блок с кликабельным элементом -->
<div class="cat-container">
<!-- Основной элемент для кликов (сюда будем добавлять эмодзи) -->
<div id="cat">🐱</div>
<!-- Эффект "+1", который будет появляться при клике -->
<div class="click-effect">+1</div>
</div>
<!-- Магазин улучшений -->
<div class="shop">
<h2>Магазин улучшений</h2>
<!-- Контейнер для всех вариантов улучшений -->
<div class="upgrades">
<!-- Первое улучшение - авто-кликер -->
<div class="upgrade" id="auto-clicker">
<h3>Авто-кликер</h3>
<p>+1 клик в секунду</p>
<!-- Цена улучшения (будет меняться) -->
<p>Цена: <span class="price">10</span></p>
<!-- Количество купленных улучшений -->
<p>Куплено: <span class="count">0</span></p>
<!-- Кнопка для покупки -->
<button>Купить</button>
</div>
<!-- Второе улучшение - эмодзи-друг -->
<div class="upgrade" id="emoji-friend">
<h3>Эмодзи-друг</h3>
<p>+2 клика в секунду</p>
<p>Цена: <span class="price">50</span></p>
<p>Куплено: <span class="count">0</span></p>
<button>Купить</button>
</div>
<!-- Третье улучшение - эмодзи-армия -->
<div class="upgrade" id="emoji-army">
<h3>Эмодзи-армия</h3>
<p>+10 кликов в секунду</p>
<p>Цена: <span class="price">200</span></p>
<p>Куплено: <span class="count">0</span></p>
<button>Купить</button>
</div>
</div>
</div>
</div>
<style>
/* Стили для всей страницы */
body {
font-family: 'Comic Neue', cursive; /* Веселый рукописный шрифт */
background-color: #ffebf3; /* Нежно-розовый фон страницы */
margin: 0; /* Убираем внешние отступы */
padding: 20px; /* Внутренние отступы по краям */
display: flex; /* Включаем flex-разметку */
justify-content: center; /* Центрируем по горизонтали */
align-items: center; /* Центрируем по вертикали */
min-height: 100vh; /* Минимальная высота = высоте экрана (viewport height) */
}
/* Основной контейнер игры */
.game-container {
background-color: white; /* Белый фон */
border-radius: 20px; /* Закругленные углы */
padding: 30px; /* Внутренние отступы */
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); /* Тень с размытием */
text-align: center; /* Выравнивание текста по центру */
max-width: 600px; /* Максимальная ширина */
width: 100%; /* Занимает 100% доступной ширины */
}
/* Заголовок игры */
h1 {
color: #ff6b9d; /* Розовый цвет текста */
margin-top: 0; /* Убираем верхний отступ */
}
/* Контейнер счета */
.score-container {
background-color: #fff5f7; /* Светло-розовый фон */
padding: 15px; /* Внутренние отступы */
border-radius: 10px; /* Закругленные углы */
margin-bottom: 20px; /* Отступ снизу */
}
/* Параграфы внутри контейнера счета */
.score-container p {
margin: 5px 0; /* Отступы сверху и снизу */
font-size: 18px; /* Размер текста */
color: #555; /* Темно-серый цвет текста */
}
/* Контейнер для кликабельного элемента */
.cat-container {
position: relative; /* Позиционирование для дочерних элементов */
margin: 20px 0; /* Отступы сверху и снизу */
}
/* Стили главной кнопки (котика) */
#cat {
width: 200px; /* Ширина */
height: 200px; /* Высота */
border-radius: 50%; /* Делаем круг */
cursor: pointer; /* Меняем курсор на "указатель" */
background-color: #ff9eb7; /* Фоновый цвет */
display: flex; /* Flex-контейнер */
justify-content: center; /* Центрируем по горизонтали */
align-items: center; /* Центрируем по вертикали */
font-size: 100px; /* Размер эмодзи */
margin: 0 auto; /* Центрируем блок */
user-select: none; /* Запрещаем выделение текста */
transition: transform 0.1s, background-color 0.3s; /* Плавные анимации */
}
/* Стили при нажатии на кнопку */
#cat:active {
transform: scale(0.95); /* Уменьшаем размер на 5% */
background-color: #ff6b9d; /* Меняем цвет фона */
}
/* Эффект "+1" при клике */
.click-effect {
position: absolute; /* Абсолютное позиционирование */
top: -20px; /* Позиционируем выше кнопки */
left: 50%; /* Центрируем */
transform: translateX(-50%); /* Точное центрирование */
color: #ff6b9d; /* Цвет текста */
font-weight: bold; /* Жирный шрифт */
font-size: 24px; /* Размер текста */
opacity: 0; /* Изначально невидим */
transition: all 0.5s; /* Плавное появление/исчезновение */
}
/* Стили магазина улучшений */
.shop {
margin-top: 30px; /* Отступ сверху */
background-color: #f0f9ff; /* Голубоватый фон */
padding: 15px; /* Внутренние отступы */
border-radius: 10px; /* Закругленные углы */
}
/* Контейнер для всех улучшений */
.upgrades {
display: flex; /* Flex-разметка */
flex-wrap: wrap; /* Перенос на новую строку */
justify-content: center; /* Центрируем элементы */
gap: 15px; /* Расстояние между элементами */
margin-top: 15px; /* Отступ сверху */
}
/* Стили одного улучшения */
.upgrade {
background-color: white; /* Белый фон */
border-radius: 10px; /* Закругленные углы */
padding: 15px; /* Внутренние отступы */
width: 150px; /* Фиксированная ширина */
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); /* Легкая тень */
}
/* Заголовок улучшения */
.upgrade h3 {
color: #5d9bff; /* Синий цвет текста */
margin-top: 0; /* Убираем отступ сверху */
}
/* Текст в улучшении */
.upgrade p {
margin: 8px 0; /* Отступы сверху и снизу */
font-size: 14px; /* Размер текста */
color: #666; /* Серый цвет текста */
}
/* Кнопка покупки */
.upgrade button {
background-color: #5d9bff; /* Синий фон */
color: white; /* Белый текст */
border: none; /* Без рамки */
padding: 8px 15px; /* Внутренние отступы */
border-radius: 5px; /* Закругленные углы */
cursor: pointer; /* Курсор-указатель */
font-family: inherit; /* Наследуем шрифт */
transition: background-color 0.3s; /* Плавное изменение цвета */
}
/* Кнопка при наведении */
.upgrade button:hover {
background-color: #3a7bd5; /* Темно-синий фон */
}
/* Неактивная кнопка */
.upgrade button:disabled {
background-color: #ccc; /* Серый фон */
cursor: not-allowed; /* Курсор "недоступно" */
}
</style>
<script>
// ========== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ==========
// Объект gameState хранит все данные игры в одном месте
const gameState = {
score: 0, // Текущее количество очков игрока
cps: 0, // Кликов в секунду (от англ. "clicks per second")
// Объект с доступными улучшениями и их параметрами
upgrades: {
// Первое улучшение - авто-кликер
"auto-clicker": {
price: 10, // Начальная цена улучшения
cps: 1, // Сколько кликов в секунду добавляет
count: 0 // Сколько таких улучшений куплено
},
// Второе улучшение - эмодзи-друг
"emoji-friend": {
price: 50,
cps: 2,
count: 0
},
// Третье улучшение - эмодзи-армия
"emoji-army": {
price: 200,
cps: 10,
count: 0
}
},
// Массив с эмодзи-котиками, которые будут появляться при кликах
emojis: ["🐱", "😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀"]
};
// ========== DOM ЭЛЕМЕНТЫ ==========
// Объект elements хранит ссылки на важные элементы страницы,
// чтобы не искать их каждый раз заново
const elements = {
score: document.getElementById("score"), // Элемент для отображения очков
cps: document.getElementById("cps"), // Элемент для отображения кликов в секунду
cat: document.getElementById("cat"), // Кликабельный элемент с котиком
clickEffect: document.querySelector(".click-effect") // Эффект "+1" при клике
};
// ========== ИНИЦИАЛИЗАЦИЯ ИГРЫ ==========
/**
* Главная функция инициализации игры
* Вызывается один раз при загрузке страницы
* Настраивает все компоненты игры в правильном порядке
*/
function initGame() {
// 1. Инициализация магазина улучшений:
// - Создает все кнопки улучшений
// - Настраивает их обработчики событий
// - Устанавливает начальные цены
initShop();
// 2. Настройка обработчика кликов по основной кнопке:
// - Добавляет обработчик события 'click' на кнопку котика
// - При клике будет вызываться функция handleClick()
initClickHandler();
// 3. Запуск автоматических кликов:
// - Активирует систему пассивного заработка
// - Каждую секунду добавляет очки (если есть улучшения)
startAutoClicker();
// 4. Установка случайного эмодзи для кнопки:
// - Выбирает случайный эмодзи из доступных
// - Отображает его на основной кнопке
setRandomEmoji();
// 5. Первоначальное обновление интерфейса:
// - Отображает начальные значения счета (0)
// - Показывает начальное количество кликов в секунду (0)
// - Обновляет состояние кнопок улучшений
updateUI();
}
// ========== ОБНОВЛЕНИЕ ИНТЕРФЕЙСА ==========
/**
* Функция updateUI - главная функция для обновления всего интерфейса игры
* Она вызывается каждый раз, когда нужно показать изменения в игре
*/
function updateUI() {
// 1. Обновляем отображение счета:
// - Берем элемент для отображения очков (elements.score)
// - Устанавливаем его текстовое содержимое равным текущему счету из gameState
elements.score.textContent = gameState.score;
// 2. Обновляем отображение кликов в секунду:
// - Берем элемент для отображения CPS (elements.cps)
// - Устанавливаем его текстовое содержимое равным текущему значению из gameState
elements.cps.textContent = gameState.cps;
// 3. Обновляем состояние кнопок улучшений:
// Вызываем отдельную функцию, которая проверит, какие улучшения можно купить
updateUpgradeButtons();
}
/**
* Функция updateUpgradeButtons проверяет, какие улучшения доступны для покупки
* и делает кнопки активными/неактивными в зависимости от текущего счета
*/
function updateUpgradeButtons() {
// 1. Получаем все ключи (названия) улучшений из объекта gameState.upgrades
// Object.keys() возвращает массив: ["auto-clicker", "emoji-friend", "emoji-army"]
Object.keys(gameState.upgrades).forEach(id => {
// 2. Для каждого улучшения:
// - Получаем данные об улучшении (цена, CPS, количество)
const upgrade = gameState.upgrades[id];
// - Находим кнопку этого улучшения на странице:
// Сначала находим блок улучшения по id, затем внутри него кнопку
const button = document.getElementById(id).querySelector("button");
// 3. Проверяем, хватает ли денег на улучшение:
// - Если очков меньше чем цена (gameState.score < upgrade.price),
// то кнопка будет disabled (неактивная)
// - Иначе кнопка будет активной
button.disabled = gameState.score < upgrade.price;
});
}
// ========== МАГАЗИН УЛУЧШЕНИЙ ==========
/**
* Функция инициализации магазина - настраивает все улучшения
*/
function initShop() {
// 1. Перебираем все доступные улучшения из gameState.upgrades
Object.keys(gameState.upgrades).forEach(id => {
// 2. Находим HTML-элемент этого улучшения по его id
const upgradeElement = document.getElementById(id);
// 3. Получаем данные об улучшении из gameState
const upgrade = gameState.upgrades[id];
/**
* Вложенная функция для обновления отображения улучшения
*/
function updateUpgradeInfo() {
// 4. Обновляем цену улучшения на странице
upgradeElement.querySelector(".price").textContent = upgrade.price;
// 5. Обновляем количество купленных улучшений
upgradeElement.querySelector(".count").textContent = upgrade.count;
}
// 6. Добавляем обработчик клика на кнопку покупки
upgradeElement.querySelector("button").addEventListener("click", () => {
// Проверяем, хватает ли очков для покупки
if (gameState.score >= upgrade.price) {
// 7. Если хватает - совершаем покупку:
// - Вычитаем цену из общего счета
gameState.score -= upgrade.price;
// - Увеличиваем счетчик купленных улучшений
upgrade.count++;
// - Увеличиваем общее количество кликов в секунду
gameState.cps += upgrade.cps;
// 8. Увеличиваем цену для следующей покупки (на 30%)
upgrade.price = Math.floor(upgrade.price * 1.3);
// 9. Обновляем интерфейс игры
updateUI(); // Обновляем общий счет и CPS
updateUpgradeInfo(); // Обновляем информацию об улучшении
}
});
// 10. Первоначальное отображение информации об улучшении
updateUpgradeInfo();
});
}
// ========== ОБРАБОТКА КЛИКОВ ==========
/**
* Функция инициализации обработчика кликов по главной кнопке
*/
function initClickHandler() {
// 1. Находим элемент котика (уже сохранен в elements.cat)
// 2. Добавляем обработчик события 'click', который вызывает handleClick
elements.cat.addEventListener("click", handleClick);
// Эквивалентная запись с пояснением:
// elements.cat.addEventListener("click", function(event) {
// handleClick(event);
// });
}
/**
* Обработчик клика по главной кнопке (котику)
* Выполняется каждый раз, когда игрок кликает по кнопке
*/
function handleClick() {
// 1. Увеличиваем счет игры на 1 очко
gameState.score++;
// 2. Обновляем интерфейс (отображаем новый счет)
updateUI();
// 3. Показываем визуальный эффект "+1"
showClickEffect();
// 4. Запускаем анимацию нажатия кнопки
animateButton();
// 5. Меняем эмодзи на случайное из доступных
setRandomEmoji();
}
/**
* Функция отображения визуального эффекта при клике
* Показывает анимацию "+1" над кнопкой
*/
function showClickEffect() {
// Получаем элемент эффекта из заранее сохраненных элементов
const effect = elements.clickEffect;
// 1. Делаем эффект видимым:
effect.style.opacity = "1"; // Полная видимость
// 2. Поднимаем эффект выше кнопки:
effect.style.top = "-40px"; // На 40px выше исходного положения
// 3. Устанавливаем текст "+1"
effect.textContent = "+1";
// 4. Добавляем случайное смещение по горизонтали:
// - Math.random() дает число от 0 до 1
// - Вычитаем 0.5 чтобы получить от -0.5 до 0.5
// - Умножаем на 40 для диапазона от -20 до 20px
const offsetX = (Math.random() - 0.5) * 40;
// 5. Устанавливаем позицию с учетом смещения:
// calc(50% + ...) центрирует эффект, а offsetX добавляет случайность
effect.style.left = `calc(50% + ${offsetX}px)`;
// 6. Через 500 миллисекунд (0.5 секунды) скрываем эффект:
setTimeout(() => {
effect.style.opacity = "0"; // Полная прозрачность
effect.style.top = "-20px"; // Возвращаем в исходное положение
}, 500);
}
/**
* Функция анимации кнопки при клике
* Создает эффект "нажатия" кнопки
*/
function animateButton() {
// 1. Уменьшаем размер кнопки до 95% (эффект нажатия)
elements.cat.style.transform = "scale(0.95)";
// 2. Через 100 миллисекунд (0.1 секунды) возвращаем кнопку в исходный размер
setTimeout(() => {
elements.cat.style.transform = "scale(1)"; // 100% от исходного размера
}, 100);
}
/**
* Функция установки случайного эмодзи
* Меняет изображение на кнопке при каждом клике
*/
function setRandomEmoji() {
// 1. Генерируем случайный индекс от 0 до количества эмодзи-1
const randomIndex = Math.floor(Math.random() * gameState.emojis.length);
// 2. Устанавливаем случайное эмодзи в качестве содержимого кнопки
elements.cat.textContent = gameState.emojis[randomIndex];
}
// ========== АВТОМАТИЧЕСКИЕ КЛИКИ ==========
/**
* Функция запуска автоматических кликов
* Добавляет очки каждую секунду в зависимости от купленных улучшений
*/
function startAutoClicker() {
// Устанавливаем интервал, который будет выполняться каждую секунду (1000мс)
setInterval(() => {
// Проверяем, есть ли автоматические клики (cps > 0)
if (gameState.cps > 0) {
// Увеличиваем счет на количество кликов в секунду
gameState.score += gameState.cps;
// Обновляем отображение счета
updateUI();
}
}, 1000); // Интервал 1000 миллисекунд = 1 секунда
}
// ========== ЗАПУСК ИГРЫ ==========
// Инициализируем игру при загрузке страницы
initGame();
</script>
</body>
</html>

Поздравляю! Вы только что создали свою первую HTML5-игру на JavaScript — веселый «Эмодзи-кликер» с магазином улучшений. Вы создали полноценную игровую механику с нуля, используя только базовые технологии веба.

🎮 Хочешь делать игры, но не знаешь, с чего начать?

Попробуй себя в геймдеве — бесплатно!

👉 У меня есть мини-курс по HTML, CSS и JavaScript, где ты:

🔸 разберёшься с основами HTML (да, прямо с нуля)

🔸 сделаешь интерактивную историю с выбором

🔸 начнёшь путь к своей первой игре — прямо в браузере

📘 Первые 2 урока — бесплатно. Поймёшь, нравится ли тебе, и решишь, хочешь ли продолжать.

Дальше — по подписке: удобно, без перегруза и с результатом.

💬 Всё просто, пошагово и без сложных слов. Даже если ты никогда не пробовал кодить.

🔗 Хочу начать курс бесплатно и сделать свою игру

✨ Начни сегодня. Сделай первую игру — и пойми, каково это: быть по ту сторону экрана!