Skip to content
MatarenerPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Ферма для Telegram Mini App

Изометрическая ферма на чистом JavaScript (ES-модули). Рисует PixiJS (WebGL), а логика, движок и скелетная анимация — свои.

Запуск

Модули не работают через file://, поэтому нужен любой локальный веб-сервер:

  • tools\run-local.cmd — двойной клик (нужен Node.js или Python), откроется http://localhost:8080
  • или npm run dev

Полезные параметры адреса:

  • ?debug — FPS, время кадра, фризы, уровень качества и масштаб рендера
  • ?quality=low|mid|high — принудительно выбрать качество (проверка поведения на слабом телефоне)

Редактор карты (только для разработчиков)

Все игроки начинают с одной карты — assets/map.json. Редактировать её:

  1. Запустить tools\editor.cmd (нужен Node.js) — откроется http://localhost:8080/editor.
  2. Левая кнопка мыши — рисовать выбранным инструментом (трава, тропинка, вода, грядка, деревья, камни, лес, дом, колодец, старт призрачка, ластик, перенос). Правая кнопка — двигать карту, колесо — масштаб, [ ] — размер кисти, Ctrl+Z — отмена, Ctrl+S — сохранить.
  3. «Сохранить» записывает assets/map.json прямо в папку проекта. Потом — коммит и пуш (push.cmd).

Редактор открывается только с этого компьютера (localhost) и в сборку dist для игроков не попадает. Жёлтая рамка — стартовый участок: дом, колодец, старт и хотя бы одна грядка должны быть в нём. После изменения карты у игроков сохраняется прогресс (монеты, уровень, участки, рюкзак), а деревья, камни, тропинки и постройки становятся как на новой карте.

Сборка

npm install
npm run build      # → dist/: один минифицированный бандл, CSS, index.html, картинки
npm run preview    # открыть собранную версию на http://localhost:8080

В бандл вшиты список картинок, иконок и стартовая карта: игра не делает за ними отдельных запросов. Папка dist/ в репозиторий не попадает: при каждом пуше в main GitHub Actions сам собирает игру и публикует её на GitHub Pages (.github/workflows/pages.yml). Адрес: https://matarener.github.io/FarmGames/

Подключение к Telegram

  1. Адрес игры — GitHub Pages (выше) или любой другой HTTPS-хостинг с содержимым dist/.
  2. В @BotFather: /newapp (или /mybots → Bot Settings → Menu Button) и укажите адрес index.html.
  3. Внутри Telegram игра сама разворачивается на весь экран, отключает закрытие свайпом вниз, учитывает вырезы экрана и сохраняет прогресс в CloudStorage аккаунта (плюс localStorage).

Как устроено

index.html, style.css     точка входа и интерфейс (mobile-first, отдельные правила для планшета и ПК)
src/main.js               сборка всего вместе, экран загрузки, прогрев, запуск игрового цикла
src/engine/               свой движок
  Game.js                 цикл кадров, пауза в фоне, реже кадры в простое
  Renderer.js             размер холста, плотность пикселей, видимая область мира
  Camera.js               панорама, зум к точке, инерция, границы
  Input.js                тап / перетаскивание / щипок / колесо / наведение / WASD
  Perf.js                 мощность устройства, качество графики, 30 FPS на слабых, замер фризов
  Iso.js                  изометрия 2:1 (тайл 64×32)
  Pathfinding.js          A* на типизированных массивах
  Sprite.js               спрайты из кода, затемнение, загрузка картинок, ГПСЧ
  Audio.js                звуки и музыка, синтезируются на лету (без файлов)
src/skeleton/             своя скелетная анимация
  Skeleton.js             кости (аффинные матрицы), слоты, скины, порядок отрисовки
  Animation.js            ключевые кадры, кривые, события, плавное смешивание анимаций
