Phương pháp đơn giản nhất để tạo địa hình trơn tru cho trò chơi 2d là gì?


23

Phương pháp đơn giản nhất để tạo địa hình trơn tru cho trò chơi 2d như "Moon Buggy" hoặc "Tuyến đường 960" là gì?

Tôi đã nhận được câu trả lời tại stackoverflow.com về việc tạo ra một loạt các độ cao ngẫu nhiên và làm mờ chúng sau này. Vâng, nó khá ổn. Nhưng nó sẽ tốt hơn để cho một số điểm, và có được một đường cong mượt mà.

Câu trả lời:


13

Một cách bạn có thể đạt được điều này như sau:

  • Tạo một điểm ở giữa màn hình, với chiều cao ngẫu nhiên; Bây giờ bạn có hai phần, một phần ở mỗi bên của điểm này
  • Đối với mỗi phần, chia thành hai đặt một điểm ở giữa phần này, với chiều cao ngẫu nhiên (nằm trong khoảng giữa hai hàng xóm của nó)
  • Lặp lại n lần.

Điều gì xảy ra là chi tiết trong khung cảnh trở nên tốt hơn với mỗi lần lặp.

Cách bạn xử lý các trường hợp ranh giới tùy thuộc vào bạn: bạn có thể giả sử các điểm tại (0, chiều cao / 2) và (chiều rộng, chiều cao / 2) chẳng hạn.

Hi vọng điêu nay co ich!

EDIT: Đây là một hình ảnh tôi làm để minh họa:

địa hình

Đây là cùng một ý tưởng!


12

Giả sử rằng bạn muốn có một địa hình thực sự trơn tru, tôi khuyên bạn nên lùi lại từ các câu trả lời dựa trên tiếng ồn và hiểu chúng đến từ đâu. Tín hiệu 'nhiễu' về cơ bản là tổng của vô số các sin có biên độ ngẫu nhiên, với biên độ 'trung bình' ở một tần số nhất định được cung cấp bởi một hàm của tần số f . Bạn có thể nhận được hầu hết các định nghĩa 'nhiễu' phổ biến theo cách này. Chẳng hạn, chuyển động Brown có 1 / f ^ 2đáp ứng tần số (nghĩa là biên độ trung bình tại một tần số nhất định tỷ lệ nghịch với bình phương tần số): điều này có nghĩa là các điểm lân cận có một chút tương quan với nhau, vì các thành phần tần số cao của tín hiệu rất nhiều ẩm ướt Ngược lại, nhiễu fractal cổ điển (dịch chuyển trung điểm, nhiễu Perlin, v.v.) có đáp ứng tần số 1 / f ; có nhiều sự khác biệt giữa các điểm gần đó, nhưng vẫn còn một chút tương quan. Đi thêm một bước nữa, nhiễu trắng có đáp ứng tần số không đổi - không có mối tương quan nào giữa các điểm.

