1. 程式人生 > >為2D遊戲生成平滑地形的最簡單的方法是什麼?

為2D遊戲生成平滑地形的最簡單的方法是什麼?

https://gxnotes.com/article/82289.html

問題描述

為”Moon Buggy”或“路線960”的2D遊戲生成平滑地形的最簡單的方法是什麼?

我在stackoverflow.com得到一個答案,生成一個隨機高度的陣列,並在後面模糊。是的,這是非常好的。但是最好給出一些要點,並獲得一個平滑的曲線。

最佳解決方案

一種方法可以實現以下目的:

  • 在螢幕中間建立一個隨機高度的點;你現在有兩個部分,一個在這一點的兩邊

  • 對於每個部分,分為兩部分,在本節中間放置一個點,其兩個鄰居之間的(範圍)隨機高度

  • 重複n次。

發生什麼事情是風景中的細節每次迭代都會變得更細。

如何處理邊界案例取決於你:你可以假設(0,height /2)和(width,height /2)的點。

希望這可以幫助!

編輯:這是我為了說明圖:

algorithm,procedural-generation,terrain

This is the same idea!

次佳解決方案

midpoint displacement algorithm可以生成美麗的2d地形。

algorithm,procedural-generation,terrain

中點位移與@tykel建議之間有微妙的不同。 Tykel的演算法細分了地平線,並選擇了一個新的高度。這產生了峰值均勻間隔的地形。人類在挑選規律方面是非常好的,所以生成的地形似乎是生成的,而不是自然的。

中點的力量來自於選擇中點,然後沿著該線的法線移位。這樣會導致峰值上下變化。所得到的地形是分形的,人類認為分形是自然的。

如果您投入了更多的引數(水平位移,最大坡度等),隨機高度位移可能會導致下降的地形。這突出了MPD的另一個優勢;調好就很簡單兩個引數,顛簸和細節水平。

第三種解決方案

假設你想要一個實際平滑的地形,我建議從noise-based的答案中退出,並瞭解他們來自哪裡。 ‘noise’訊號本質上是無限多個隨機振幅的正弦波的和,其中在給定頻率處的’average’振幅由頻率f的函式給出。您可以通過這種方式獲得大多數常見的’noise’定義。例如,布朗運動具有1 /f^2頻率響應(即,給定頻率處的平均幅度與頻率的平方成反比):這意味著附近的點具有相當的相互位置,因為訊號的high-frequency分量是很大的阻尼。相比之下,經典分形噪聲(中點位移,珀林噪聲等)具有1 /f頻率響應;附近點之間有更多的差異,但仍然有相當多的關聯。進一步,白噪聲具有恆定的頻率響應 – 任何點之間根本無相關性。

這對你有什麼好處?那麼,您可以通過將幾個正弦曲線相加來確定它們在任何給定頻率下都具有適當的幅度,可以得到一個平滑的訊號,仍然有一點嘈雜的感覺。你想要的頻率是’random’,所以沒有兩個它們將有一個共同的倍數(否則你會得到一個週期性的元件到你的山丘的整體形狀),所以我建議像以下過程(完成工作例):

  1. 在[1..10]的範圍內隨機選擇4個(實數) – 這些將是您的正弦波的頻率。我在random.org上滾動了骰子,得到:f0 = 1.75,f1 = 2.96,f2 = 6.23,f3 = 8.07。沒有什麼神奇的數字4(你可以使用更多,但使用更少,將開始使個人正弦波更明顯)或範圍1到10這裡(這只是一種確保你的最高和最低的方式頻率不是太遠)。選擇範圍[1..2]中的一個頻率,其餘的在範圍[2..10]中可能有意義,以便您具有已知的’dominant’正弦曲線。

  2. 對於這四個(或多個)頻率fi中的每一個,在-C /fi和C /fi之間的範圍內為某些常數C選擇幅度ai。您在此處選擇的值控制波的總體幅度 – 為方便起見我選擇了C = 1.然後我需要在[-1 /1.75(= -0.571).. 1 /1.75(= 0.571)]範圍內的隨機數字,類似地在[-0.338 .. 0.338]的範圍內, [-0.161 .. 0.161]和[-0.124 .. 0.124]。再次骰子四次,我得到a0 = -0.143,a1 = -0.180,a2 = -0.012,a3 = 0.088。 (請注意,這可能不是完成此步驟的最佳方式 – 由於函式的最大可能值是幅度abs(a0)+ abs(a1)+ abs(a2)+ abs(a3)的和,生成它們之後,您可以將每個四個ai值分配一次,然後將每個值乘以C,以便您可以確定該功能可以獲得的精確最大值。

  3. 選擇四個’offsets’ oi,每個都在[0..2π](0..6.28)的範圍內 – 這些將調整波的起始點,使它們都不是從0開始。我得到o0 = 1.73,o1 = 4.98,o2 = 3.17,o3 = 4.63。

  4. ‘f繪圖’函式f(x)= a0 sin(f0(kx + o0))+ a1 sin(f0(kx + o1))+ a2sin(f0(kx + o0))+ a3sin(f0(kx + o0)) – 這裡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.088sin(8.07(x + 4.63))。

這是我的示例執行的結果,如在Wolfram Alpha中繪製的那樣,它注意到它將其圖形的大小修正為顯示目的,但是您應該通過上述常數對結果的水平和垂直拉伸進行充分的控制:

algorithm,procedural-generation,terrain

第四種方案

您可以使用噪聲函式來生成隨機高度。其中最簡單的是價值噪聲,其工作原理與您的描述完全相同:您生成一些隨機的整數高度,然後在它們之間插入高度。 most-often使用插值法是立方S-curve對映:

假設在x0點處有高度h0,在x1處有高度h1。然後在任意點獲得高度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),它可以在給定的座標(使用上面的方法)返回高度。該功能具有由初始高度的頻率確定的頻率。為了形成分形,您將多個頻率的功能組合在一起:

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

在這個例子中,我組合了四個頻率 – 原始,雙倍,四倍和八倍的原始頻率,較高的頻率給出較少的重量。理論上,分形態一直到無窮大,但實際上只需要幾個術語。公式中的fbm代表分數布朗運動 – 這是該功能的名稱。

這是一個強大的技術。您可以播放帶有不同頻率權重的倍頻器,或新增一些功能來扭曲噪聲。例如,要獲得更多的”ridged”感覺,h(x)可以更改為1-abs(h(x))(假設-1<=h(x)<=1)

然而,雖然這一切都很好,但這種技術有很大的侷限性。以“高度”為基礎的方法,你永遠不會有地形“懸垂”。而且我想象他們是一個非常好的功能,在一個“月球越野車”般的遊戲。

新增漂亮的懸垂是一項艱鉅的任務。我可以想到的一件事 – 你可以從分形”heightline”開始,並將”tessellate”變成一系列樣條曲線或貝塞爾曲線。那麼地形線將由幾個”key points”定義。對這些關鍵點應用一些抖動 – 這將導致地形的隨機變形,可能形成一些有趣的形狀。然而,地形self-intersections可能會成為這種方法的問題,特別是在抖動量較大的情況下。

第五種方案

有兩種流行的方法來生成地形高度圖。

這裡給出的一些答案已經基於Diamond-square演算法,但是知道這個名字可以更容易地搜尋更多的資訊。佩林的噪音也有其他用途,所以檢查它是很好的。

參考文獻

注:本文內容整合自google/baidu/bing輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:gxnotes#qq.com(#替換為@)。

本文由 《共享筆記》整理, 博文地址: https://gxnotes.com/article/82289.html,未經允許,請勿轉載。