«Хочется сделать простую карту, чтобы листать её в Telegram». С этого всё и началось. А закончилось — изометрическим движком, авторизацией по WebApp, системой энергии, покупкой участков и боевым ровером с шестью колёсами.
🚀 С чего всё началось?
В начале всё было очень просто.
Мы сделали простенького бота, о котором я уже как-то тут писал, и бэк рендерил картинки с кусочком карты, где ты находишься.
В целом, даже эта идея была вполне рабочей и первые 300 пользователей с разных источников легко собрались. Мы даже провели на 9 мая конкурс "найди звезду победы" и выплатили победителю небольшой приз :)
Но само собой, что бот - не предел мечтаний, нужно было пилить полноценный мини-апп.
На боте лишь проверили гипотезу, отладили механики, типа уменьшения энергии, подзарядки аккумулятора в течении времени, пока не заходишь в игру.
Первый шаг в сторону мини-аппки - сделали вебстраничку, где можно было листать мышкой или пальцем — просто ради визуализации. Прямоугольная сетка, тайлы, немного стилей. Telegram WebApp проглатывал HTML5 на ура. Тогда не было никакой логики, просто подгрузка текстур и картинка под пальцем.
🎮 А потом захотелось интерактивности
Следующим шагом стало добавление изометрии — чтобы выглядело как псевдо-3D. Самое интересное, что даже не потребовалось изменять текстуры. Серьезно :) Они по-прежнему те же самые, квадратные, 64 х 64. И не используется никакой 3д - движок.
вот краткое и понятное объяснение, как строится изометрическая карта из квадратных тайлов:
🧠 Основная идея:
Каждый квадратный тайл поворачивается на 45° и масштабируется по вертикали, чтобы получился ромб (изометрическая проекция). Вместо привычной сетки (x, y) мы рассчитываем экранные координаты (left, top) по формуле:
📐 Формулы для отображения:
При размере одного тайла T:
W = T * sqrt(2) — изометрическая ширина (диагональ квадрата).
H = W / 2 — изометрическая высота (высота ромба).
WX2 = W / 2, HX2 = H / 2 — половинки для смещения от центра.
Переход от логических координат (dx, dy) к пиксельным:
isoX = (dx - dy) * WX2 + centerX; isoY = (dx + dy) * HX2 + centerY;
🧩 Что это даёт:
(dx - dy) — смещает тайл по горизонтали.
(dx + dy) — смещает тайл по вертикали.
centerX, centerY — центр экрана, чтобы карта строилась относительно игрока.
🎯 В результате:
Из обычной квадратной сетки (x, y) формируется ромбовидная карта, где видны и горизонтальные, и вертикальные соседние тайлы.
Центральная клетка (текущий игрок) — всегда по центру, а остальные располагаются вокруг.
Ну а дальше уже дело техники - придумали алгоритм перемещения в 8 направлениях: вверх, вниз, влево, вправо, плюс диагонали.
Подключили ранее обкатанный в чатботе расход энергии за каждый шаг, и разный расход за диагональные движения, в сравнении с линейным. Плюс небольшой рандом :)
Задали запреты на воду, скалы и занятую клетку, чтобы не было “читов”.
🔐 Само собой - авторизация
Чтобы пользователь не “прыгал” по чужим роверам и участкам, мы внедрили Telegram WebApp InitData (это такая строка с хешем, которую фронт передает нам в бэк, а мы - уже на сервере телеграм с токеном бота валидируем подпись. Если сошлась - то пользователь зашел к нам через телегу. Если нет - скорее всего он просто открыл веб-страницу как сайт, или что-то пытается поломать, подделать :)
Telegram сам отдаёт токен с подписью.
Мы проверяем подпись на бэке по HMAC SHA256.
Получаем ID пользователя, сохраняем его в сессии.
Теперь всё честно: ровер – только твой, кристаллы – только твои.
🪐 Стало красивее: добавили кристаллы и рамки
Кристаллы на клетках — можно собирать.
Подсветка клеток: белая рамка — твоя, красная — чужая.
Имена владельцев, чтобы было видно, кто что захватил.
В планах: Покупка участков за кристаллы. Это было в текстовом боте. И ползая по карте, даже видны купленные тобой (белым) и оппонентами (красным) участки.
⚡️ Оптимизация и загрузка ассетов
Мы поняли, что каждая картинка может тормозить игру на слабом устройстве, и:
Добавили прелоадер, который подгружает PNG-шки перед игрой.
Сделали показ спиннера на любом действии (движение, загрузка).
Кэшируем тайлы и обновляем только при движении.
🤖 Как выглядит сейчас
Заходит в Telegram Mini App.
Авторизуется за доли секунды.
Видит изометрическую карту с ровером, кристаллами, участками, рекламными баннерами.
Может двигаться по клеткам, собирать кристаллы (в будущем - бурить и находить ресурсы, торговать ими, покупать землю).
А мы — всё это рисуем прямо в DOM.
Никаких Canvas, WebGL, или тяжелых движков. Только HTML, CSS и немного магии на JS.
💬 Если интересно — покажу, как это выглядит вживую.
Тестить можно тут. А если зайдёт — добавим NFT, фермы и квесты на выживание 😄