ฉันจะสร้างทะเลสาบและแม่น้ำสุ่มในเกมของฉันได้อย่างไร


19

ฉันมีเกมสร้างบล็อก 2 มิติและพยายามสร้างทะเลสาบและแม่น้ำที่สร้างแบบสุ่ม ฉันได้ดูอัลกอริธึมสัญญาณรบกวนของ Perlin แล้ว แต่ฉันไม่สามารถสร้างผลลัพธ์ที่ดีและสุ่มได้

ฉันพยายามใช้ห้องสมุดเสียงหลามแต่ก็ไม่ได้สร้างแผนที่แบบสุ่มมาก

มีฟังก์ชั่นของเมล็ดพันธุ์ที่ฉันขาดหายไปในห้องสมุดนั้นเพื่อให้สุ่มขึ้นหรือไม่? ฉันจะเปลี่ยนแปลงตัวแปรใดหากฉันต้องการให้สุ่มเพิ่มขึ้น? ถ้าเป็นไปได้ให้คำตอบทางเทคนิคกับฉันน้อยลงโดยใช้คณิตศาสตร์น้อยลง

แผนที่เป็นแผนที่เรียงต่อกันแบบสองมิติ นี่คือตัวอย่างบางส่วนของการไม่สุ่มของอัลกอริทึมอื่น ๆ รหัสต่อไปนี้ถูกเอาท์พุท 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

ข้อมูลเพิ่มเติมโปรด คำถามนี้ไม่สามารถตอบได้ในสถานะปัจจุบัน
Gustavo Maciel

ฉันเพิ่มอีกเล็กน้อย แต่สิ่งที่คุณต้องรู้
Julian

คุณเพิ่มข้อมูลที่ดี แต่เราต้องการข้อมูลเพิ่มเติมอีกเล็กน้อย "ไม่สุ่มมาก" คืออะไร ภาพหน้าจอใด ๆ ให้เราเห็นผลลัพธ์ที่กำหนดและผลลัพธ์ที่ต้องการคืออะไร คุณลองมันได้อย่างไร รหัสใดที่คุณสามารถแสดงให้เราเห็น? บริบทของคุณคืออะไร 2D หรือ 3D? ปูกระเบื้องหรือรูปหลายเหลี่ยม? ขออภัยถ้าทั้งหมดนี้มากเกินไป แต่ฉันพยายามช่วยเท่านั้น -1 ไม่ใช่ของฉันหากคุณไม่ให้ข้อมูลคำถามจะไม่เหมาะสำหรับไซต์และพวกเขาจะปิดมัน อีกครั้งฉันพยายามช่วย
Gustavo Maciel

2
+1, ตอนนี้เป็นคำถามที่ดี :) ฉันไม่เก่งกับเสียงเพอร์ลินและการสร้างขั้นตอนทั้งหมด แต่คุณกำลังเพาะวัตถุสุ่มหรือไม่? หากฉันไม่เข้าใจผิดมันrandom.seed()จะใช้เวลาของระบบเป็นเมล็ด และแทนที่จะoctaves = random.randint(1,500000)*.000001+.5ลองทำดู: octaves = random.random() (มันมีผลเหมือนกันคุณจะได้ตัวเลขระหว่าง 0 ถึง 1 แต่มีความเป็นไปได้มากกว่าหมายเลข 500,000 เท่านั้น)
Gustavo Maciel

ขอบคุณ +1 :) :) พยายามที่จะเพิ่ม 1 ความคิดเห็น แต่ฉันไม่สามารถ
Julian

คำตอบ:


7

ดีที่ดูเหมือนว่าคุณจะไม่ได้เพาะเครื่องกำเนิดไฟฟ้าจำนวนสุ่ม ในหลามก็สามารถทำได้อย่างง่ายดายด้วยเพียงrandom.seed ()

และฉันก็เห็นด้วยว่าคุณกำลังสร้างตัวเลขระหว่าง 1 ถึง 500,000 และทำให้มันอยู่ระหว่าง 0 และ 1 มันเป็นวิธีการใช้งาน แต่มันถูก จำกัด ให้มีความเป็นไปได้เพียง 500,000 คุณดีกว่าด้วยการใช้random.random()มันสร้างตัวเลขระหว่าง 0 ถึง 1 แต่มีความเป็นไปได้มากกว่า! หากคุณยังต้องการตัวเลขระหว่าง 0.5 ถึง 1.0 ตามที่รหัสของคุณแนะนำคุณสามารถทำได้:(random.random() * 0.5) + 0.5

