Oyunumda nasıl rastgele göller ve nehirler oluşturabilirim?


19

2D blok bina oyunum var ve rastgele oluşturulmuş göller ve nehirler yapmaya çalışıyorum. Perlin gürültü algoritmasını inceledim, ancak rastgele ve güzel sonuçlar elde edemedim.

Python gürültü kitaplığını kullanmaya çalışıyorum , ama çok rastgele haritalar oluşturmadı.

Daha rasgele hale getirmek için kütüphanede eksik olduğum bazı tohum fonksiyonu var mı? Daha rasgele gitmesini istersem hangi değişkeni değiştiririm? Mümkünse, daha az matematik ve daha fazla python terimiyle daha az teknik cevap verin.

Harita 2B döşenmiş bir harita. İşte diğer algoritmanın rasgele olmama durumunun bazı örnekleri. Aşağıdaki kod, arka arkaya 3 kez çıktı. Ben oktav ve frekansı böyle bir şey ile rastgele: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

Yukarıdaki çıktıyı üreten kod budur:

"""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

Daha fazla bilgi lütfen. Bu soru şu anki durumunda cevaplanamıyor.
Gustavo Maciel

Biraz daha ekledim, ama bilmen gerekenler.
Julian

İyi bilgiler eklediniz, ama biraz daha fazlasına ihtiyacımız var. "Çok rasgele değil" nedir? Bize herhangi bir ekran görüntüsü verilen sonucun ne olduğunu ve istenen sonucun ne olduğunu görüyor mu? Nasıl denedin? Bize göstermen için herhangi bir kod var mı? Bağlamın nedir? 2D mi yoksa 3D mi? Döşenmiş veya çokgen? Bütün bunlar çok fazlaysa özür dilerim, ama sadece yardım etmeye çalışıyorum. -1 benim değildi, bilgi vermezseniz, soru site için uygun olmayacak ve onu kapatacaklar. Yine yardım etmeye çalışıyorum.
Gustavo Maciel

2
+1, şimdi iyi bir soru :) Perlin gürültüsü ve tüm prosedürel üretim ile iyi değilim, ama rastgele nesneyi mi çekiyorsun? Eğer yanılmıyorsam, bu random.seed()yüzden sistem zamanı tohum olarak kullanılacaktır. Ve bunun yerine octaves = random.randint(1,500000)*.000001+.5deneyebilirsiniz: octaves = random.random() (aynı sonuca sahip, 0 ile 1 arasında bir sayı elde edersiniz, ancak sadece 500000 sayıdan çok daha fazla olasılık elde edersiniz.)
Gustavo Maciel

Teşekkürler +1 :) :) Artı 1 yorum denedim ama yapamam
Julian

Yanıtlar:


7

Göründüğü gibi, rastgele sayı üretecini tohumlamıyorsunuz . Python'da , sadece bir random.seed () ile kolayca yapılabilir .

Ve 1 ile 500000 arasında bir sayı ürettiğinizi ve 0 ile 1 arasında bir sayı oluşturduğunuzu görebiliyorum. Bu işlevsel bir yöntem, ancak sadece 500000 olasılıkla sınırlı. Sadece kullanmak random.random()0 ve 1 arasında bir sayı üretir, ancak çok daha fazla olasılıkla daha iyidir ! Kodunuzun da belirttiği gibi, 0,5 ile 1,0 arasında bir sayıya ihtiyacınız varsa, şunları yapabilirsiniz:(random.random() * 0.5) + 0.5

Son kodunuz aşağıdaki gibi görünmelidir:

import sys
from noise import pnoise2
import random
random.seed()
octaves = random.random()
# octaves = (random.random() * 0.5) + 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

Bu kadar!


Tohumculuğun bununla nasıl bir ilgisi olduğu net değil. Rastgele sayılar tohum eklemezseniz yine de rastgele olur, ancak tekrar eder. Tohumlama yapmamanın tek belirtisi, programı her çalıştırdığınızda aynı rastgele sıraya sahip olmalıdır (her seferinde aynı tohumun kullanıldığı varsayılarak).
Tim Holt

1
Sorunuzda belirtildiği gibi arka arkaya üç kez aynı çıktıyı alıyorsanız , büyük olasılıkla rastgele jeneratörü tohumlamadığınız için mümkündür. Tohumlayın ve sorunu çözüp çözmediğine bakın.
ashes999

Ah ben "arka arkaya 3 kez" bit - "Daha rasgele hale getirmek için o kütüphanede eksik bazı tohum işlevi var mı?" Evet tekrarlanmayan rastgelelik için tohumlama :)
Tim Holt 15:12

8

Bu, özel programlama sorunuza cevap vermiyor, ancak göller ve nehirler oluşturmanın, rastgele su lekeleri ve aralarında su şeritleri yerleştirmekle ilgili olmadığını düşünün. Arazi yüksekliği hakkında - göle dönüşen çöküntüler (havzalar) ve daha yüksek noktalardan alt noktalara akan su hakkında.

Göller ve mantıklı nehirler yaratma büyük bir örnek istiyorsanız, bu blog postasına kontrol edebilirsiniz -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html O var hedefiniz gerçekçi gerçekçi hidrografi ise bu tür şeyler için iyi bir referans.


2

Çok basit: Aynı haritayı arka arkaya üç kez (veya daha fazla) alıyorsanız, bunun nedeni tohumu rastgele seçmemenizdir.

Ne anlama geliyor?

Bilgisayarlar doğası gereği deterministiktir (rastgele olmayan), bu yüzden rasgeleliği simüle ederler. Aslında tekrarlanabilir bir şekilde rastgele (bu yüzden buna "sahte rasgele sayı üreteci" diyoruz).

Bu nasıl çalışıyor?

Rastgele bir sayı oluşturduğunuzda, ona bir "tohum" verme seçeneğiniz vardır. Önemli olan, her zaman aynı tohumu kullanırsanız, her zaman aynı sırayla, aynı sırayla rastgele sayılar alırsınız. Her zaman. Bu iyi ya da kötü olabilir.

Sizin durumunuzda, rastgele jeneratörü tohumlamadığınız anlaşılıyor ve varsayılan olarak aynı tohumu alıyorsunuz - muhtemelen tarihinizin / saatinizin bazı bileşenlerini kullanıyor. Bu nedenle, rastgele seçmenizi öneririm.

Gusatavo'nun cevabında belirttiği gibi, random.seed () öğesini çağırmanız gerekir . Dokümanlar, "X [varsayılan parametre] atlanırsa veya Nonegeçerli sistem saatinin kullanıldığını" belirtir . Bu yeterli olmalı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.