src/game/
  data.js                 все таблицы и баланс: культуры, растения, предметы, дом, цены
  World.js                карта: клетки, объекты, участки 10×10, туман, сохранение разницы
  Farm.js                 правила фермы: тапы, действия, рост, урожай, рынок, рюкзак
  PixiScene.js            отрисовка всего мира через WebGL (PixiJS), атласы текстур
  artSprites.js           загрузка картинок художника (assets/art) и иконок
  shore.js                берег пруда (рисуется кодом поверх текстуры воды)
  Player.js, ghost.js     персонаж-призрачок: путь, очередь до 6 действий, кости и анимации
  Mover.js                режим «Переставить»: дом, колодец, грядки, тропинки, свои растения и постройки
  placed.js               свои постройки из рюкзака (поливалки, потом декор и здания): поставить, убрать, перенести
  storeAll.js             «Убрать всё»: свои вещи с карты разом в рюкзак (чистые функции, группы — STORE_ALL)
  sprinklers.js           поливалки: какие клетки поливают (сам полив — beds.js growBed)
  beds.js                 грядки: рост и полив, покупка (цена, предел по уровню), грядка в рюкзаке
  buildData.js            здания с крафтом: здания (чертёж, материалы, время стройки), новые товары, рецепты
  buildRules.js           правила зданий (чистые функции): чертёж, стройка, очередь крафта, ускорение
  houseRules.js           улучшение дома по времени (чистые функции): начать, кончилось, ускорить
  buildings.js            здания и дом в игре: леса и здание на карте, окно здания, «+N» за готовое, полоски
  flora.js, wild.js       деревья и кусты: плоды, рост; дикая трава, кусты и саженцы
  inventory.js            рюкзак: чистые функции над состоянием
  planting.js             посадка культур и саженцев: чем платить, порядок и фильтры в окне выбора
  questData.js            таблицы заданий: сюжет и ветки, задания дня/недели/месяца, события по датам
  questRules.js           правила заданий (чистые функции): счёт, награды, смена дня, перенос старых сохранений
  quests.js               задания в игре: тосты, звуки, опыт по событиям правил
  giftData.js             подарки: разделы окна, дорожка ежедневных подарков на 30 дней
  giftRules.js            правила подарков (чистые функции): какой день, забрать, смена дня
  gifts.js                подарки в игре: звук, радость призрака, сохранение
  wheelData.js            колесо фортуны: сектора с призами и шансами, цены вращений
  wheelRules.js           правила колеса (чистые функции): сколько вращений осталось, какой сектор выпал
  wheel.js                колесо в игре (вращение и щелчки рисует окно в UI.js)
  orderData.js            доска заказов: сколько заказов, размер, награда, ожидание, заказчики
  orderRules.js           правила заказов (чистые функции): что просят, сдать, отказаться, позвать сразу
  orders.js               заказы в игре: звук, опыт, счётчики заданий «Продай…» и «Заработай…»
  hints.js                стрелка-подсказка к заданию на карточке
  bars.js                 полоски времени роста
  Save.js                 localStorage + Telegram CloudStorage (с нарезкой на части)
src/ui/UI.js              HUD, всплывающие меню, окна дома, рынка (с доской заказов), рюкзака, заданий, подарков, колеса, настроек
src/editor/MapEditor.js   редактор карты (только локально)
src/telegram/             обёртка над Telegram WebApp API
assets/                   картинки художника и стартовая карта — см. assets/README.md
tools/                    локальный сервер, сборка, нарезка картинок, бот баланса,
                          проверка правил (node tools/test-quests.mjs, test-gifts.mjs,
                          test-wheel.mjs, test-orders.mjs, test-planting.mjs, test-paths.mjs, test-sprinklers.mjs,
                          test-store-all.mjs, test-builds.mjs, test-beds.mjs)
docs/GDD.md               геймдизайн-документ

Правила игры (Farm, flora, wild, inventory, quests, World) отделены от звука и отрисовки, время и случайность передаются параметрами, контент — в таблицах data.js: так их потом можно перенести на сервер.

Задания

