Làm cách nào tôi có thể tạo địa hình theo kiểu Worms?


48

Tôi đang làm việc trên một trò chơi theo kiểu Worms và muốn tạo ra một số địa hình theo thủ tục. Trước đây tôi đã thực hiện rất nhiều việc tạo địa hình bằng tiếng ồn perlin và đây là những gì tôi bắt đầu sử dụng cho trò chơi này. Vấn đề duy nhất với nó là nó quá đơn giản và nhàm chán, mang lại cho tôi một số ngọn đồi nhưng không phải là sự phức tạp mà tôi muốn. Tôi muốn có các tính năng như hang động và núi treo và tôi không bận tâm đến những hòn đảo nổi. Một cái gì đó như thế này, nhưng thậm chí crazier sẽ ổn:

nhập mô tả hình ảnh ở đây

Tôi đã nghĩ đến việc đầu tiên tạo ra địa hình bằng cách sử dụng tiếng ồn perlin cổ điển, sau đó chỉ cần loại bỏ các phần để tạo ra các hang động và những gì không, nhưng tôi gặp khó khăn trong việc hướng dẫn loại bỏ các phần đó. Có sự thay thế nào để tạo ra một địa hình như vậy không?


Liệu màu đỏ đại diện cho hang động hay đó chỉ là một phần của địa hình?
Richard Marskell - Drackir

Đó là một phần của địa hình. Tôi chỉ Google hình ảnh đó, là gần nhất với những gì tôi muốn thực hiện. Phần "hang động" có thể là cái lỗ nhỏ ở bên phải, nếu nó được tiếp tục nhiều hơn bên trong địa hình bên trái.
Xeon06

@Drackir, chỉnh sửa hình ảnh.
Xeon06

Liên quan: gamedev.stackexchange.com/questions/6721/ trên (nhưng không phải là một bản sao vì nó dường như tập trung vào việc thực hiện so với các thuật toán tạo).
Josh

@JoshPetrie thực sự. Tôi tốt với sự hủy diệt. Đó là thế hệ tôi gặp rắc rối.
Xeon06

Câu trả lời:


51

Tôi khuyên bạn nên bắt đầu với 2D Perlin-noise. Một cái gì đó như thế này:

tiếng ồn perlin

Sau đó áp dụng một ngưỡng trên hình ảnh, để bạn có được một số đảo bị cô lập, như được hiển thị ở đây:

tiếng ồn perlin với ngưỡng

Tôi đã chọn ngưỡng 0,04, mọi thứ trên ngưỡng sẽ có màu xanh lam. Phần còn lại màu đen. Sau đó, đã đến lúc xác định "hòn đảo" nào nên giữ và hòn đảo nào cần vứt bỏ.

Một cách tiếp cận khả thi sẽ là chạy qua hình ảnh từ trái sang phải ở nhiều độ cao khác nhau và chọn các "đảo" giao nhau với một xác suất nhất định. Trong hình ảnh ví dụ, dòng thấp nhất có xác suất 100%, vì vậy mọi đảo mà nó đi qua sẽ được chọn (điền màu trắng). Dòng thứ hai có xác suất 50% và dòng trên cùng có xác suất 10%.

Khi bạn đã đánh dấu các đảo của mình như thế, bạn có thể đóng các khoảng trống ở giữa bằng cách áp dụng một hoạt động hình thái ( giãn )

đảo bị giãn

Và có một cảnh quan có thể.

"Độ chi tiết" của tiếng ồn sẽ xác định mức độ nhỏ của các chi tiết trong thế giới của bạn. Vì vậy, có lẽ tốt nhất để thử nghiệm với các giá trị này.

Ngoài ra, ở đâu và với xác suất "đường chọn" của bạn được định vị, kết quả sẽ khác nhau rất nhiều. Nếu bạn có một đường gần đỉnh của hình ảnh với xác suất cao để "chọn" một hòn đảo, thì bạn có thể xây dựng một số loại cảnh quan hang động, v.v.


