2D 게임에서 부드러운 지형을 생성하는 가장 간단한 방법은 무엇입니까?


23

"Moon Buggy"또는 "Route 960"과 같은 2D 게임에서 부드러운 지형을 생성하는 가장 간단한 방법은 무엇입니까?

stackoverflow.com에서 임의의 높이 배열을 생성하고 나중에 흐리게 처리하는 방법에 대한 답변을 받았습니다. 예, 괜찮습니다. 그러나 일부 점을 제공하고 매끄러운 곡선을 얻는 것이 좋습니다.

답변:


13

이를 달성 할 수있는 한 가지 방법은 다음과 같습니다.

  • 화면 가운데에 임의의 높이로 점을 만듭니다. 이제이 지점의 양쪽에 하나씩 두 개의 섹션이 있습니다.
  • 모든 섹션에 대해이 섹션의 중앙에 두 개의 지점을 두 개의 이웃 사이에 (범위) 임의의 높이로 배치하십시오.
  • n 번 반복하십시오.

각 반복마다 풍경의 디테일이 더 세밀 해집니다.

경계 사례를 처리하는 방법은 전적으로 사용자에게 달려 있습니다. 예를 들어 (0, height / 2) 및 (width, height / 2)를 가리킬 수 있습니다.

이것이 도움이되기를 바랍니다!

편집 : 여기 그림을 위해 만든 그림이 있습니다.

지형

이것은 같은 생각입니다!


12

실제로 부드러운 지형을 원한다고 가정하면 소음 기반 답변에서 물러나서 어디에서 왔는지 이해하는 것이 좋습니다. '잡음'신호는 본질적으로 임의의 진폭의 무한히 많은 정현파의 합이며, 주파수 f 의 함수에 의해 주어진 주어진 주파수에서 '평균'진폭을 갖습니다 . 이 방법으로 일반적인 '소음'정의를 대부분 얻을 수 있습니다. 예를 들어, 브라운 운동은 1 / f ^ 2주파수 응답 (즉, 주어진 주파수에서의 평균 진폭은 주파수의 제곱에 반비례합니다) : 이것은 신호의 고주파 성분이 무겁기 때문에 근처의 지점이 서로 상당한 상관 관계를 가지고 있음을 의미합니다. 감쇠. 대조적으로, 클래식 프랙탈 노이즈 (미드 포인트 변위, Perlin 노이즈 등)는 1 / f 주파수 응답을 갖습니다 . 근처 점들 사이에는 더 많은 차이가 있지만 여전히 약간의 상관 관계가 있습니다. 한 걸음 더 나아가서 백색 잡음은 일정한 주파수 응답을 갖습니다.

이게 무슨 소용입니까? 글쎄, 당신은 단지 몇 개의 정현파를 합하여 주어진 주파수에서 적절한 진폭을 갖도록함으로써 여전히 약간의 시끄러운 신호를 얻을 수 있습니다. 주파수가 '무작위'가되기를 원하므로 두 개가 공통 배수를 갖지 않아야합니다 (그렇지 않으면 언덕의 전체 모양에주기적인 구성 요소를 얻음). 다음 절차와 같은 것을 제안합니다 작업 예와 함께) :

  1. [1..10] 범위에서 무작위로 4 개의 실수를 선택하십시오. 이는 사인파의 주파수입니다. 나는 random.org에서 주사위를 굴렸다 .f 0 = 1.75, f 1 = 2.96, f 2 = 6.23, f 3 = 8.07. 숫자 4 (더 많이 사용할 수는 있지만 더 적은 수를 사용하면 개별 사인파를보다 분명하게 만들기 시작합니다) 또는 여기에서 1 ~ 10의 범위에 마법이 없습니다. 주파수가 너무 멀지 않습니다 ). 알려진 '주요한'정현파를 갖도록 [1..2] 범위의 주파수와 [2..10] 범위의 나머지 주파수를 선택하는 것이 좋습니다.
  2. 이러한 네 개의 (또는 다수의 단) 주파수의 각각에 대해 F , 진폭 선택 I 사이의 범위의 어딘가 / F-C를 IF C / I 일부 상수에 대한 C . 여기서 선택한 값은 편의상 웨이브의 전체 진폭을 제어합니다. 편의상 C = 1을 선택했습니다 . 그런 다음 [-1 / 1.75 (= -0.571) .. 1 / 1.75 (= 0.571) 범위의 난수가 필요했습니다. ], [-0.338..0.338], [-0.161..0.161] 및 [-0.124..0.124] 범위에서 유사하게 적용됩니다. 네 번 다시 주사위 롤링, 내가 가지고 0 = -0.143, 1 = -0.180, 2 = -0.012, 그리고a 3 = 0.088입니다. (이것은 아마도이 단계를 수행하는 가장 좋은 방법은 아닙니다. 함수의 최대 가능한 값은 진폭의 합입니다 abs ( a 0 ) + abs ( a 1 ) + abs ( a 2 ) + abs ( 3 ), 당신의 네 개의 각 분할하는 더 이해 할 수 나는 당신이 그 (것)들을 생성 한 후이 합으로 값을 다음 곱에 의해 각각 C는 그래서 당신은 달성 할 수있는 기능이 있는지 정확한 최대 수 있다는 C .)
  3. 네 '오프셋'선택 O를 범위에서, 각각 [0..2π] (0..6.28) -이들은 모두 내가 가진 0에서 시작하지 않도록 웨이브의 시작 지점을 조정할 것 O를 0 = 1.73, o 1 = 4.98, o 2 = 3.17 및 o 3 = 4.63입니다.
  4. '함수'함수 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 ) )-여기서 k 는 함수의 수평 '스트레칭'을 제어하는 ​​또 다른 상수입니다. 자신의 응용 프로그램이 무엇인지 파악해야합니다. 편의상 나는 방금 k를 골랐다.= 1이므로 전체 함수는 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)).

