Як я надихнувся Cookie Clicker і написав власний браузерний Times Clicker

Привіт, DOU! Я соло-розробник. Ще давненько я залип у культовий Cookie Clicker, і мені завжди хотілося спробувати зібрати щось подібне власноруч — зі своїм сюжетом, іншими механіками та кастомним балансом.

У цій статті я хочу поділитися досвідом розробки Times Clicker (timesclicker.pp.ua) класичної браузерної клікер-гри. Я розповім, чому створення «простої гри на одну кнопку» вимагає цікавих архітектурних рішень у React, як правильно зберігати прогрес і розраховувати офлайн-фарм, а також навіщо пакувати це все в PWA.

Ідея: Чому я вирішив зробити свій клікер?

Здавалося б, концепція максимально банальна: є кнопка, є лічильник. Але коли починаєш накладати на це пасивний дохід, систему апгрейдів, множники та різноманітні фікси, звичайний React-стан починає дико гальмувати від десятків рендерів на секунду.

Мені було цікаво подолати ці технічні обмеження і зробити плавний, чуйний продукт, який не соромно запустити на телефоні.

Технічні виклики «ігор на одній кнопці»

1. Ігровий цикл (Game Loop) у React

У класичних веб-додатках інтерфейс оновлюється тільки тоді, коли користувач кудись тисне. У грі стан має змінюватися постійно. Спочатку рука тягнеться написати примітивний setInterval, але для плавної анімації та нарахування ресурсів це жахливий варіант. Довелося затягувати логіку на requestAnimationFrame, щоб автоматичний фарм працював без ривків.

2. Збереження прогресу та офлайн-дохід

Клікер втрачає сенс, якщо гравець втрачає все після закриття вкладки. Тому весь стейт постійно синхронізується з локальним сховищем (localStorage).

Найцікавіше було реалізувати розрахунок офлайн-прогресу: при запуску гра порівнює поточний Date.now() з часом останнього збереження, множить різницю на пасивний дохід і привітно зустрічає гравця заготовленою кількістю ресурсів.

3. Багатомовність

Щоб гра мала ширшу аудиторію, я заклав модульну систему локалізації. Усі текстові константи та перемикачі мов винесені в окремі файли (наприклад, логіка перемикання лежить у www/chooser_lang.js), що дозволяє легко додавати нові локалізації.

Пакування в PWA: Гра як нативний додаток

Щоб грати з телефона було зручно (без зайвих панелей браузера), я упакував проєкт у Progressive Web App (PWA).

Згенерувавши оптимізований білд (папка www), я підключив маніфест і налаштував іконки (icon-192.png, icon-512.png). Тепер достатньо натиснути «Додати на головний екран» умовному користувачеві iOS чи Android — і Times Clicker відкривається на весь екран як звичайний мобільний додаток.

Що далі

Розробка ігор у вебі — це чудовий спосіб перемкнутися від важких робочих тасок і поломаних баз даних. Times Clicker вже доступний за посиланням: timesclicker.pp.ua .

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

Буду радий почути ваші думки! Хто з вас теж писав свої клікери чи ігри на вихідних? Як вирішували проблеми з оптимізацією ігрового циклу в React? Залітайте в коментарі!

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини про геймдев

👍ПодобаєтьсяСподобалось3
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Робити таку гру на реакті, досить спірне рішення, як на мене.

Згоден, що для ігор з фізикою чи складною графікою React не підходить. Але якщо розібратися, то класичний клікер — це на 90% управління станом та рендер UI-компонентів (кнопки, меню, списки апгрейдів). Для цього React підходить чудово. Головним челенджем було якраз не дати йому вмерти від зайвих рендерів і правильно подружити requestAnimationFrame з хуками. Для пет-проєкту і тренування оптимізації — те, що треба). А на чому б ви порадили писати браузерний клікер?

Якесь готове рішення. Phaser , наприклад.

Я ще жодну гру не зробив, а він зробив, хай й на реакті . Я думаю різниця велика