Гексы и пиксели: советы по рисованию

Как правильно рисовать шестиугольники для тактических видеоигр и пошаговых стратегий.

Гексы и пиксели: советы по рисованию

Привет! На связи Саша Тюпин. Последние несколько лет я разрабатываю пошаговые стратегиями на гексагональных картах.

В этой статье расскажу как собрать из шестиугольных тайлов нормальную карту с нормальными переходами, да и вообще поделюсь всякими мыслями, техниками, фишечками и прочим.

Речь пойдет прежде всего про 2D и пиксель-арт в частности. Если вы любите 3D и/или текстуры высокого разрешения, то стоит обратить пристальное внимание на туториалы Catlike Coding, там все очень подробно и с кодом объясняется.

Впрочем, про используемые там техники я тоже немного напишу.

Проблематика

Для начала объясню в чем, собственно, сложность и почему для квадратных тайлов есть сотни туториалов, тысячи примеров, специальные инструменты в редакторах и движках, а для гексагональных нет вообще ни черта, хотя про их существование вроде как всем известно.

Проблем тут две:

  • Бесшовные текстуры — их сложно рисовать, поскольку тайлы не прямоугольные и нетривиально стыкуются между собой. Нет инструментария в редакторах.
  • Переходы между биомами — опять же, сложная стыковка гексов и практически полное отсутствие наработанных практик. Непонятно, как вообще подступиться к задаче.

Первая проблема — бесшовные текстуры

Как обычно рисуется прямоугольный тайл? Создаем спрайт, ставим tiled mode по обеим сторонам и смотрим, чтобы он был красивый и бесшовный. А с гексом что делать?

Нет, ну явно не это
Нет, ну явно не это

Здесь есть несколько решений и пара из них даже хорошие.

Забить на бесшовность

Тоже вариант, конечно. Сделать каждый гекс отдельным и хорошо заметным. Путь простой, но скучный. Кроме того, игра становится похожей на настолку, что глубокому погружению не способствует.

UniWar / SH Limited
UniWar / SH Limited

Заранее отрисованная карта

Ну тут уж совсем все просто. Рисуется красивая карта, а слой с гексами натягивается поверх нее. Опционально можно раскидать какие-нибудь препятствия. Такое мы видели в Panzer General и в Героях.

Основная проблема решения — ограниченная вариативность карт, но если этого не требуется, то вариант роскошный. Можно делать сколь угодно сложные и красивые задники.

Бесшовные гексы

А может все-таки можно как-то заморочиться и нарисовать бесшовные гексы? Ладно, варианты есть, но все они так себе.

Чудовищная настойчивость

Нарисовал, сохранил, посмотрел в игре. И так сто раз по кругу. Для настоящих самураев. Если игра очень быстро собирается или способна обновлять ресурсы в рантайме (так кроме веба вообще умеет кто-то?), то, в принципе, терпимо.

Плагины и скрипты

Для Aseprite, кажется, ничего нет, но можно написать скрипт. Правда, придется кнопку жать все время, но хоть что-то. Когда-то я даже делал на Node.js скрипт, который следит за файлом и показывает в браузере превью.

В общем, тут только грусть и костыли, человеческих решений нет. Если знаете редактор, который поддерживает гексагональный тайлинг — напишите в комментах.

Математика и искажения

А что если нарисовать прямоугольный тайл, а потом как-то хитро его повернуть, нарезать и превратить в гексагональный? Пара вариантов есть — они описаны в гайде для Battle for Wesnoth, так что повторять их не буду.

Существует еще несколько вариантов натянуть прямоугольную текстуру на гексагональную сетку, например вот эти:

Гексы и пиксели: советы по рисованию

В первом случае нужно 4 разных гекса для создания бесшовности, во втором всего один, но текстура очень часто повторяется.

На мой взгляд этот путь тупиковый, хотя бы потому что есть следующий, и он намного лучше.

Использовать гексы как маску для текстуры

Берем бесшовную текстуру побольше и обрезаем ее в шейдере по маске гекса. Решение современное, красивое и удобное. Требует знания шейдеров на уровне «сложить и перемножить числа».

Делается достаточно просто, выглядит прекрасно. На мой вкус — лучший вариант.

Ок, с бесшовностью вроде разобрались.

Переходы между биомами

Так, а вот это уже намного сложнее. Биомы-то у нас есть, но они все еще выглядят как из настолки. Нужны красивые переходы между ними.

Посмотрим, что мы тут можем сделать.

Не делать ничего

Ну да, это мы уже проходили. Ничего не делай и ничего не будет.

Блендинг

