AI-конструктор изометрических игр — создайте проходимый мир 2.5D прямо в браузере
Создайте свой AI-конструктор изометрических игр
Опишите изометрический мир и играйте в него мгновенно — ромбовидная сетка, сортировка по глубине и перемещение по клику, всё в браузере. Без кода, без экспорта. Бесплатно.
AI-конструктор изометрических игр берёт письменное описание сцены и возвращает играбельный мир 2.5D: ромбовидную сетку тайлов, камеру, зафиксированную на повороте 45 градусов, объекты, отсортированные от задних к передним, и персонажа, которого можно отправить куда угодно одним кликом. Neta Studio делает это в браузере. Вы вводите фразу, композитор расставляет рельеф и объекты на сетке, и вы нажимаете «Играть». Без установки движка, без экспорта, без конвейера сборки.
То, на что обычно уходят выходные, уже подключено: проекция 2:1, сортировка по глубине и обратное преобразование экрана в тайл, стоящее за перемещением по клику. А управляете вы на самом деле компоновкой, набором тайлов, персонажем, правилами перемещения и тем, как далеко камере разрешено двигаться.
Одно предложение → изометрический мир
Композитор — это первый экран. Одно текстовое поле, размер карты в тайлах и размер тайла. Вы описываете сцену так, как описали бы её дизайнеру уровней, генерируете и попадаете в редактор с уже собранным миром на ромбовидной сетке. По умолчанию это 64 на 64 тайла при 64 на 32 пикселя на тайл, что помещает целый экран мира в одну ортографическую камеру без необходимости масштабирования.
В ответ возвращаются четыре слоя. Земля хранит один идентификатор рельефа на тайл и объединяется в единую сетку, а не в отдельную сетку на каждый тайл. Объекты опираются на зарегистрированные габариты: бочка 1x1, дом 3x3, причал 2x4, который должен касаться кромки воды. Сущности хранятся отдельно от объектов, потому что они двигаются и нуждаются в данных поиска пути. Освещение и туман лежат сверху и не влияют на порядок сортировки.
Камера установлена на поворот 45 градусов и наклон, точно соответствующий ромбу 2:1, то есть atan(0.5), примерно 26,57 градуса, а не 30 градусов, которые приводят в большинстве руководств. Проекция ортографическая, поэтому деления на перспективу нет и тайл у дальнего края карты имеет тот же размер в пикселях, что и тайл у ближнего края. Сортировка по глубине работает ещё до того, как вы нажмёте «Играть».
Что композитор решает за вас
Он выбирает распределение рельефа, плотность объектов для каждого биома и палитру, которая остаётся в пределах одного атласа. Что важнее, он регистрирует габариты — именно то, что позже сохраняет перекрытие корректным. Если вы попросите портовый городок, вы получите причалы, ящики и кромку воды, но он не узнает, что причал должен касаться воды, если вы об этом не скажете.
Что вы всё ещё размещаете вручную
Перекрашивайте рельеф кистью, перетаскивайте объекты из библиотеки и задавайте точки появления. Всё, к чему привязано правило, например мост, который должен перекинуться через реку, вы размещаете сами. Композитор даёт вам начальную компоновку, а не готовый уровень.
01
Напишите описание сцены в поле композитора.
02
Задайте размер карты и размер тайла. 64x64 тайла при 64x32 пикселя — значение по умолчанию для проходимой карты.
03
Сгенерируйте мир и осмотрите его из фиксированной изометрической камеры.
04
Перекрасьте рельеф и переместите объекты. Каждый объект регистрирует свои габариты при размещении.
05
Поставьте персонажа на проходимый тайл, затем нажмите «Играть», чтобы проверить перемещение по клику.
Ромбовидная сетка и сортировка по глубине — всё под контролем
Изометрический тайл — это квадрат, повёрнутый на 45 градусов и сжатый до половины высоты. При tileW = 64 и tileH = 32 преобразование мира в экран имеет вид sx = (x - y) * 32 и sy = (x + y) * 16. Это и есть вся проекция. Это не истинная изометрическая проекция, а диметрическая примерно на 26,57 градуса — именно поэтому ромбы 2:1 попадают на целые пиксели, а настоящая изометрическая сетка на 30 градусов не попадает. Соотношение 2:1 выбрано потому, что оно одинаково сокращает обе оси и позволяет рисовать каждый спрайт для одного угла камеры.
Порядок по глубине при такой проекции — это алгоритм художника: сначала рисуйте объект с меньшим tileX + tileY. Это работает, пока два объекта не окажутся на одной диагонали. Забор в точке (5, 3) и персонаж в точке (4, 4) дают один и тот же ключ 8. Какой бы порядок ни вернула сортировка, он и рисуется сверху, а если сортировка нестабильна, порядок меняется между кадрами и пара мерцает на стыке. Второй сбой — высота. Спрайт, привязанный к своему центру, сортируется по среднему пикселю, поэтому фонарь высотой 96 пикселей рисуется поверх персонажа, стоящего перед его основанием. Привязка должна находиться в нижней части по центру спрайта, на тайле, который занимает объект.
Третий сбой — размер. Здание 3x3, отсортированное как один объект с ключом 20, будет нарисовано поверх персонажа в точке (9, 12) с ключом 21, даже если этот персонаж стоит перед левой колонной здания. Движок читает зарегистрированный габарит и разрезает всё, что больше 1x1, на полосы по колонкам, поэтому персонаж проходит перед одной колонной и за следующей. По той же причине длинная стена не может быть единым спрайтом.
- Ключ сортировкиПервичный ключ — tileX + tileY. Вторичный — край габарита, третичный — стабильный идентификатор сущности, поэтому равные ключи никогда не меняются местами между кадрами.
- Регистрация габаритовКаждый объект объявляет свой габарит в тайлах при размещении. Объект 2x2 не перекроет тайл дорожки 1x1, если вы это не разрешите.
- Разрезание по колонкамОбъекты шире одного тайла разбиваются на полосы и сортируются по полосам. Несколько дополнительных вызовов отрисовки, зато никаких глюков с проходом за объектом.
- Привязка у ногСпрайты вращаются вокруг нижней точки по центру. Центральная точка вращения ломает перекрытие для всего, что выше одного тайла.
- Объединённая земляТайлы земли объединяются или инстансируются по идентификатору рельефа. Карта на 4096 тайлов — это один вызов отрисовки на рельеф, а не 4096 вызовов.
Перемещение по клику на настоящей сетке тайлов
Всё начинается с обратного преобразования проекции. Возьмите позицию указателя, вычтите начало координат камеры и любое смещение из-за чёрных полос, затем вычислите tileX = (sx / 32 + sy / 16) / 2 и tileY = (sy / 16 - sx / 32) / 2, после чего округлите оба значения вниз. Ошибётесь со знаком во втором слагаемом — и персонаж пойдёт к зеркальному тайлу по другую сторону центра ромба. Вот тот баг, на который вы потратите полдня.
Если камера может свободно вращаться или двигаться, не кэшируйте это обратное преобразование. Пустите луч из камеры через указатель, пересеките его с плоскостью земли и переведите точку попадания в мире в тайлы по тем же формулам. Вариант с трассировкой луча занимает несколько строк и выдерживает любое изменение камеры.
Затем проверяйте. Тайл, по которому кликнули, может содержать габарит объекта, быть водой, быть за пределами карты или быть недостижимым. Ограничьте координаты, выходящие за границы, проверьте сетку занятости и запустите A* по 8 соседям со стоимостью диагонали 1,414 и без срезания углов между двумя заблокированными тайлами. Двигайтесь в тайлах в секунду, а не в пикселях в секунду, чтобы скорость оставалась постоянной при изменении размера тайла. Проходите через центры тайлов по сглаженному сплайну с радиусом прибытия около 0,05 тайла, иначе персонаж будет дёргаться на каждой точке маршрута.
01
Переведите указатель в координаты тайла обратным преобразованием или пустите луч в плоскость земли, если камера вращается.
02
Ограничьте границами карты и опросите сетку занятости на предмет объектов, воды и заблокированного рельефа.
03
Запустите A* от текущего тайла персонажа до целевого тайла.
04
Двигайтесь по маршруту в тайлах в секунду по сглаженному сплайну с небольшим радиусом прибытия.
05
Пересчитайте маршрут при новом клике и отмените старый, а не ставьте оба в очередь.
Изометрические жанры, которые можно создать
Четыре жанра охватывают большинство изометрических проектов, и различаются они правилами занятости и временем, а не проекцией. Градостроительный симулятор живёт на многоклеточных габаритах, дорожной сети, которую нужно соединять, и режиме строительства, который показывает габарит до размещения. Тактика пошаговая, поэтому поиск пути выполняется сразу для множества юнитов, а подсветка дальности рисуется прямо на ромбовидной сетке. Подземельный рогалик использует небольшие карты и тесные коридоры, где разрезание стен по колонкам важнее всего, потому что камера никогда не двигается. Экшен-RPG работает в реальном времени, поэтому управление, состояния атаки и смешивание анимаций важнее изящества поиска пути.
Что остаётся неизменным во всех четырёх: ромб 2:1, ключ сортировки, привязка у ног и обратное преобразование при клике. Смена жанра в середине проекта меняет правила занятости и цикл обновления, но не рендерер.
| Жанр | Что меняется | Что остаётся неизменным |
|---|---|---|
| Градостроительный симулятор | Многоклеточные габариты, связность дорог, предпросмотр застройки и поворот | Ромбовидная сетка, ключ сортировки, обратное преобразование при клике для размещения |
| Тактика | Очередь ходов, наложения дальности и линии видимости, предпросмотр маршрутов для каждого юнита | Ромбовидная сетка, разрезание по колонкам, привязка у ног |
| Подземельный рогалик | Небольшие карты, колонны стен, туман и линия видимости | Проекция 2:1, сортировка по глубине, формулы перевода тайла в экран |
| Экшен-RPG | Управление в реальном времени, состояния атаки, смешивание анимаций | Сетка, сетка занятости, перемещение по клику как запасной вариант для касаний |
Играйте прямо сейчас — в браузере
Каждый мир здесь работает в браузере без установки и без экспорта. Граф сцены — Three.js, рендерер — WebGL2 с запасным вариантом WebGL1, а карта загружается как объединённая геометрия земли плюс инстансированные объекты. Вы нажимаете «Играть» — и уже идёте. Поделитесь миром, и кто-то другой будет идти по нему на своей машине с тем же поворотом 45 градусов.
На телефонах тот же путь клика проходит через события указателя, поэтому касание — это клик. Целями касания служат тайлы, а значит, немного неточное касание объекта размером в 1 тайл всё равно попадёт в нужный тайл. Масштабирование щипком по умолчанию отключено на картах шириной менее 32 тайлов, потому что ромб 2:1 уже читается на ширине телефона. Если частота кадров падает, сокращайте число объектов раньше, чем размер карты; инстансирование помогает больше, чем удаление рельефа.
Mini World
Mini World — это случай небольшой карты: компактный ромбовидный остров, горстка объектов, один персонаж, перемещение по клику по всему пространству. Это самый быстрый способ увидеть, как ведут себя объединение земли и сортировка по тайлам, потому что всю карту видно сразу и плохому ключу сортировки негде спрятаться.
The Cyclops' Island
The Cyclops' Island — это случай, где перекрытие действительно важно: высокие объекты, колонны стен и персонаж, который ходит за ними. Понаблюдайте за углом здания, когда персонаж проходит мимо. Полоса спереди рисуется поверх персонажа, полоса сзади — под ним, и ни в один момент персонаж не проступает сквозь стену.
Agent Sprite Forge
Agent Sprite Forge создаёт наборы спрайтов персонажа, нарисованные под изометрический угол, с точкой вращения уже в нижней части по центру и высотой кадра, согласованной с высотой вашего тайла. Оставьте камеру на повороте по умолчанию — и одного набора достаточно. Включите вращение камеры — и понадобится набор на каждый шаг поворота, потому что спрайт, нарисованный для 45 градусов, неправильно читается на 90.
Шагните в мир, которому он принадлежит
Спрайт — это персонаж, которому негде стоять. Последний шаг — тот, которого не предлагает больше никто: возьмите только что созданный набор и поместите его в мир, по которому можно ходить, — небольшой остров, планету, дождливый угол улицы. Каждый мир на этом сайте создан из одного письменного описания и опубликован как страница, в которую можно играть.
FAQ
Нужно ли писать код, чтобы сделать здесь изометрическую игру? +
Нет. Вы описываете мир, перекрашиваете тайлы, размещаете объекты и персонажа и нажимаете «Играть». Скриптинг нужен только для пользовательских правил, например моста, который обрушивается при нажатии на рычаг.
Как обрабатывается сортировка по глубине, когда два объекта находятся в одном ряду? +
Первичный ключ — tileX + tileY, с устойчивым правилом разрешения совпадений, поэтому равные ключи никогда не меняются местами между кадрами. Объекты крупнее одного тайла разрезаются на полосы по колонкам, так что персонаж может пройти перед одной колонной и за следующей.
Использовать спрайтовых персонажей или 3D-сетки? +
Отрисовываются оба, но ведут себя по-разному. Спрайты дешевы, сохраняют вид 2:1 и привязаны к углу поворота, под который были нарисованы. 3D-сетки свободно вращаются вместе с камерой и обходятся дороже на каждого персонажа из-за скелетной анимации и освещения.
Может ли камера вращаться? +
Да, по умолчанию фиксированными шагами поворота по 45 градусов. Свободное вращение работает с 3D-объектами, но ломает спрайтовых персонажей, которым нужен набор на каждый шаг поворота. Ключ сортировки пересчитывается для нового поворота.
Работает ли это на мобильных? +
Да. Касания распознаются как клики, поиск пути и сортировка выполняются по одному и тому же коду, а холст масштабируется под область просмотра. Держите число объектов умеренным на старых телефонах и сокращайте объекты раньше, чем размер карты.
Могу ли я экспортировать мир в другой движок? +
Этапа экспорта нет. Мир работает в браузере и распространяется по ссылке. Пересобрать его в другом месте означает заново создать карту тайлов и повторно экспортировать наборы спрайтов.
Какой размер тайла мне использовать? +
64 на 32 пикселя — значение по умолчанию, хорошо читается и на компьютере, и на телефоне. Перейдите на 32 на 16 для больших стратегических карт, где хочется больше тайлов на экране, или на 128 на 64 для подземельного рогалика с детализированными объектами. Что бы вы ни выбрали, в расчёте клика используются tileW/2 и tileH/2, поэтому меняйте это в одном месте.
Обратно в 3D Game Builder
Все 31 готовых 3D-мира, игры и сцены собраны на одной странице — в каждую из них можно играть.