다음은 Wolfram Alpha에 표시된 내 예제 실행의 결과입니다. 표시 목적으로 그래프 크기를 수정하지만 위에서 언급 한 상수를 통해 결과의 가로 및 세로 스트레치를 충분히 제어 할 수 있어야합니다. :

단순 무작위 정현파


10

중간 점 변위 알고리즘은 아름다운 2D 지형을 생성 할 수 있습니다.

지형 예

중간 점 변위와 @tykel이 제안하는 것 사이에는 미묘한 차이가 있습니다. Tykel의 알고리즘은 수평선을 세분화하고 새로운 높이를 선택합니다. 이렇게하면 피크가 균일하게 이격 된 지형이 만들어집니다. 인간은 규칙 성을 고르는 데 능숙하므로 생성 지형이 자연스럽지 않고 생성 된 것처럼 보입니다.

중간 점의 힘은 중간 점을 선택한 다음 해당 선의 법선 을 따라 변위 하는 데 있습니다. 이것은 피크가 좌우로 변할뿐만 아니라 좌우로 변하게한다. 결과 지형은 프랙탈이며 인간은 프랙탈을 자연적인 것으로 인식합니다.

임의의 높이 변위로 인해 몇 가지 매개 변수 (수평 변위, 최대 경사 등)를 던지면 지형이 하강 할 수 있습니다. 이것은 또 다른 MPD 강점을 강조합니다. 튜닝이 매우 간단합니다. 두 가지 매개 변수, 울퉁불퉁 함 및 세부 수준.


7

노이즈 기능을 사용하여 임의의 높이를 생성 할 수 있습니다 . 가장 간단한 방법은 값 노이즈입니다. 이는 설명과 정확히 동일합니다. 임의의 정수 높이를 생성 한 다음 그 사이의 높이 를 보간 합니다. 가장 많이 사용되는 보간법은 3 차 S- 곡선 매핑입니다.

당신은 높이가 가정 h0점에서 x0높이 h1지점에서 x1. 그런 다음 어느 지점에서나 높이를 얻으려면 x( x0<=x<=x1)

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;

이 방법으로 얻은 높이는 매끄럽고 임의적이지만 실제로는 흥미롭지 않습니다. 지형을 개선하기 위해 프랙탈 노이즈를 사용할 수 있습니다 . 그것은 다음과 같이 작동합니다 : h(x)주어진 좌표에서 위의 방법을 사용하여 높이를 반환 하는 함수 를 생성했다고 가정하십시오 . 이 기능은 원래 interger 높이의 주파수에 의해 결정되는 주파수를가집니다. 프랙탈을 만들려면 함수를 여러 주파수와 결합하십시오.

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

이 예에서는 원래, 두 배, 4 배 및 8 배 원본의 4 가지 주파수와 적은 무게로 더 높은 주파수를 결합합니다. 이론적으로 프랙탈은 무한대로 진행되지만 실제로는 몇 가지 용어 만 필요합니다. fbm식 분수 브라운 운동을 나타내며, -는이 함수의 이름이다.

이것은 강력한 기술입니다. 주파수가 다른 주파수 멀티 플라이어로 재생하거나 노이즈를 왜곡하는 기능을 추가 할 수 있습니다. 예를 들어, 더 "거친"느낌을 얻기 h(x)위해 1-abs(h(x))(가정 -1<=h(x)<=1) 으로 변경할 수 있습니다

그러나이 모든 것이 훌륭하지만이 기술에는 심각한 한계가 있습니다. "Hightline"기반 접근 방식을 사용하면 지형 "오버행"을 가질 수 없습니다. 그리고 나는 그들이 "Moon Buggy"와 같은 게임에서 가질 수있는 아주 멋진 기능이라고 생각합니다.

좋은 돌출부를 추가하는 것은 어려운 작업입니다. 내가 생각할 수있는 한 가지는 프랙탈 "높이 선"으로 시작하여 일련의 스플라인 또는 베 지어 곡선으로 "테셀 레이트"할 수 있습니다. 그런 다음 지형선은 여러 "핵심 포인트"에 의해 정의됩니다. 이 핵심 포인트에 약간의 지터를 적용하면 지형이 임의로 변형되어 흥미로운 모양이 형성 될 수 있습니다. 그러나 지형 자체 교차로는이 접근 방식, 특히 지터 양이 많은 경우 문제가 될 수 있습니다.


4

지형 높이 맵을 생성하는 데 널리 사용되는 두 가지 방법이 있습니다.

여기에 주어진 일부 답변은 이미 Diamond-square 알고리즘을 기반으로하지만 이름을 알면 더 많은 정보를 쉽게 검색 할 수 있습니다. Perlin 노이즈는 다른 용도도 있으므로 어쨌든 확인하는 것이 좋습니다.


OP는 2D, 마리오 스타일의 풍경에 대해 이야기하고 있지만 여전히 좋은 링크입니다.
tenpn

1

내 생각은 부드러운 노이즈 기능을 만드는 것입니다. 먼저 "random"int를 반환하는 intNoise (int) 메소드를 사용하지만 입력에 따라 다릅니다. 동일한 입력을 두 번 사용하면 결과는 동일합니다.

그런 다음 평활화 방법을 사용하여 입력 주위의 두 정수를 사용하여 임의의 값을 만드는 floatNoise (float)를 만듭니다.

그런 다음 X 위치를 입력으로 사용하고 Y를 출력으로 사용하십시오. 결과는 부드럽게 곡선이지만 임의의 높이를 갖습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.