Есть одна текстура, есть другая, давайте мы их сблендим и будем красиво. Основной способ стыковки игр с 3D окружением и/или текстурами высокого разрешения. Может выглядеть очень пристойно, особенно если блендинг нелинейный и дополнен геометрией.

Sid Meier's Civilization VI / Firaxis Games
Sid Meier's Civilization VI / Firaxis Games

Пустыня мягко перетекает в равнину, а в более резком переходе к траве уже используется другой паттерн — с пятнами. Эффект усиливают геометрия, объединяющая гексы.

Решение это, конечно, хорошее, но для пиксель-арта подходит слабо. Скорее всего получится шумная каша. Я с трудом смог найти пример такого подхода в единственной игре — Emperor of the Fading Suns, где это немного сглажено видимой границей гекса и CRT-монитором.

Emperor of the Fading Suns / Holistic Design
Emperor of the Fading Suns / Holistic Design

При этом переходы к воде здесь все еще сделаны нормально.

В наше время такое делать уже, конечно, стыдно.

Переходы от вершин

Я не знаю игр где используется этот паттерн, но я видел его в паре паков, предназначенных для создания карт. В нем переход рисуется от вершины к вершине для каждого их сочетания. Выглядит это так:

Zeshio
Zeshio

На мой вгляд, этот подход состоит целиком из недостатков:

  • Полный сет переходов это целых 30 тайлов.
  • Все их как-то надо состыковать друг с другом или замаскировать стыки границами гексов.
  • Переходы жестко привязаны к биомам.
  • Иногда непонятно к какому конкретно биому принадлежит гекс.

В общем, не рекомендую.

Переходы от граней

Перейдем к рабочему решению — сделать кучу стыковочных гексов с вариантами для каждого сочетания граней. Вот так это может выглядеть:

Тут читатель может сказать — ты вообще считать умеешь? Здесь же 64 варианта, до пенсии рисовать можно! А ты еще говорил, что 30 это много. А стыковать все добро как?

На самом деле всё не так страшно. Как можно заметить, переходы по граням все очень похожи друг на друга, а значит их можно собрать из боле мелких элементов и в следующей части статьи я расскажу как. А пока просто будем считать, что они у нас есть.

Поясню как это все работает. Возьмем вот такой кусок местности:

Гексы и пиксели: советы по рисованию

Сначала сортируем биомы по приоритету, от этого будет зависеть то, как они будут перекрывать друг друга. В нашем случае это вода — земля — трава.

Биом с самым низким приоритетом, воду, пропускаем.

От земли делаем переходы ко всем биомам с более низким приоритетом, в данном случае к воде.

Гексы и пиксели: советы по рисованию

Покрасим переходы. Я их просто залью одним цветом, но можно применить ту же текстуру, что используется на гексах (см. выше про маски).

Гексы и пиксели: советы по рисованию

Теперь повторяем все то же самое с травой.

Гексы и пиксели: советы по рисованию

Вот и все. Как можно заметить, переходы к воде смотрятся, мягко говоря, не очень. Ну да, чтобы выглядело хорошо, нужно для воды специальные рисовать. Этот подход применяется в небезызвестной Battle for Wesnoth. Когда-то и там были стремные переходы к воде:

Battle for Wesnoth
Battle for Wesnoth

А потом ничего, нарисовали красивые (правда не для всех биомов):

Battle for Wesnoth
Battle for Wesnoth

Двойные переходы от граней

Это мой выбор!

Решение похоже на предыдущее, но, если надо, то переходы рисуются с обоих сторон грани — можно одного типа, а можно разные. Это позволяет делать промежуточные биомы, что решает сразу две проблемы.

Во-первых переходы к воде теперь выглядят по-человечески:

Гексы и пиксели: советы по рисованию

Во-вторых, если переход двух биомов друг в друга выглядит странно — ну там снег в лаву или что-то такое — то можно сделать промежуточный биом из обычной землицы:

Гексы и пиксели: советы по рисованию

Бонус-трек: генерация переходов шейдером

Теоретически возможна, практических реализаций я не встречал. Однако, это не значит, что шейдеры бесполезны — с их помощью можно усилить эффектность перехода, например сделать волны и прибой:

Арт: Lanius00 и Евгений Ламантин

Как нарисовать шаблоны переходов

Теперь давайте разберемся как вообще рисовать все это добро. Я делаю это скриптом на JS (не входит в комплект), как и всю подготовку ассетов, но можно и прямо в игре все собирать, просто спрайтов будет больше в несколько раз.

Каждый гекс может примыкать к другому биому любой комбинацией из своих 6 граней. Я помечу каждую из них номером от 0 до 5, начиная с северо-восточной.

