>>57258Seawolves v0.04 in production. Part IVСделал мало, в первую очередь, добавил анимацию волн (на одной из пикч). Теперь по воде идут волны, чем быстрее игра, тем быстрее. Их количество и цвет зависят от силы ветра. По-моему, выглядеть и ощущаться игра стала как-то живее, даром что мелочь добавил. Кроме того, я расширил классы орудий и кораблей, подготавливаясь к созданию двух оставшихся миссий.
Но рассказать сегодня я хочу вовсе не про это, а хочу воспеть оду таким охуенным парням как perlin noise и simplex noise, с которыми я недавно познакомился. Поэтому, это пост больше для тех, кому интересна процедурная генерация, но кто в глубину особо этим не занимался (для про-инди-гейм-девелоперов тут вряд ли что-то новое, конечно).
Собственно, я хотел сгенерировать карту для второй миссии. Мне нужна была карта с определёнными свойствами: я хотел что-то вроде озера, окружённого со всех сторон берегом, чтобы игроку некуда было улизнуть. Мой текущий алгоритм на основе клеточного автомата, который я использую, очень ограниченный, медленный, практически не кастомизируемый, и вообще был переделан на коленке из более простого алгоритма для генерации пещер, который я видел на roguebasin. Поэтому я стал искать что-то другое. Про шумы, в том числе Перлина, я слышал раньше, но сейчас изучил получше. Хотел сначала разобраться в его математике и написать его реализацию вообще самостоятельно, но нашёл хорошую библиотеку (где реализован и симплексный заодно), поэтому мне не нужно было особо вникать в механику, но я поизучал, какими же полезными свойствами обладают эти шумы. И честно говоря, я просто ошеломлён, насколько они охуенны. Мой старый алгоритм кажется мне теперь таким убогим говном. И очень многие вопросы, которые меня терзали относительно будущей генерации глобального мира, сразу же отпали. Теперь я смотрю на это дело с намного большим оптимизмом.
На первый взгляд, эта серая пятнистая картинка не вызывает такого уж восторга. Но с её помощью можно творить чудеса. Я с помощью matplotlib написал небольшую отдельную прогу, с помощью которой прикинул генерацию этого самого озера для миссии . На этом примере я продемонстрирую некоторые качества этих шумов, которые можно выгодно использовать (на пикче perlin_lake.png). Размер каждой картинки (600х600) вполне соотвествует планируемому размеры карты под миссию (в реалиях игры это 30х30 км). 4 цвета тоже соответствуют типам тайлов - глубокая вода, мелкая вода, песок и трава/лес. Думаю, это всё пойдёт в игру с минимальными изменениями.
1) В первой строчке просто три рандомных озера, со стандартными (т.е. которые больше всего мне понравились) параметрами генерации. Здесь важно отметить одну вещь - сид. Да, эти шумы можно идеально сидить одним целым числом! И это очень круто, с предыдущим алгоритмом это не было возможно (если попотеть, я бы мог, возможно, соорудить нечто вроде сид-матрицы большой размерности, но полезность этого сомнительна). Последующие примеры я показываю с озером с сидом 127 (левый крайний угол).
2) Во второй строчке я поигрался с различными вариантами сложения уровней. Сила шумов в том, что суммируя (с разными весами) шумы с разной степенью "частоты" (ячеистости), можно получать весьма различные результаты. Здесь, например, показаны различные варианты "изрезанности" и геометрической правильности берегов. Всё очень легко настраивается изменением пары коэффициентов
3) В третьей строчке я уменьшал влияние собственно шумов. Суть моего алгоритма в том, что на детерминируемую функцию (которая уменьшает уровень воды по мере приближения к краям) накладываются случайные шумы. Варьируя вес этих шумов, форму озера можно приблизить к геометрически правильной фигуре (можно заметить, что это не круг, а нечто вроде сглаженного квадрата, так специально задумано)
4) В последней строке ещё пара интересных штук.
Во-первых, шумы Перлина можно скейлить, изменяя "разрешение", но не меняя саму форму. Сравните озеро в левом верхнем углу и нижнем левом. Это одно и то же озеро, но в одном случае на поле 600х600, в другом 30х30. И такая возможность менять разрешение намного важнее, чем может показаться. По сути, это одна из ключевых проблем, о которой я долго думал, и которой не мог найти разрешение для алгоритма на клеточных автоматах. Ведь глобальный мир нужно будет генерировать на уровне достаточно больших секторов, иначе количество вычислений просто неподъемно для игрушки. И шумы позволяют это сделать - работать на уровне крупных тайлов, а когда игрок появится в том или ином секторе (например, там завяжется морской бой) "детализировать" нужный квадрат на лету! У шумов также есть ещё одно охуенное свойство, которое я до сих пор не до конца понимаю, как работает, но вычисление значения каждой клетки абсолютно независимо от соседей - свойство, которым тоже не обладают клеточные автоматы, и которое давно не давало мне покоя. А значит, можно сгенерировать какой-то сектор, много позже сгенерировать другой, рядом - и это будет незаметно, они будут идеально стыковаться. Плюс, к вопросу о распределённых вычилениях, генерацию можно, по идее, легко распределить между потоками без каких-либо проблем. В общем, раньше я недоумевал, как игры вроде ДФ генерируют (довольно быстро) миры с таким коллосальным количество тайлов (а это чуть ли не миллиарды), причём выглядящие как будто сгенерированные одним куском, но теперь это становится намного яснее.
Две другие картинки - просто, чтобы заполнить место. В одном случае показал, как можно поиграться с уровнем воды, на том же сиде. В последнем случае изменил формулу для рассчёта расстояния, и в итоге озеро стало более глубоким ближе к серединам сторон.
Как-то так. Для генерации мира, конечно, мне нужно будет изучить ещё много разных трюков и приёмов. Типичный подход, например, использовать карту высот и карту влажности для создания биомов. А ДФ и вовсе использует кучу схожих для определения свойств местности: влажность, дренаж, дикость природы... А мне (посколько игра-то про кораблики) в перспективе нужны хорошие модели для ветров и течений. Добавить к этому создание рек, генерацию городов, проработку всяких экономических отношений и прочего - для всего этого нужны другие подходы. Но в целом, теперь задача генерации мира выглядит намного реалистичнее для меня, хотя бы первые шаги в этом направлении.
Для тех, кто по каким-то причинам дочитал до этого места и всё ещё заинтересован, пару ресурсов.
Хорошая (далеко не единственная, впрочем) библиотека с реализацией шумов Перлина и симплексных, для python:
https://github.com/caseman/noiseЯ использовал именно её.
Неплохая статья, из которой я почерпнул пару идей по обработке шума в необходимую форму:
http://www.redblobgames.com/maps/terrain-from-noise/На этом же сайте полно других релейтед материалов, в том числе другие подходы к генерации местности, статьи по пасфайндингу и прочее.
>>57287Спасибо за совет, действительно, нужно хотя бы для начала изучить как это делается вообще, самые основы. Вполне вероятно, это окажется не так страшно, и можно будет начать продумывать это уже с самого начала.
> я сейчас наслаждаюсь стодварфовой крепостью на 40 тиках/секунду при i7 под капотом.
Графическое фпс понизил? Если занизить его кап до 20-25, то количество "реальных" тиков возрастёт на 10-15, по моему опыту.