У меня есть 2D-игра по строительству блоков, и я пытаюсь создать случайно сгенерированные озера и реки. Я изучил алгоритм шума Перлина, но не смог получить случайные и приятные результаты.
Я пытался использовать библиотеку шума Python , но она не создавала карты очень случайно.
Есть ли в этой библиотеке какая-то начальная функция, которую мне не хватает, чтобы сделать ее более случайной? Какую переменную я могу изменить, если я хочу, чтобы она была более случайной? Если возможно, дайте мне менее технический ответ, с меньшим количеством математических выражений и большим количеством терминов на языке питона.
Карта является двумерной мозаичной картой. Вот несколько примеров неслучайности другого алгоритма. Следующий код был выведен 3 раза подряд. Я рандомизировал октаву и частоту примерно так:freq = 16.0 * random.randint(1, 500000) * 0.000001 + 0.5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
Это код, который произвел вывод выше:
"""Writes a 256x256 grayscale simplex noise texture file in pgm format
(see http://netpbm.sourceforge.net/doc/pgm.html)
"""
# $Id: 2dtexture.py 21 2008-05-21 07:52:29Z casey.duncan $
import sys
from noise import pnoise2
import random
octaves = random.randint(1, 500000) * 0.000001 + 0.5
freq = 16.0 * octaves
for y in range(30):
for x in range(40):
n = int(pnoise2(x/freq, y / freq, 1)*10+3)
if n>=1:
n=1
else:
n=0
print n,
print
источник
random.seed()
так что системное время будет использоваться в качестве начального числа. И вместо этогоoctaves = random.randint(1,500000)*.000001+.5
вы можете попробовать:octaves = random.random()
(у него тот же результат, вы получите число от 0 до 1, но его гораздо больше возможностей, чем просто 500000 чисел.)Ответы:
Ну, кажется, вы не заполняете генератор случайных чисел. В python это легко сделать с помощью random.seed () .
И я также вижу, что вы генерируете число от 1 до 500000 и делаете его между 0 и 1. Это функциональный метод, но он ограничен до 500000 возможностей. Вы лучше, просто используя
random.random()
его уже генерирует число от 0 до 1, но с гораздо большими возможностями! Если вам все еще нужно число от 0,5 до 1,0, как предполагает ваш код, вы можете просто сделать:(random.random() * 0.5) + 0.5
Ваш окончательный код должен выглядеть следующим образом:
Это все!
источник
Это не отвечает на ваш конкретный программный вопрос, но учтите, что создание озер и рек - это не случайное размещение капель воды и полосок воды между ними. Речь идет о высоте местности - о впадинах (бассейнах), которые превращаются в озера, и в воду, которая течет из более высоких в более низкие места.
Если вы хотите получить отличный пример создания озер и рек, которые имеют смысл, вы можете проверить это сообщение в блоге -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html Это хороший ориентир для такого рода вещей, если ваша цель - реалистичная гидрография.
источник
Это очень просто: если вы получаете одну и ту же карту три раза подряд (или больше), это потому, что вы не рандомизировали начальное число.
Что это значит?
Компьютеры по своей природе являются детерминированными (неслучайными), поэтому они симулируют случайность. На самом деле это случайное повторение (поэтому мы называем это «генератором псевдослучайных чисел»).
Как это работает?
Когда вы создаете случайное число, у вас есть возможность дать ему «семя». Важно то, что если вы всегда используете одно и то же начальное число, вы всегда получите одну и ту же последовательность случайных чисел в том же порядке. Всегда. Это может быть хорошо или плохо.
В вашем случае, похоже, что вы не заполняете генератор случайных чисел, и по умолчанию вы получаете то же самое начальное число - оно, вероятно, использует какой-то компонент вашей даты / времени. Следовательно, я рекомендую вам рандомизировать это.
Как Гусатаво упомянул в своем ответе, вам нужно вызвать random.seed () . В документе указано, что «если X [параметр по умолчанию] опущен или
None
используется текущее системное время». Этого должно быть достаточно.источник