日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

游戏中的过程生成——元胞自动机 Celluar Automata 生成洞穴地形

發布時間:2024/1/3 综合教程 50 生活家
生活随笔 收集整理的這篇文章主要介紹了 游戏中的过程生成——元胞自动机 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];
        }
    }
}

總結

以上是生活随笔為你收集整理的游戏中的过程生成——元胞自动机 Celluar Automata 生成洞穴地形的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。