游戲中的過程生成——元胞自動機 Celluar Automata 生成洞穴地形


最近在學習過程生成技術,在這里寫一些心得。

對於元胞自動機,我們這里只討論輸入是一副二維bool數組的情況,即大多數游戲中的情況。

一個元胞自動機,對於一個輸入,給出一個同樣格式的輸出。輸出中的每個點都是按照自動機中的規則從輸入中演化而來的。大部分情況下,一個輸出上的點,是根據輸入中該點周圍的點的狀態來決定輸出中的狀態。

我們輸入一個二維bool數組,並且規定它的演化規則為,某個點周圍的true較多,就演化為true,否則演化為false。這種規則下,我們輸入一個隨機生成的噪點圖,經過一定次數的演化,就可以獲得相當自然的“洞穴”地圖。

根據噪點圖中噪點的數量,最終生成的洞穴被填充的面積也不同。

unity官方給出了一個用元胞自動機隨機生成洞穴地形的教程 https://unity3d.com/cn/learn/tutorials/projects/procedural-cave-generation-tutorial

其中的元胞自動機生成的部分代碼有一點錯誤,它並沒有把輸入的數組進行備份,直接對每個點進行遍歷,因此每個點取到的之前一行的點都是新生成的點。

不過負負得正的是因此生成了看起來更像洞穴的結果。事實上如果按照它的規則,寫一個周圍有4個true,則下一次變為true,否則變為false的自動機的話,最終的圖像會出現非常明顯的鋸齒抖動。如下圖。


上圖中的鋸齒不管進行幾次迭代都會一直存在

我做出的修正是當周圍的格子為true時剛好有4個時,則自身保持不變。最終獲得了看起來像是洞穴的效果。

類似這樣的小調整可以做很多,比如邊界上的點的處理等。通過不斷調整可以獲得各種不同效果。

貼一下代碼

using UnityEngine;
using System.Collections;
namespace CS.MapGeneration {
    public class CelluarAutomata {
        private static int[,] offset = {
            { -1, -1 }, { -1, 0 }, { -1, 1 },
            {0,-1 },    {0,1 },
            {1,-1 }, {1,0 }, {1,1 }
        };
        private static int GetNeighbourCount(bool[,] map,int x,int y) {
            int res = 0;
            for (int i = 0; i < offset.GetLength(0); i++) {
                int nx = x + offset[i, 0];
                int ny = y + offset[i, 1];
                if (nx<=0 || ny <=0 || nx>=map.GetLength(0) || ny >= map.GetLength(1) ||map[nx,ny])
                    res++;
            }
            return res;
        }
        
        public void Iterate(bool[,] map) {
            bool[,] copy = map.Clone() as bool[,];
            for(int i = 0; i < copy.GetLength(0); i++) {
                for(int j = 0; j < copy.GetLength(1); j++) {
                    map[i, j] = Rule(copy, i, j);
                }
            }
        }

        protected static bool Rule(bool[,] map, int x,int y) {
            if (!map[x, y] && GetNeighbourCount(map, x, y) > 4)
                return true;
            else if (map[x, y] && GetNeighbourCount(map, x, y) < 4)
                return false;
            return map[x, y];
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM