Увеличение вероятности создания похожих плиток рядом друг с другом.


9

Я работаю над системой карт тайлов, которая выглядит следующим образом (зеленый - трава, воздух - белый, камень - серый, а синий - вода):

плитки

Он использует простой генератор случайных чисел, так что с вероятностью 45% черепица может быть травой, 30% - водой и 25% - камнем.

Могу ли я в любом случае увеличить склонность блоков травы / камня к слипанию, образуя массы земли, и превращать водные блоки в океаны (что-то вроде того, что можно увидеть в игре, подобной Minecraft)?

Ответы:


17

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

То, на что вы хотите обратить внимание, это фрактальные типы шума - в данном случае перлин или симплексный шум. Если вы генерируете шум, вы получите значения от -1 до 1.

http://en.wikipedia.org/wiki/Perlin_noise

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

getTerrain(x,y) {
if(perlin_noise(x,y) > 0) {
    if(perlin_noise(x * scale,y * scale) > 0) {
        return rock
    } else {
        return dirt
    }
} else {
    return water
}

Поскольку я считаю, что метод сканирования и броска слишком сложен и не слишком масштабируем, я предложу другой метод, который мне понравился:

Положите сетку на карту, разбивая карту на большие квадраты.

Генерация случайного числа на каждом перекрестке (от 0 до 1 будет работать для ваших процентов)

Разделите, разрезав каждый квадрат на 4 четных квадрата - следуйте старым линиям, и там, где вы найдете линии подразделения, сгенерируйте случайное число между 2 смежными точками, аналогично, для центра креста, сгенерируйте точку, которая находится между самой высокой и самые низкие значения.

Промыть и повторить. Вы получите начальную случайность с первого прохода, но последние проходы дадут некоторую однородность. Извините за псевдослучайные числа:

0-------5  0---3---5 0-1-3-4-5 011233455
|       |  |   |   | | | | | | 012344555
|       |  |   |   | 0-2-4-6-5 002445665
|       |  |   |   | | | | | | 123445666
|       |  2---5---7 2-4-5-7-7 234455777
|       |  |   |   | | | | | | 233455688
|       |  |   |   | 2-3-5-5-9 223455589
|       |  |   |   | | | | | | 233455589
2-------9  2---4---9 2-4-4-5-9 234445579

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

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


+1 Поскольку я думаю, что скачок к шуму, как правило, к этому приведет. Мне интересно, может ли это быть слишком большим скачком, хотя первоначальное «сканирование вокруг и изменение процентов» облегчило мне голосование :)
Джеймс

3

Шум является хорошим решением, как уже упоминалось. Другой вариант - сделать второй проход данных, чтобы подтолкнуть их к нужному макету. Размытие по Гауссу - один из многих способов добиться этого. Выполнение прохода с этим должно дать вам хорошие "круглые" капли каждого типа.

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


2

Относительно простым способом сделать это было бы создание нескольких ядер в случайных положениях. Нарисуйте диаграмму Вороного этих точек. Присвойте элемент каждой области результата.

Это приводит к чему-то довольно уродливому и механически выглядящему. Немного испортите границы, и вы будете в приличной форме.

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

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

Этот пост заслуживает картины, но мне лень ее предоставить.



0

Вы можете сделать это, используя этот метод:

  • положить все плитки в неопределенном списке
  • пока есть плитка в неуказанном списке
  • начать
  • выбрать одну плитку из этого списка
  • проверьте соседей по этой плитке и выберите тип в зависимости от соседей
  • удалить эту плитку из неопределенного списка
  • конец
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.