Сюжет и пять веток (Огород, Рыбалка, Лес и сад, Стройка, Торговля) идут параллельно, в каждой открыто одно задание. С 3 уровня добавляются задания дня, недели и месяца (сброс по московскому времени) и события по датам. Новое задание, ветка или событие — это строка в questData.js. Окно заданий открывается кнопкой «Задания» в нижнем меню (дом — в «Ещё»). Оно устроено как рюкзак: разделы (Основные, День, Неделя, Месяц, Событие) — колонкой слева, и они видны и у открытого задания, так что из любого задания, в том числе открытого с карточки на экране, можно перейти к любому списку. На экране до трёх заданий: закреплённые игроком и текущее задание сюжета. С ?debug в адресе в «Настройках» есть кнопки «+1 день», «+7 дней» и «Событие» для проверки.

Подарки

Не объект на карте, а кнопка под монетами: она светится, пока есть подарок, который можно забрать, и пропадает, когда забирать нечего. Окно «Подарки» всегда открывается из «Ещё». В окне разделы «Ежедневные», «От друзей», «Приглашения», «События»; пока работают только «Ежедневные». Ежедневные — дорожка из 30 дней входа: раз в день (новый день в 00:00 по Москве, как у заданий) забирается подарок следующего дня, каждый 7-й день — кристаллы, 30-й — сундук с кристаллами, пропущенные дни не сгорают, после 30-го дорожка начинается заново. Награды — giftData.js. С ?debug в «Настройках» кнопка «Подарки заново» сбрасывает дорожку, «+1 день» — следующий день.

Колесо фортуны

Кнопка под подарком светится, пока есть бесплатное вращение на сегодня; окно всегда открывается из «Ещё» → «Колесо». Бесплатно — раз в день, за монеты — 5 раз в день (цена растёт), за кристаллы — без ограничений. Сектор решают правила (wheelRules.js, случайность параметром), окно докручивает колесо до него. Призы, шансы и цены — wheelData.js. С ?debug — кнопка «Колесо заново».

Грядки

Грядки не копают: их покупают на рынке (раздел «Постройки», грядка там первая) и получают за задания «Огорода». Купленная грядка ложится в рюкзак, «Поставить» ставит её на траву, как дорожку: каждое нажатие — готовая грядка, без энергии. Кнопка «Грядки» справа (над «К фермеру», цифра — сколько грядок в рюкзаке) включает расстановку, а если в рюкзаке пусто — открывает рынок сразу на грядке. Каждая следующая грядка дороже, а сколько их можно купить, зависит от уровня (2 + 2 за уровень, не больше 40): считаются все свои грядки, на ферме и в рюкзаке. Предел мешает только покупке: грядки-награды даются и сверх него, а в старых сохранениях остаются все вскопанные. Цены и предел — BEDS в data.js, правила — beds.js (bedLimit, bedPrice, buyBed). Задания про грядки и достижение «Огородник» считают, сколько грядок есть (их даёт мир: ctx.stats у заданий, ctx.bedsAll у достижений), а не события.

Поливалки и свои постройки

Поливалки продаются на рынке в разделе «Постройки», ставятся из рюкзака кнопкой «Поставить» (или «Ещё» → «Переставить» → нажать на пустую траву): первое нажатие на клетку — предпросмотр, голубым видно, какие клетки она польёт, второе нажатие или «Поставить» — ставит. Грядка в зоне поливалки поливается сама, как только просит воды, и за время отсутствия тоже. Виды, клетки полива и цены — SPRINKLERS в data.js. Все свои постройки хранятся в st.placed (placed.js): новая постройка — это строка в OBJECTS с item и предмет в ITEMS с place: 'obj'; свои правила (оплата, стройка, запрет убрать) подключаются через registerPlaced.

Убрать всё своё в рюкзак

