Làm thế nào tôi có thể tạo ra các hồ và sông ngẫu nhiên trong trò chơi của mình?


19

Tôi có một trò chơi xây dựng khối 2D và đang cố gắng tạo ra các sông và sông được tạo ngẫu nhiên. Tôi đã xem xét thuật toán nhiễu Perlin, nhưng, tôi không thể làm cho nó tạo ra kết quả ngẫu nhiên và tốt đẹp.

Tôi đã cố gắng sử dụng thư viện tiếng ồn python , nhưng, nó không tạo ra bản đồ rất ngẫu nhiên.

Có một số chức năng hạt giống tôi đang thiếu trên thư viện đó để làm cho nó ngẫu nhiên hơn? Biến nào để tôi thay đổi nếu tôi muốn nó đi ngẫu nhiên hơn? Nếu có thể, hãy cho tôi một câu trả lời ít kỹ thuật hơn, với ít thuật ngữ hơn và nhiều thuật ngữ trăn hơn.

Bản đồ là một bản đồ lát gạch 2D. Dưới đây là một số ví dụ về tính không ngẫu nhiên của thuật toán khác. Các mã sau đây đã được xuất ra 3 lần liên tiếp. Tôi đã ngẫu nhiên các quãng tám và tần số với một cái gì đó như thế này: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

Đây là mã đã tạo ra đầu ra ở trên:

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

Thêm thông tin, xin vui lòng. Câu hỏi này không thể được trả lời ở trạng thái hiện tại.
Gustavo Maciel

Tôi đã thêm một chút nữa, nhưng, những gì bạn cần biết.
Julian

Bạn đã thêm thông tin tốt, nhưng chúng tôi cần thêm một chút. "Không ngẫu nhiên" là gì? Bất kỳ ảnh chụp màn hình nào cho chúng tôi xem kết quả đã cho là gì và kết quả mong muốn là gì? Làm thế nào bạn đã thử nó? Bất kỳ mã để bạn chỉ cho chúng tôi? Bối cảnh của bạn là gì? 2D hay 3D? Lát hay đa giác? Xin lỗi nếu tất cả điều này là quá nhiều, nhưng tôi chỉ đang cố gắng giúp đỡ. -1 không phải là của tôi, nếu bạn không cung cấp thông tin, câu hỏi sẽ trở nên không phù hợp với trang web và họ sẽ đóng nó. Vì vậy, một lần nữa, tôi đang cố gắng giúp đỡ.
Gustavo Maciel

2
+1, bây giờ là một câu hỏi hay :) Tôi không tốt với tiếng ồn perlin và tất cả các quá trình tạo thủ tục, nhưng, bạn có đang gieo mầm đối tượng ngẫu nhiên không? Nếu tôi không nhầm, random.seed()vì vậy thời gian hệ thống sẽ được sử dụng làm hạt giống. Và thay vì octaves = random.randint(1,500000)*.000001+.5bạn có thể thử: octaves = random.random() (nó có cùng kết quả, bạn sẽ nhận được một số từ 0 đến 1, nhưng khả năng của nó nhiều hơn chỉ là 500000 số.)
Gustavo Maciel

Cảm ơn +1 :) :) Đã thử cộng thêm 1 nhận xét nhưng tôi không thể
Julian

Câu trả lời:


7

Vâng, như có vẻ như, bạn không gieo hạt các bộ tạo số ngẫu nhiên. Trong python, nó có thể được thực hiện dễ dàng chỉ với Random.seed () .

Và tôi cũng có thể thấy bạn đang tạo ra một số trong khoảng từ 1 đến 500000 và biến nó thành từ 0 đến 1. Đây là một phương pháp chức năng, nhưng nó được giới hạn ở mức 500000 khả năng. Bạn tốt hơn chỉ với việc sử dụng random.random()nó đã tạo ra một số từ 0 đến 1, nhưng với nhiều khả năng hơn! Nếu bạn vẫn cần một số trong khoảng từ 0,5 đến 1,0, như mã của bạn gợi ý, bạn có thể thực hiện:(random.random() * 0.5) + 0.5

Mã cuối cùng của bạn sẽ trông như sau:

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

Đó là tất cả!


Tôi không rõ làm thế nào để gieo hạt có liên quan đến nó. Số ngẫu nhiên sẽ vẫn là ngẫu nhiên nếu bạn không gieo hạt, nhưng sẽ lặp lại. Triệu chứng duy nhất của việc không gieo hạt phải là cùng một chuỗi ngẫu nhiên mỗi khi bạn chạy chương trình (giả sử cùng một hạt giống được sử dụng mỗi lần).
Tim Holt

1
Nếu bạn nhận được cùng một đầu ra ba lần liên tiếp như được đề cập trong câu hỏi của bạn, thì rất có thể là do bạn chưa chọn trình tạo ngẫu nhiên. Hạt giống nó và xem nếu nó khắc phục vấn đề.
tro999

Ah tôi đã không thấy bit "3 lần liên tiếp" - đang đọc, "Có một số chức năng hạt giống tôi đang thiếu trên thư viện đó để làm cho nó ngẫu nhiên hơn". Có gieo hạt cho sự ngẫu nhiên không lặp lại :)
Tim Holt

8

Điều này không trả lời câu hỏi lập trình cụ thể của bạn, nhưng hãy xem xét rằng việc tạo ra các hồ và sông không phải là về việc đặt ngẫu nhiên các đốm nước và dải nước giữa chúng. Đó là về chiều cao địa hình - về áp thấp (lưu vực) biến thành hồ và nước chảy từ điểm cao đến điểm thấp hơn.

Nếu bạn muốn có một ví dụ tuyệt vời về việc tạo ra các hồ và sông có ý nghĩa, bạn có thể xem bài đăng trên blog này -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html Đó là một tài liệu tham khảo tốt cho loại điều này nếu mục tiêu của bạn là thủy văn thực tế hợp lý.


2

Điều đó rất đơn giản: nếu bạn nhận được cùng một bản đồ ba lần liên tiếp (hoặc nhiều hơn), thì đó là vì bạn đã không chọn ngẫu nhiên hạt giống.

Điều đó có nghĩa là gì?

Máy tính vốn đã có tính xác định (không ngẫu nhiên), vì vậy chúng mô phỏng tính ngẫu nhiên. Nó thực sự lặp lại ngẫu nhiên (đó là lý do tại sao chúng tôi gọi nó là "trình tạo số ngẫu nhiên giả").

Cái này hoạt động ra sao?

Khi bạn tạo một số ngẫu nhiên, bạn có tùy chọn cho nó một "hạt giống". Điều quan trọng là nếu bạn luôn sử dụng cùng một hạt giống, bạn sẽ luôn nhận được cùng một chuỗi các số ngẫu nhiên, theo cùng một thứ tự. Luôn luôn. Điều này có thể tốt hoặc xấu.

Trong trường hợp của bạn, có vẻ như bạn không chọn trình tạo ngẫu nhiên và theo mặc định, bạn đang nhận được cùng một hạt giống - nó có thể sử dụng một số thành phần của ngày / giờ của bạn. Do đó, tôi khuyên bạn nên chọn ngẫu nhiên nó.

Như Gusatavo đã đề cập trong câu trả lời của mình, bạn cần gọi Random.seed () . Các tài liệu nói rằng "nếu X [tham số mặc định] bị bỏ qua hoặc None, thời gian hệ thống hiện tại được sử dụng." Điều này là đủ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.