Điều này có ích gì cho bạn? Chà, bạn có thể nhận được tín hiệu mượt mà mà vẫn có một chút nhiễu với nó bằng cách chỉ cần tóm gọn một số hình sin nhưng đảm bảo rằng chúng có biên độ thích hợp ở bất kỳ tần số nào. Bạn muốn tần số là 'ngẫu nhiên' để không có hai trong số chúng có bội số chung (nếu không, bạn sẽ có một thành phần định kỳ cho hình dạng tổng thể của các ngọn đồi của bạn), vì vậy tôi đề xuất một cái gì đó giống như quy trình sau (hoàn thành với ví dụ làm việc):

  1. Chọn 4 số (thực) ngẫu nhiên trong phạm vi [1..10] - đây sẽ là các tần số của sóng hình sin của bạn. Tôi 'lắc xí ngầu' tại Random.org và nhận được: f 0 = 1.75, f 1 = 2.96, f 2 = 6.23 và f 3 = 8.07. Không có gì kỳ diệu về số 4 (bạn có thể sử dụng nhiều hơn, nhưng sử dụng ít hơn sẽ bắt đầu làm cho các sóng hình sin rõ ràng hơn) hoặc phạm vi từ 1 đến 10 ở đây (đó chỉ là cách đảm bảo rằng mức cao nhất và thấp nhất của bạn tần số không quá xa nhau). Có thể có ý nghĩa khi chọn một tần số trong phạm vi [1..2] và phần còn lại trong phạm vi [2..10] chỉ để bạn có hình sin 'chiếm ưu thế' đã biết.
  2. Đối với mỗi bốn tần số (hoặc nhiều) tần số f i này , hãy chọn biên độ a i ở đâu đó trong phạm vi giữa -C / f iC / f i cho một số C không đổi . Giá trị bạn chọn ở đây kiểm soát biên độ tổng thể của sóng của bạn - để thuận tiện, tôi đã chọn C = 1. Sau đó, tôi cần các số ngẫu nhiên trong phạm vi [-1 / 1.75 (= -0.571) .. 1 / 1.75 (= 0.571) ] và tương tự trong các phạm vi [-0.338 .. 0.338], [-0.161 .. 0.161] và [-0.124 .. 0.124]. Cán dice bốn lần một lần nữa, tôi có một 0 = -0,143, một 1 = -0,180, một 2 = -0,012, vàa 3 = 0,088. (Lưu ý rằng đây có lẽ không phải là cách tốt nhất để thực hiện bước này - vì giá trị tối đa có thể của hàm là tổng biên độ abs ( a 0 ) + abs ( a 1 ) + abs ( a 2 ) + abs ( một 3 ), nó có thể làm cho ý nghĩa hơn để phân chia mỗi bốn bạn một i giá trị bằng số tiền này khi bạn đã tạo ra chúng, và sau đó nhân với mỗi người bằng C do đó bạn có thể chắc chắn tối đa chính xác chức năng có thể đạt được là C .)
  3. Chọn bốn 'độ lệch' o i , mỗi ô trong phạm vi [0..2π] (0..6.28) - những điểm này sẽ điều chỉnh điểm bắt đầu của sóng để chúng không bắt đầu từ 0. Tôi có o 0 = 1,73, o 1 = 4,98, o 2 = 3,17 và o 3 = 4,63.
  4. 'Vẽ' hàm f (x) = a 0 sin ( f 0 (kx + o 0 ) ) + a 1 sin ( f 0 (kx + o 1 ) ) + a 2 sin ( f 0 (kx + o 0 ) ) + a 3 sin ( f 0 (kx + o 0 ) ) - ở đây k là một hằng số khác, điều khiển 'độ căng' ngang của các chức năng của bạn. Bạn sẽ phải tìm ra cái này là gì cho ứng dụng của riêng bạn; để thuận tiện tôi chỉ chọn k= 1, và do đó, chức năng tổng thể của tôi là f (x) = -0.143 sin (1.75 ( x + 1.73)) - 0.180 sin (2.96 ( x +4.98)) - 0.012 sin (6.23 ( x +3.17)) + 0.088 sin (8,07 ( x +4,63)).

Đây là kết quả của ví dụ chạy của tôi, như được vẽ trong Wolfram Alpha - lưu ý rằng nó sửa kích thước của biểu đồ cho mục đích hiển thị, nhưng bạn nên có nhiều quyền kiểm soát đối với kết quả ngang và dọc của kết quả thông qua các hằng số tôi đã đề cập ở trên :

Hình sin ngẫu nhiên đơn giản


10

Các thuật toán chuyển trung điểm có thể tạo ra địa hình 2d đẹp.

ví dụ địa hình

Có sự khác biệt tinh tế giữa chuyển vị giữa và những gì @tykel đang đề xuất. Thuật toán của Tykel chia nhỏ đường chân trời và chọn một tầm cao mới. Điều này tạo ra địa hình nơi các đỉnh được cách đều nhau. Con người rất giỏi trong việc chọn ra các quy tắc, do đó, địa hình tạo ra sẽ có vẻ như được tạo ra, không phải tự nhiên.

Sức mạnh của Midpoint đến từ việc chọn điểm giữa sau đó dịch chuyển dọc theo mức bình thường của đường thẳng đó. Điều này làm cho các đỉnh thay đổi lên xuống cũng như bên này sang bên kia. Địa hình kết quả là fractal, và con người cảm nhận fractals là tự nhiên.

Sự dịch chuyển chiều cao ngẫu nhiên có thể dẫn đến một địa hình đi xuống nếu bạn ném thêm một vài thông số (chuyển vị ngang, độ dốc tối đa, v.v.). Điều này nhấn mạnh một điểm mạnh khác của MPD; nó rất đơn giản để điều chỉnh. Hai thông số, độ gập và mức độ chi tiết.


7