«Ещё» → «Переставить» → «Убрать всё» (кнопка видна, пока ничего не выбрано). Окно показывает группы своих вещей с числом и переключателями: дорожки, пустые грядки, пруды (с камышом, рогозом и камнями), починенный колодец, свои взрослые деревья и кусты (висящие плоды — в рюкзак), постройки и растущие ростки (выключены: вернутся саженцами и начнут расти заново). Дом, грядки с посадками, сломанный колодец, дикое, закрытые участки и то, с чем сейчас работает призрачок, остаются. Если после уборки не останется ни пруда, ни колодца, окно предупреждает, что воду будет негде набрать. После уборки режим «Переставить» остаётся: пустая трава — поставить обратно. Пустую грядку и починенный колодец можно убрать и по одной («В рюкзак» в «Переставить»): предметы «Грядка» и «Колодец» (раздел «Постройки»). Грядки ставятся обратно, как дорожки (каждое нажатие на траву — готовая грядка), колодец — как постройка. Правила — beds.js (storeBed/placeBed) и well.js; пока колодец в рюкзаке, при загрузке он сам не возвращается. Группы — STORE_ALL в data.js, правило — storeAll.js (каждая вещь убирается тем же правилом, что и по одной). Новая своя постройка через placed.js попадает в «Постройки» сама; отдельная группа (например, «Декор») — строка в STORE_ALL и одна строка в groupOf.

Доска заказов

Рынок → «Заказы», со 2 уровня. На доске 3 заказа от соседей: 1–3 товара (культуры по уровню, рыба после задания «Рыбалка», плоды своих деревьев и кустов) за монеты в 1,5 раза дороже рынка и опыт. Сданный заказ засчитывается как продажа на рынке. После сдачи новый покупатель приходит через 5 минут, после отказа — через 15, ожидание можно пропустить за кристаллы. Цифра на кнопке «Рынок» — сколько заказов уже можно сдать. Все числа — orderData.js. С ?debug — кнопка «Заказы заново».

Здания с крафтом

Кухня (с 3 уровня), столярная мастерская (4), кузница (5) и камнерезная мастерская (6) — по одной на ферму, 2×2 клетки, как дом. Чертёж покупается на рынке в «Постройках», ставится из рюкзака кнопкой «Построить»: материалы списываются, и на месте стоит это же здание в лесах, пока идёт стройка (полоска над ним, «Достроить сейчас» за кристаллы). Готовое здание открывает своё окно: рецепты сеткой и очередь на 3 места — товары делаются по одному, готовое забирается нажатием на здание (над ним пузырь с галочкой). Ждущий товар можно отменить (продукты вернутся), тот, что делается, — доделать за кристаллы. Здание можно убрать в рюкзак и поставить снова: очередь не теряется. Здания, товары и рецепты — buildData.js, правила — buildRules.js (состояние st.builds), задания — ветка «Мастерские» в questData.js.

Улучшение дома

Улучшение дома идёт по времени (time в HOUSE, data.js: до 2 уровня — 3 мин, до 3 — 20 мин, до 4 — 1 ч, до 5 — 3 ч). Ресурсы списываются сразу, дом стоит в лесах (картинка house_up_<уровень>, полоска над ним), а энергия, лейка и участки остаются прежними, пока стройка не кончится. В окне дома — сколько осталось и «Достроить сейчас» за кристаллы. Правила — houseRules.js (состояние st.houseUp).

Производительность на слабых устройствах

  • Вся графика — картинки художника в атласах видеокарты; игра открывается только когда всё загружено и прогрето (~2 с кадров за экраном загрузки), чтобы в игре не было подгрузок.
  • Земля каждого участка — одна сетка ромбов; объекты не перерисовываются, пока не изменились.
  • Разрешение рендера ограничено по классу устройства (×1 / ×1.5 / ×2). Если кадр не укладывается в бюджет, FPS ограничивается до 30.
  • В простое игра рисует реже, а в фоне останавливается полностью.

Картинки

Как называются картинки, где лежат листы художника и как их нарезать — в assets/README.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages