J'ai un jeu de construction de blocs 2D et j'essaie de créer des lacs et des rivières générés de manière aléatoire. J'ai étudié l'algorithme de bruit Perlin, mais je n'ai pas réussi à générer des résultats aléatoires et agréables.
J'ai essayé d'utiliser la bibliothèque de bruit python , mais elle n'a pas créé de cartes de manière très aléatoire.
Y a-t-il une fonction de départ qui me manque dans cette bibliothèque pour la rendre plus aléatoire? Quelle variable dois-je changer si je veux qu'elle soit plus aléatoire? Si possible, donnez-moi une réponse moins technique, avec moins de mathématiques et plus de termes python.
La carte est une carte en mosaïque 2D. Voici quelques exemples du caractère non aléatoire de l'autre algorithme. Le code suivant a été généré 3 fois de suite. Je randomisais les octaves et la fréquence avec quelque chose comme ça: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
C'est le code qui a produit la sortie ci-dessus:
"""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()
donc l'heure système qui sera utilisée comme graine. Et au lieu deoctaves = random.randint(1,500000)*.000001+.5
vous pouvez essayer:octaves = random.random()
(il a le même résultat, vous obtiendrez un nombre compris entre 0 et 1, mais c'est beaucoup plus de possibilités que seulement 500000 nombres.)Réponses:
Eh bien, comme il semble, vous n'amorcez pas le générateur de nombres aléatoires. En python, cela peut être fait facilement avec juste un random.seed () .
Et je peux aussi voir que vous générez un nombre compris entre 1 et 500 000 et que vous le faites entre 0 et 1. C'est une méthode fonctionnelle, mais elle est limitée à seulement 500 000 possibilités. Vous êtes mieux avec simplement l'utiliser
random.random()
génère déjà un nombre compris entre 0 et 1, mais avec beaucoup plus de possibilités! Si vous avez toujours besoin d'un nombre compris entre 0,5 et 1,0, comme le suggère votre code, vous pouvez simplement faire:(random.random() * 0.5) + 0.5
Votre code final devrait ressembler à ceci:
C'est tout!
la source
Cela ne répond pas à votre question de programmation spécifique, mais considérez que la création de lacs et de rivières ne consiste pas à placer au hasard des gouttes d'eau et des bandes d'eau entre elles. Il s'agit de la hauteur du terrain - des dépressions (bassins) qui se transforment en lacs et de l'eau qui coule des endroits les plus élevés aux plus bas.
Si vous voulez un excellent exemple de création de lacs et de rivières qui ont du sens, vous pouvez consulter cet article de blog -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html It's une bonne référence pour ce genre de chose si votre objectif est une hydrographie raisonnablement réaliste.
la source
C'est très simple: si vous obtenez la même carte trois fois de suite (ou plus), c'est parce que vous n'avez pas randomisé la graine.
Qu'est-ce que ça veut dire?
Les ordinateurs sont intrinsèquement déterministes (non aléatoires), ils simulent donc le caractère aléatoire. C'est en fait répétitivement aléatoire (c'est pourquoi nous l'appelons "générateur de nombres pseudo aléatoires").
Comment cela marche-t-il?
Lorsque vous créez un nombre aléatoire, vous avez la possibilité de lui donner une "graine". L'important est que si vous utilisez toujours la même graine, vous obtiendrez toujours la même séquence de nombres aléatoires, dans le même ordre. Toujours. Cela peut être bon ou mauvais.
Dans votre cas, il semble que vous n'amorçiez pas le générateur aléatoire, et par défaut, vous obtenez la même graine - il utilise probablement un composant de votre date / heure. Par conséquent, je vous recommande de le randomiser.
Comme Gusatavo l'a mentionné dans sa réponse, vous devez appeler random.seed () . Les documents indiquent que "si X [le paramètre par défaut] est omis ou
None
, l'heure système actuelle est utilisée". Cela devrait être suffisant.la source