Bạn có thể sử dụng các hàm nhiễu để tạo độ cao ngẫu nhiên. Đơn giản nhất trong số chúng là nhiễu giá trị, hoạt động chính xác như mô tả của bạn: bạn tạo một số độ cao số nguyên ngẫu nhiên và sau đó nội suy độ cao giữa chúng. Phương pháp nội suy thường được sử dụng là ánh xạ đường cong S khối:

Giả sử bạn có chiều cao h0tại điểm x0và chiều cao h1tại điểm x1. Sau đó, để có được chiều cao tại bất kỳ điểm nào x( x0<=x<=x1), bạn sử dụng

t = (x-x0)/(x1-x0); // map to [0,1] range
t = t*t*(3 - 2*t); // map to cubic S-shaped curve
h = h0+t*h1;

Độ cao thu được theo cách này sẽ trơn tru, ngẫu nhiên, nhưng không thực sự thú vị. Để làm cho địa hình của bạn tốt hơn, bạn có thể sử dụng tiếng ồn fractal . Nó hoạt động như thế này: giả sử bạn đã tạo một hàm h(x)trả về chiều cao tại một tọa độ cho trước (sử dụng phương thức trên). Hàm này có tần số, được xác định bởi tần số của độ cao interger gốc. Để tạo ra một fractal từ nó, bạn kết hợp các chức năng với nhau với một số tần số:

fbm(x)=h(x) + 0.5*h(2*x) + 0.25*h(4*x) + 0.125*h(8*x);

Trong ví dụ này, tôi kết hợp bốn tần số - gốc, gấp đôi, 4 lần và 8 lần ban đầu, với tần số cao hơn cho trọng lượng ít hơn. Về mặt lý thuyết, fractals đi tất cả các con đường đến vô tận, nhưng trong thực tế chỉ cần một vài thuật ngữ. Công fbmthức là viết tắt của chuyển động Brownian phân đoạn - đây là tên của hàm này.

Đây là một kỹ thuật mạnh mẽ. Bạn có thể chơi với hệ số nhân tần số, với trọng số của các tần số khác nhau hoặc thêm một số chức năng để làm méo tiếng ồn. Ví dụ: để có được cảm giác "lột xác" hơn, h(x)có thể thay đổi thành 1-abs(h(x))(giả sử -1<=h(x)<=1)

Tuy nhiên, trong khi tất cả điều này là tốt đẹp, kỹ thuật này có một hạn chế nghiêm trọng. Với cách tiếp cận dựa trên "chiều cao", bạn không bao giờ có thể có địa hình "nhô ra". Và tôi tưởng tượng chúng là một tính năng rất hay có trong một trò chơi giống như "Moon Buggy".

Thêm phần nhô ra đẹp là một nhiệm vụ khó khăn. Một điều mà tôi có thể nghĩ đến - bạn có thể bắt đầu với một "chiều cao" fractal, và "tessellate" nó thành một loạt các đường cong spline hoặc bezier. Sau đó, đường địa hình sẽ được xác định bởi một số "điểm chính". Áp dụng một số jitter cho các điểm chính này - điều này sẽ dẫn đến biến dạng ngẫu nhiên của địa hình, có thể tạo thành một số hình dạng thú vị. Tuy nhiên, tự giao cắt địa hình có thể trở thành một vấn đề với phương pháp này, đặc biệt là với số lượng jitter cao.


4

Có hai phương pháp phổ biến để tạo bản đồ chiều cao địa hình.

Một số câu trả lời được đưa ra ở đây đã dựa trên thuật toán Diamond-vuông, nhưng việc biết tên giúp tìm kiếm thêm thông tin dễ dàng hơn. Tiếng ồn Perlin cũng có những công dụng khác, vì vậy tốt nhất là bạn nên kiểm tra nó.


OP đang nói về phong cảnh 2D, kiểu mario, nhưng đây vẫn là những liên kết tốt.
tenpn

1

Ý tưởng của tôi sẽ là tạo ra một chức năng tiếng ồn được làm mịn. Đầu tiên với một phương thức intNaty (int) trả về một int "ngẫu nhiên", nhưng wich phụ thuộc vào đầu vào. Nếu bạn sử dụng cùng một đầu vào hai lần, kết quả sẽ giống nhau.

Sau đó, sử dụng phương pháp làm mịn để tạo một floatNaty (float) sử dụng hai số nguyên xung quanh đầu vào để xây dựng một giá trị ngẫu nhiên.

Sau đó sử dụng vị trí X làm đầu vào và Y làm đầu ra. Kết quả sẽ là một đường cong được làm mịn nhưng với chiều cao ngẫu nhiên.

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.