Гексы и пиксели: советы по рисованию

Каждая грань находится в одном из двух состояний — примыкает или нет. Таким образом, каждый шаблон можно обозначить числом от 000000 до 111111 в двоичном формате или от 0 до 63 в десятичном. То есть нам нужно сгенерировать 64 шаблона чтобы покрыть все возможные комбинации.

На самом деле, можно все дико вращать и зеркалить и тогда понадобится только 14, но если уж мы делаем все скриптом, то проще подготовить сразу все варианты.

Гексы и пиксели: советы по рисованию

Теперь надо придумать как бы все это разбить на кусочки, повращать и сложить обратно. К счастью, эта работа уже проделана мной.

Если долго вглядываться в гексы, то можно заметить что каждая вершина в переходе может быть открытой (1), то есть граничить только с одной гранью с переходом, или закрытой (2), то есть с двумя.

Гексы и пиксели: советы по рисованию

Это важное наблюдение, которое позволит нам разбить грани на 4 группы:

  • A — переход от одной открытой вершины к другой.
  • B — переход от закрытой вершины к открытой по часовой стрелке.
  • C — переход от открытой вершины к закрытой по часовой стрелке.
  • D — переход от одной закрытой вершины к другой.
Гексы и пиксели: советы по рисованию

Нарисуем для каждой группы грани 0, 1 и 2. Остальные зеркалим. Можно только 0 и 1, но я считаю, что если уж что-то зеркалить, то нужно делать это по обеим осям сразу, иначе очень заметны повторения. Кроме того, при такой разбивке отзеркаленные грани никогда не буду примыкать друг к другу.

Помимо прочего, я обрезал кусочки шаблонов таким образом, чтобы они не перекрывали друг друга при сборке — резать надо ту половину, которая примыкает к закрытой вершине. Поэтому кусочки из группы D такие куцые.

Гексы и пиксели: советы по рисованию

Теперь собираем шаблоны. Алгоритм простой — берём числа от 0 до 63, переводим в бинарный формат и пробегаемся по всем граням. Для каждой из них смотрим на соседей и выбираем группу, а потом и номер грани. Для 3, 4 и 5 зеркалим по обоим осям 0, 1 и 2 соотвественно. Иногда двигаем кусочек шаблона куда надо.

B2 и отзеркаленный C1 на последнем гексе всё-таки перекрывают другу друга, но только пустыми местами
B2 и отзеркаленный C1 на последнем гексе всё-таки перекрывают другу друга, но только пустыми местами

Теперь неплохо бы проверить как всё это стыкуется. Я собрал для теста вот такую вот загогулину, которая, по идее, включает в себя все возможные стыки:

Гексы и пиксели: советы по рисованию

В качестве финального штриха я подрезал и повернул некоторые кусочки, чтобы часть стыков была видна сразу и вся конструкция занимала меньше места.

Гексы и пиксели: советы по рисованию

Теперь огонь! Можно пользоваться.

Заключение

Такие вот мысли про гексы. Статья не претендует на какой-то ультимативный гайд по теме, скорее на точку отсчета для своих мыслей. Про то как рисовать обычные тайлы материала миллионы, а вот про гексы совсем нет. Пусть будет.

Этой статьи не было бы, если я не разрабатывал свою пошаговую 4x-стратегию на гексагональной карте. Она называется «Луна» и почитать про нее можно в обзорной статье. Девлог я веду в Телеграме и Твитере.

Будьте клевыми, играйте в стратегии! До встречи.

147147
25 комментариев

Если планируется терраформирование то должна быть определенная логика взаимодействия ландшафта. 

То есть ландшафт можeт делится по температуре:
Жара/лава - Тропики - Умеренный климат- Осень - зима/Лед
и по высоте:
Горы - Холмы - лес - Равнина - болото/берег - море

И соотвественно в генераторе ландшафта использовать простое правило что между соседними гекмами не должна быть разница высот и температуры не была бы больше 2х позиций. 

4
Ответить

Спасибо. Про гексы много инфы не бывает! (тут должен был быть донат, но иностранцам не дозволено)

2
Ответить

Может в ЛС у автора реквизиты попросить и скинуть доступным для вас обоих способом? 

1
Ответить

Чел, это суперофигенно!

1
Ответить

Все любят гексы!
Отличный метод, спасибо

1
Ответить

В закладки, хорошая статья, много пищи на подумать. Пишите, пожалуйста, еще!

1
Ответить

Привет! Приятно, что что-то из нарисованного мной пошло в дело

1
Ответить