Cảm ơn rất nhiều cho câu trả lời chi tiết và minh họa tuyệt vời! Đây chính xác là những gì tôi sẽ làm.
Xeon06

Bạn có bất cứ lời khuyên nào về việc tạo ra tiếng ồn perlin như vậy không, với mức độ chi tiết này và như vậy? Tôi đã cố gắng cả buổi tối và không đi đến đâu.
Xeon06

@ Xeon06 Tôi chỉ sử dụng chức năng nhiễu Perlin được cung cấp bởi flash . Các tham số là 24cho baseXbaseY, 1 quãng tám và tôi đã chọn phát ra tiếng ồn thang độ xám và "fractal" bị vô hiệu hóa. Ngôn ngữ nào bạn đang thực hiện điều này trong?
bummzack

Tôi đang triển khai JavaScript. Tôi đã lướt web để triển khai tốt sẽ cho kết quả tương tự trong một tuần nhưng không tìm thấy gì.
Xeon06

Tôi đã đặt một câu hỏi khác liên quan đến phần tiếng ồn perlin gamedev.stackexchange.com/questions/20880/fast-noise-generation
Xeon06

6

Tôi sẽ bắt đầu với tiếng ồn perlin, được lọc cẩn thận. Bạn sẽ kết thúc với một cái gì đó giống như trong hình kèm theo câu hỏi, với những hòn đảo nổi. Juste loại bỏ các đảo nổi sau đó bằng thuật toán đếm giống như các thuật toán được thảo luận ở đây


Oh tôi nghĩ rằng tôi nhận được nó ngay bây giờ. Tôi cần sử dụng tiếng ồn perlin 2D, không phải 1D. Bạn có thể giải thích về lọc nói?
Xeon06

2
Tôi không thể đăng ảnh ngay bây giờ, nhưng tôi chỉ nói về một bộ lọc ngưỡng đơn giản nếu (0,3> pixelValue> 0,5) KeepIt ();. Bit 'cẩn thận' là về việc lấy đúng 0,3 và 0,5. Bạn cũng có thể có một gradient tuyến tính (hoặc không), bắt đầu với alpha cao ở phía trên, dần dần về 0 ở phía dưới, vì vậy bạn có chỗ cho một bầu trời và mặt đất chủ yếu được lấp đầy. Mong rằng sẽ giúp.
Ravachol

@Ravachol Nếu bạn đăng một liên kết đến một bức ảnh, ai đó có nhiều đại diện hơn có thể thêm nó vào bài đăng của bạn cho bạn.
Richard Marskell - Drackir

"Nếu (0,3> pixelValue> 0,5)", tôi đoán đây chỉ là một lỗi đánh máy, nhưng có thể gây nhầm lẫn khi có những điều mâu thuẫn trong bài đăng của bạn ... Bạn có thể chỉnh sửa nó không?
jcora

Tôi dường như không thể chỉnh sửa một bình luận. Đọc "nếu (0,3 <pixelValue <0,5)", rõ ràng.
Ravachol

4

Tôi thực sự thực hiện điều này bắt đầu từ câu trả lời xuất sắc của bummzack.

Đây là các bước tôi đã kết thúc với:

  1. Tạo hình ảnh với nhiễu Perlin
  2. Lũ lụt nơi bạn muốn một số địa hình
  3. Sự giãn nở + xói mòn để loại bỏ các lỗ rỗng quá nhỏ
  4. Xóa các vùng nền còn lại bên trong địa hình
  5. Khử răng cưa

Và đây là một ví dụ về kết quả: ví dụ về địa hình được tạo

Tôi đã viết một bài viết chi tiết về toàn bộ quá trình ở đây và mã (JavaScript) là nguồn mở, hãy kiểm tra nếu bạn muốn một cái gì đó sẵn sàng để sử dụng;)

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.