รหัสสุดท้ายของคุณควรมีลักษณะดังนี้:

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

นั่นคือทั้งหมด!


ฉันไม่ชัดเจนว่าการเพาะมีส่วนเกี่ยวข้องกับมันอย่างไร ตัวเลขสุ่มจะยังคงสุ่มถ้าคุณไม่ได้เพาะ แต่จะทำซ้ำ อาการเดียวของการไม่เริ่มต้นควรเป็นลำดับสุ่มที่เหมือนกันทุกครั้งที่คุณเรียกใช้โปรแกรม (สมมติว่าใช้เมล็ดเดียวกันในแต่ละครั้ง)
Tim Holt

1
หากคุณได้รับผลลัพธ์เดียวกันสามครั้งติดต่อกันตามที่กล่าวถึงในคำถามของคุณเป็นไปได้มากว่าคุณยังไม่ได้สร้างตัวสร้างแบบสุ่ม เริ่มต้นมันและดูว่าจะแก้ไขปัญหาได้หรือไม่
ashes999

อ่าฉันไม่เห็นบิต "3 ครั้งในแถว" กำลังอ่านอยู่ "มีฟังก์ชั่นของเมล็ดพันธุ์ที่ฉันขาดหายไปในห้องสมุดนั้นหรือไม่เพื่อให้มันเป็นส่วนที่สุ่มขึ้น" ใช่เพาะสำหรับการสุ่มซ้ำไม่ใช่ :)
ทิมโฮลท์

8

นี่ไม่ใช่การตอบคำถามการเขียนโปรแกรมเฉพาะของคุณ แต่ให้พิจารณาว่าการสร้างทะเลสาบและแม่น้ำไม่ได้เกี่ยวกับการสุ่มวาง blobs ของน้ำและแถบน้ำระหว่างพวกเขา มันเกี่ยวกับความสูงของภูมิประเทศ - เกี่ยวกับการกด (แอ่ง) ที่กลายเป็นทะเลสาบและน้ำที่ไหลจากที่สูงไปยังจุดที่ต่ำกว่า

หากคุณต้องการเป็นตัวอย่างที่ดีของการสร้างทะเลสาบและแม่น้ำที่ให้ความรู้สึกคุณอาจตรวจสอบการโพสต์บล็อกนี้ -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html มัน เป็นการอ้างอิงที่ดีสำหรับสิ่งนี้หากเป้าหมายของคุณคืออุทกศาสตร์ที่สมเหตุสมผล


2

มันง่ายมาก: หากคุณได้รับแผนที่เดียวกันสามครั้งติดต่อกัน (หรือมากกว่า) นั่นเป็นเพราะคุณไม่ได้สุ่มเมล็ด

สิ่งนี้หมายความว่า?

คอมพิวเตอร์มีการกำหนดแน่นอน (ไม่ใช่แบบสุ่ม) ดังนั้นจึงจำลองแบบสุ่ม มันสุ่มซ้ำแล้วซ้ำอีก (นั่นคือเหตุผลที่เราเรียกว่า "ตัวสร้างตัวเลขสุ่มหลอก")

มันทำงานอย่างไร

เมื่อคุณสร้างหมายเลขสุ่มคุณมีตัวเลือกในการให้ "seed" สิ่งที่สำคัญคือถ้าคุณใช้เมล็ดเดียวกันเสมอคุณจะได้หมายเลขสุ่มตามลำดับเดียวกันเสมอ เสมอ. สิ่งนี้อาจดีหรือไม่ดี

ในกรณีของคุณดูเหมือนว่าคุณไม่ได้เพาะเมล็ดกำเนิดแบบสุ่มและโดยค่าเริ่มต้นคุณจะได้รับเมล็ดพันธุ์เดียวกันซึ่งอาจใช้ส่วนประกอบบางส่วนของวันที่ / เวลาของคุณ ดังนั้นฉันขอแนะนำให้คุณสุ่มมัน

ในฐานะที่เป็น Gusatavo กล่าวถึงในคำตอบของเขาคุณจะต้องโทรrandom.seed () เอกสารระบุว่า "ถ้า X [พารามิเตอร์เริ่มต้น] ถูกละเว้นหรือNoneใช้เวลาของระบบปัจจุบัน" นี้ควรจะเพียงพอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.