Как я создаю себе несложный процедурный мир не привлекая внимания санитаров
Захотел сделать небольшую игру чтоб вот тебя закидывало в случайный фентези мир, а ты там "приключался", боссов бил, королевство свое строил. Что-то похожее на Terraria.
Но что делать если ты рукожоп не хочешь особо заморачиваться с качественной процедуркой игрового мира?
Сделать мир из огромных гексагонов? Звучит как хуета отличная идея! 💡
1. Генерируем двумерную карту
Перед тем как создавать гексагоны надо сначала создать/сгенерировать сам ландшафт в виде двумерной матрицы, где будет вообще ландшафт, перепады высот, какие будут в каком биоме и.т.д.
Предварительно я разделил для себя мир на несколько "слоёв":
1. Карта поверхности, на ней будет определена структура мира, в каких ячейках гексы вообще будут существовать собственно. База одним словом
2. Карта высот. На этой карте будут заданы группы высот для гексов, чтоб мир был не "плоский"
3. Карта биомов. На этой карте мы сформируем будущие группы биомов.
4. Карта рек и озер. Несмотря на "крупногексагональный" форм-фактор будущего мира, я хочу чтоб по нему текли реки и были озера. Эта карта пометит условный гекс (или же ячейку массива) как имеющую реку, а там разберёмся
Вот они, слева направо, их боялся весь проект
"Чё ты там нахуевертил" - Скажите вы щурясь как азиат из мема
Я художник! Я так вижу! На самом деле это техническая визуализация уже сформированного мира в 2D матрице, мне же надо было как-то смотреть на то что там выходит вообще.
"И шо ты, пёс, даже не расскажешь как ты это генерировал?" - спросит моя воображаемая аудитория.
А я вам отвечу! Нет. Сейчас все обьясню! И так, А-а-а-а-втомобиль лгоритм в студию!
Смотрите, существуют адекватные разработчики, которые, когда речь заходит за процедурную генерацию, в первую очередь думают в сторону шумов, тот же Шум перлина (Perlin Noise) это идеальный способ выстроить и попиксельную 2д карту ландшафта, с перепадами высот (чем темнее пиксель тем выше). Выглядит он вот так:
Но причём тут адекватные разработчики, и я)
Я сделал это по принципу который придумал себе ещё на первом курсе, саморастущие ядра (шо?)
Если вкратце, в двумерном массиве ограниченном размере мира (например сетка 64×64 ячейки) в случайных местах создается расчетное количество "ядер" генерации, каждое ядро помечает свой адрес как будущую поверхность сразу, и помимо этого несёт в себе случайное количество "зарядов".
Каждую итерацию ядро тратит на то, чтобы "расширится" в случайное направление сетки, захватив, и пометив как будущую поверхность и захваченную ячейку, и так пока у всех ядер не закончатся заряды.
Выглядит это вот так, и в принципе формируется нормальный +- ландшафт:
Жёлтые - ядро
Синие - захваченные ядром ячейки
Точно такой же принцип используется и для карты высот и карты биомов, только теперь ядра формируется в ячейках адреса которых уже являются "поверхностью".
Создаются группы высот которым назначаются высоты, которые при генерации самих гексов собсна говоря и передадутся.
В этот раз ядра, это ромбики, а разным цветом обозначеныгруппы высот:
Ну и абсолютно тот же принцип с биомами, только в ячейках групп биомов хранится ссылка на соответствующий экземпляр класса Biome
Круто! Теперь у нас есть карты двумерных массивов содержащие все необходимые данные для генерации крупногексагонального мира
Используя гайды из Habr свои навыки и умения, я написал скрипт в котором циклом производится проходка по, сохраненным ранее в двумерные массивы, картам данных, и на основе этих данных формируется... Пока только гексагональная 3д структура с разными высотами:
Красиво, но пусто, а давайте запустим туда нашего персонажика которого я создал "за кадром"
Теперь вообще и пусто и некрасиво... Миша все хуня давай по новой! Тебе так никто денег не даст!
Добавим генерацию биомов, чтобы гексам относительно их адреса в карте биомов присваивался соответствующий биом:
Во, уже лучше! Это правда "биомы" пока условные, просто гексы те же, с разными структурками, на итоговый вид это особо не повлияет. Так что нужно на гекс навесить деталей. Tiling time!
Во, так лучше, только надо вот эти стыки на ровной поверхности убрать.
А ещё добавлю "детали" какие нибудь, пусть будут ёлочки в биоме "лес", пока с временной графикой, пара текстурок.
Сделаю банальной "россыпью" этих елочек на каждый гекс
Уже что-то похожее на мир! На этом пока все, впереди ещё туева хуча работы, оптимизация отрисовки деталей (LOD), механизм генерации структур в мире (всякие замки, руины, домики набигающие) и.т.д
+ Мне ещё предстоит решить проблему как игроку перемещаться между гексами с сильными перепадами высот... Лестницы? Винтовые пещеры? Прыгучие платформы? Лианы? Надо думать...
p.s. У самих гексов реализован LOD, и их детализация уменьшается на отдаленном расстоянии от игрока, а дальше и вовсе отключается. Так же я сделаю с деталями на гексах я думаю.
Спасибо всем тем двум людям которые дочитают эту тягомотину до конца!