① [沙盒游戲][演算法] 隨機地圖生成項目、一 柏林雜訊的生成演算法邏輯詳細分析(Ken Perlin 源碼)
沙盒游戲的魅力在於其無限的隨機性和自由度,比如《我的世界》和《飢荒》等經典作品。作為開發者,對游戲中的隨機性背後實現方式的好奇心驅使我們深入探究。作者計劃通過Unity構建一個能生成類似《我的世界》地圖的隨機地圖生成器,盡管更新可能因工作忙碌而較慢,但他歡迎同好們提出意見和建議。
這個系列的起點是作者的游戲啟蒙——泰拉瑞亞,盡管它歷經變遷,但柏林雜訊生成演算法成為了構建隨機地圖的關鍵。柏林雜訊,實際上是通過梯度和線性插值,將隨機數平滑連接,產生看起來自然的隨機效果,通常使用Ken Perlin的函數實現。
柏林雜訊的創造者Ken Perlin,一個在迪士尼電影《電子世界爭霸戰》中為特效開發出這種演算法的傳奇人物,其發明過程雖非傳統科研團隊的常規路徑,卻展現了個人的創造力。Ken Perlin於1982年就發明了柏林雜訊,那時他還是哈佛大學的數學系本科生,這一成就令人驚嘆。
詳細講解柏林雜訊的生成邏輯,首先從網格劃分開始,每個整數坐標點都有對應的隨機梯度向量。這些梯度通過與距離向量的內積,通過線性插值確定點的最終值。雖然主流的插值函數是Ken Perlin建議的,但其他滿足特定條件的函數也可用。他的源碼基於java,雖然主要用於紋理生成,但對地圖生成有一定啟示。
總結柏林雜訊的步驟:首先初始化網格,然後為每個整數點分配隨機梯度,通過內積計算插值值。關鍵在於均勻的梯度選擇,避免整體偏置,以提高隨機性和效率。
在深入分析源碼時,作者發現一些鮮為人知的問題,如梯度表的選擇策略,以及固定梯度帶來的隨機性問題。此外,晶格頂點的特殊性也影響了地圖生成的多樣性和初始設置。雖然文章暫未深入可視化,但作者計劃在後續內容中探討這些話題。
② 三套簡單的迷宮地圖生成方案
文章基於一種基礎的地圖,來討論三套不同的迷宮地圖生成方案。不涉及代碼,採用通俗語句和示意圖說明生成方式,方案來源於游戲界前輩,根據自己的基礎地圖做了修正以適應不同游戲需要。生成後的地圖可進一步豐富靜態分布,增強地圖表現。文章展示地圖面積較小,便於表達迷宮生成規則,實際游戲製作時,按需擴展。
地圖形式多樣,使用tile塊分割,主要分為三類:陸地、過渡、水域。其中水域作為分割元素,圍繞陸地設計迷宮,過渡地塊根據游戲需求生成。若不使用水域,可替換為傳統牆壁。
方案一:主路扭曲型
1. 首先生成基礎地圖,用1表示陸地,0表示水域。
2. 選擇靠近邊緣的1作為起點,隨機找另一個黃色1(上下左右方向)聯通,將相鄰0變為陸地。
3. 從新格子開始重復步驟2,直至找不到黃色1。
4. 按原路返回,找到有黃色1的格子開始循環,直至生成完整迷宮。
5. 迷宮生成後,添加終點完成。
此方案生成迷宮有一條貫穿大部分區域的扭曲主路。
方案二:自然分岔型
1. 生成基礎地圖,用1表示黃色1,0表示灰色0。
2. 隨機選擇邊緣黃色1變為紅色1(陸地),周圍灰色0標記為藍色0。
3. 隨機選擇藍色0,檢查對面紅色1,若對面為黃色1,則將對面黃色1變為紅色1,藍色0變為紅色0,更新周圍灰色0為藍色0。
4. 重復步驟3,直到地圖無藍色0。
此方案生成迷宮分岔路多,相對自然,但可能比前兩種更復雜。
方案三:塊狀分割型
1. 在大地圖上生成若干小型地塊(奇數邊長,不重合),用橙色1表示。
2. 依據方案一,在非地塊區域生成迷宮,使迷宮與地塊分開。
3. 隨機連接地塊周圍黃色1,數量根據需求調整。
4. 簡化地圖,去掉3邊為灰色0的黃色1,減少死胡同。
5. 添加入口和出口完成地圖。
此方案增加小型地塊,適合設計玩家反饋,分岔路減少,選擇次數降低,便於控制地圖結構。
所有方案在生成後,地圖面積較小,適用於表達迷宮規則,實際游戲製作時需按需擴展。迷宮生成後,可進一步豐富靜態分布,增強地圖表現。方案選擇基於游戲需求,不同方案生成的迷宮特徵各異,適用於不同游戲場景。
參考資源包括隨機prim演算法的多種分析與實現,以及基於小型地塊的迷宮生成思路。迷宮生成網頁提供直觀的生成工具,允許設定迷宮大小和形狀規則。
③ 波函數坍縮 地圖生成-演算法過程可視化(2D)
波函數坍縮(Wave Function Collapse)生成 ,是一個隨機程序化的生成演算法,比較經典的是用在游戲場景的地圖生成。想要了解詳細的解讀可以參考 《波函數坍縮演算法》的無限城市... ,當前文章是WFC 2D版本的實現。
點擊 查看可視化樣例
這有一個可視化的程序,它可以 逐步、暫停 、回放 整個計算過程 ,以便於你理解 wfc 演算法。
每個都對應地圖上的一個確定坐標位置,初始狀態,每個Slot 都包含成為任何一種圖案(Model)可能性,這種可能性用"熵"來表示,經過坍縮最終成為一個確定的圖案。
這里指的是信息熵,當值越大時,圖案的可能性就越多,演示程序為了方便將展示"熵"值進行了單位化(范圍 0-1)。
具體的圖案,包含有:圖片資源、旋轉角度、權重值(概率)、四條邊信息。
每條邊都有connectId ,用於判斷兩條邊是否能夠相互連接。
波函數坍縮演算法 2D 版本的實現。
github 鏈接 : https://github.com/anseyuyin/wfc2D
語言環境: typescript 、 javascript
項目包含了