Ёжик и яблоки
Пиксельная аркада для браузера. Управляйте ёжиком, ловите яблоки и набирайте очки. Сердца и молнии помогают выжить, а гнилые яблоки замедляют и ослабляют лечение.

Особенности
- Три скина вместе с окружением: зелёный лес, золотая осень и снежная зима.
- Бонусы снимают дебафы, временные сердца защищают от промахов и гнилых яблок.
- Управление с клавиатуры на компьютере и экранными кнопками на сенсорных устройствах; автоматическая пауза при переключении окна или вкладки.
- Единый пиксельный стиль: персонажи, предметы, пейзажи и иконки интерфейса.
- Эффекты бонусов: кольца и всплывающие иконки, золотые искры ускорения, зелёная аура порчи, очищение и разрушение голубого щита. Настройка системы «Уменьшение движения» отключает вращение ёжика и движущиеся частицы, заменяя эффекты спокойными индикаторами.
Игра написана на JavaScript с Three.js: 2D-спрайты отображаются ортографической камерой, интерфейс — HTML/CSS, сборка — Vite. Серверная часть не требуется.
Быстрый запуск
Для разработки нужны Node.js 22.12+ или ветка 20 начиная с 20.19, а также npm. Для игры — браузер с WebGL 2 и клавиатура или сенсорный экран.
npm ci
npm run dev
Откройте адрес из вывода Vite (обычно http://localhost:5173). Открытие index.html через file:// больше не поддерживается.
Управление
←/→— движение.- На сенсорном экране удерживайте экранные кнопки
←/→. Одновременное нажатие останавливает ёжика; отпускание или отмена касания прекращает движение. Прокрутка вне кнопок остаётся доступна. Rили кнопка — новая игра после проигрыша.- Под игровым полем можно выбрать лесной, осенний или зимний скин вместе с окружением: зелёный лес, золотая осень с опавшей листвой или заснеженный лес. Выбор действует и после перезапуска партии; все скины имеют одинаковый хитбокс.
- При потере фокуса игра приостанавливается вместе с таймерами эффектов.
- В горизонтальной ориентации на невысоком экране скины находятся справа от поля, управление — под ним.
Бонусы и баланс
Пропущенное яблоко отнимает половину сердца. Яблоки появляются каждые 1,4 секунды. Первые бонусы и опасности приходят постепенно: молния на 2-й секунде, сердце на 4-й, гнилое яблоко на 6-й.
| Предмет | Эффект | Интервал появления |
|---|---|---|
| Молния | Снимает оба дебафа и даёт скорость ×2 на 8 секунд | 5 секунд |
| Сердце | Снимает оба дебафа и лечит на 1,5 сердца; под порчей — на 0,5. При полном здоровье даёт щит | 6 секунд |
| Гнилое яблоко | Снимает ускорение, замедляет на 30% на 2,5 секунды и ослабляет лечение на 4 секунды | 6 секунд |
Щит выглядит как временное сердце: действует 15 секунд и поглощает один промах или гнилое яблоко целиком, сохраняя ускорение. Максимум пять щитов; используется ближайший к истечению. При полном запасе новое сердце обновляет самый старый щит.
Повторные эффекты обновляют срок, а не складывают силу или длительность. При одновременном сборе сначала обрабатываются гнилые яблоки, затем молнии и сердца: очищающая молния позволяет сердцу лечить в полную силу. Лечение и щиты применяются до штрафов за промахи того же кадра. Поэтому результат не зависит от порядка предметов в массиве. Баланс настраивается в ITEMS и EFFECTS в src/game.js.
Проверки и сборка
После установки зависимостей:
npm test
npm run build
npm run preview
npm test запускает тесты игровой логики и проверку актуальности графики через встроенный Node.js test runner, без браузера. Для проверки конкретной механики:
npm test -- --test-name-pattern="rotten"
npm run preview позволяет проверить готовую сборку в браузере по адресу из вывода команды. Автотесты не проверяют WebGL-отрисовку; перед публикацией проверьте движение, сбор бонусов, смену окружения и перезапуск игры.
Публикация
После npm run build загрузите содержимое dist/ целиком на статический HTTP-хостинг: index.html и каталог assets/. Сборка использует относительные пути, поэтому её можно размещать и в подкаталоге сайта.
На хостинге не нужны Node.js, npm или база данных. npm run preview предназначен для локальной проверки, а не для рабочего сервера. Открывать готовую сборку через file:// также не следует — используйте HTTP-сервер.
Графика
Фоны, предметы, сердца интерфейса и три скина используют согласованные пиксельные палитры. Предметы нарисованы на сетке 16×16, ёжики — 32×24, сезонные фоны — 200×150. SVG содержат только прямоугольные пиксели; Three.js масштабирует текстуры без размытия. Все окружения загружаются при запуске и переключаются одновременно со скином.
Исходник рисунков — scripts/generate-art.js (пиксельные схемы и палитры). После правок запустите npm run art и добавьте обновлённые src/art/*.svg вместе с исходником. Сборка использует готовые SVG; тесты проверяют, что они не устарели.
Код
src/game.js— состояние и шаг симуляции; не зависит от DOM и Three.js, время в секундах.src/view.js— загрузка текстур, Three.js-сцена, спрайты и освобождение GPU-ресурсов.src/effects-view.js— ауры, щиты и кратковременные эффекты получения бонусов; использует игровое время, поэтому замирает на паузе.src/main.js— запуск, пауза, перезапуск и цикл кадров;src/input.js— клавиатура и экранные кнопки с Pointer Events.src/hud.js,src/style.css,index.html— интерфейс поверх сцены.src/assets.js— импорты SVG и список доступных скинов; Vite включает используемые изображения в сборку.