मैं Minecraft जैसे इंजन के लिए फ्लोटिंग लैंड मास कैसे उत्पन्न कर सकता हूं?


19

मैं XNA में एक Minecraft जैसा इंजन बना रहा हूं। मैं जो करना चाहता हूं वह इस वीडियो में दिखाए गए के समान फ्लोटिंग आइलैंड्स बनाना है:

http://www.youtube.com/watch?v=gqHVOEPQK5g&feature=related

मैं विश्व जनरेटर का उपयोग करके इसे कैसे दोहराऊंगा? क्या मुझे कुछ पेरलिन शोर एल्गोरिथ्म का उपयोग करना होगा? मैं नहीं जानता कि यह कैसे मुझे इस तरह से भूमि जनता बनाने में मदद करेगा।

यहाँ पेर्लिन शोर जनरेटर के लिए कोड है जो मैं उपयोग कर रहा हूं:

    private double[,] noiseValues;
    private float amplitude = 1;    // Max amplitude of the function
    private int frequency = 1;      // Frequency of the function

    /// <summary>
    /// Constructor
    /// </summary>
    /// 
    public PerlinNoise(int freq, float _amp)
    {
        Random rand = new Random(System.Environment.TickCount);
        noiseValues = new double[freq, freq];
        amplitude = _amp;
        frequency = freq;

        // Generate our noise values
        for (int i = 0; i < freq; i++)
        {
            for (int k = 0; k < freq; k++)
            {
                noiseValues[i, k] = rand.NextDouble();
            }
        }
    }

    /// <summary>
    /// Get the interpolated point from the noise graph using cosine interpolation
    /// </summary>
    /// <returns></returns>
    public double getInterpolatedPoint(int _xa, int _xb, int _ya, int _yb, double x, double y)
    {
        double i1 = interpolate(
            noiseValues[_xa % Frequency, _ya % frequency],
            noiseValues[_xb % Frequency, _ya % frequency]
            , x);

        double i2 = interpolate(
            noiseValues[_xa % Frequency, _yb % frequency],
            noiseValues[_xb % Frequency, _yb % frequency]
            , x);

        return interpolate(i1, i2, y);
    }

    public static double[,] SumNoiseFunctions(int width, int height, List<PerlinNoise> noiseFunctions)
    {
        double[,] summedValues = new double[width, height];

        // Sum each of the noise functions
        for (int i = 0; i < noiseFunctions.Count; i++)
        {
            double x_step = (float)width / (float)noiseFunctions[i].Frequency;
            double y_step = (float)height / (float)noiseFunctions[i].Frequency;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    int a = (int)(x / x_step);
                    int b = a + 1;
                    int c = (int)(y / y_step);
                    int d = c + 1;

                    double intpl_val = noiseFunctions[i].getInterpolatedPoint(a, b, c, d, (x / x_step) - a, (y / y_step) - c);
                    summedValues[x, y] += intpl_val * noiseFunctions[i].Amplitude;
                }
            }
        }
        return summedValues;
    }

    /// <summary>
    /// Get the interpolated point from the noise graph using cosine interpolation
    /// </summary>
    /// <returns></returns>
    private double interpolate(double a, double b, double x)
    {
        double ft = x * Math.PI;
        double f = (1 - Math.Cos(ft)) * .5;

        // Returns a Y value between 0 and 1
        return a * (1 - f) + b * f;
    }

    public float Amplitude { get { return amplitude; } }
    public int Frequency { get { return frequency; } }

लेकिन बात यह है कि कोड का लेखक शोर उत्पन्न करने के लिए निम्नलिखित का उपयोग करता है, और मैं इसे कम से कम नहीं समझता हूं।

    private Block[, ,] GenerateLandmass()
    {
        Block[, ,] blocks = new Block[300, 400, 300];

        List<PerlinNoise> perlins = new List<PerlinNoise>();
        perlins.Add(new PerlinNoise(36, 29));
        perlins.Add(new PerlinNoise(4, 33));

        double[,] noisemap = PerlinNoise.SumNoiseFunctions(300, 300, perlins); 

        int centrey = 400 / 2;

        for (short x = 0; x < blocks.GetLength(0); x++)
        {
            for (short y = 0; y < blocks.GetLength(1); y++)
            {
                for (short z = 0; z < blocks.GetLength(2); z++)
                {
                    blocks[x, y, z] = new Block(BlockType.none);
                }
            }
        }

        for (short x = 0; x < blocks.GetLength(0); x++)
        {
            for (short z = 0; z < blocks.GetLength(2); z++)
            {
                blocks[x, centrey - (int)noisemap[x, z], z].BlockType = BlockType.stone; 
            }
        }

        //blocks = GrowLandmass(blocks);

        return blocks;
    }

और यहां वह साइट है जिसका मैं उपयोग कर रहा हूं: http://lotsacode.wordpress.com/2010/02/24/perlin-noise-in-c/

और मैं मार्टिन सोज्का द्वारा निर्दिष्ट तरीके से पेर्लिन शोर को लागू करने की कोशिश कर रहा हूं।

ठीक है, तो यह वही है जो मुझे अब तक मिला है:

यहाँ छवि विवरण दर्ज करें

जवाबों:


21

आधार भूमि के लिए, दो 2D निरंतर शोर क्षेत्र (पेरलिन, सिम्प्लेक्स, वेवलेट, इसके संयोजन - जो भी आपके लिए काम करता है) बनाएं, एक ज्यादातर कम आवृत्ति के साथ। भूमि की ऊपरी सीमा के लिए कम आयाम वाले हिस्से, उच्च आवृत्ति वाले उच्च आयाम वाले भागों और कम आवृत्ति, भूमि की निचली सीमा के लिए उच्च आयाम वाले अन्य। जहां निचली सीमा उच्च सीमा से ऊपर है, वहां किसी भी भूमि के स्वर को शामिल न करें (या जो भी आपका खेल इलाके का प्रतिनिधित्व करने के लिए उपयोग किया जाएगा)। अंतिम परिणाम लगभग इस तरह दिखता है ...


लेकिन यह 2 डी के लिए है क्या यह नहीं है?
डेरेस्टियम

लेकिन मुझे यह काफी पसंद है :)
डेरेस्टियम

4
2 डी / 3 डी - एक ही बात
गेविन विलियम्स

ठीक है, बीमार करने के लिए इसे लागू करने का प्रयास ... मुझे शुभकामनाएँ;)
डेरेस्टियम

@ डारेस्टियम: यह आसान दृश्य के लिए एक 2 डी उदाहरण है। एक ही विधि एक से अधिक संख्या (बीजगणितीय) आयामों के लिए काम करती है।
मार्टिन सोजका

15

क्या ऐसा कुछ पर्याप्त होगा?

यहाँ छवि विवरण दर्ज करें

यदि हां, तो इस लेख को देखें । सबसे प्रासंगिक भागों का हवाला देते हुए:

अधिक रोचक शोर प्राप्त करने के लिए सिम्पलेक्स शोर के कई सप्तक एक साथ जोड़े जा सकते हैं। [...] चूंकि मैं एक तरह की लगभग गोलाकार तैरती हुई चट्टान प्राप्त करना चाहता हूं, मुझे केंद्र से इसकी दूरी के साथ शोर को गुणा करना होगा। [...] मैं यह भी चाहता हूं कि चट्टान नीचे से ऊपर की तरफ चपटी हो, इसलिए दूसरा गुणन कारक y दिशा में एक ढाल है। एक्स और जेड बिट को संपीड़ित करते समय शोर के लिए इन्हें एक साथ जोड़कर और खींचकर, हमें एक तैरती चट्टान की तरह कुछ मिलता है। [...] शोर के एक और उदाहरण के साथ गुफाओं का उत्खनन थोड़ा भी इसे और अधिक रोचक बनाता है।

  • तो मूल रूप से आप सिम्प्लेक्स या पर्लिन शोर से उत्पन्न डेटा सेट के साथ शुरू करेंगे (या एक साथ जोड़े गए शोर के कई सप्तक )।
  • फिर इसे और अधिक गोलाकार बनाकर ( इसे केंद्र से दूरी से शोर को गुणा करके) एक अस्थायी लैंडमास के करीब आकार दें ।
  • और इसे बनाकर ज़मीन तैयार करें शीर्ष के पास चापलूसी (इसे एक ऊर्ध्वाधर ढाल से गुणा करते हुए अर्थात शीर्ष पर कम मूल्यों के साथ शुरू होता है और नीचे की तरफ उच्च होता है)।
  • इन तीनों को मिलाएं और आकार को समायोजित करें X / Y / Z कुल्हाड़ियों के साथ शोर मापते (लेख एक्स अक्ष और X और Z अक्षों पर संपीड़ित करने पर खिंचाव ) का सुझाव देता है।
  • गुफाओं की खुदाई के लिए शोर का एक अतिरिक्त पास इस्तेमाल किया जा सकता है ।

हां, मुझे लगता है कि कुछ ऐसा ही है जो मैं चाहता हूं। बात यह है कि मेरे पास पेर्लिन शोर के साथ बहुत कम अनुभव है, इसलिए केवल एक चीज जो मैं उत्पन्न कर सकता हूं, वह वास्तव में बुनियादी पहाड़ है और "शोर टॉगल के कई सप्तक" को जोड़ने के बारे में कोई विचार नहीं होगा)। पेरलिन शोर पीढ़ी के लिए मैं कोड का उपयोग कर रहा हूं। कि मैं उतर गया stackoverflow.com/questions/4753055/... और सी # करने के लिए इसे स्थलांतरित किया। बीमार मूल पोस्ट में अपने संस्करण जोड़ने ... चाहेंगे तुम मुझे का एक उदाहरण देने के लिए मैं कैसे उस के साथ इस तरह के एक बड़े पैमाने पर भूमि प्राप्त करने के लिए तैयार हो जाएगा कोड?
डेरेस्टियम

2
इसलिए मैंने लेख को लिंक किया। इसमें अंत में सभी चरणों और स्रोत कोड की व्याख्या है। आपको उसका अध्ययन करने का प्रयास करना चाहिए।
डेविड गौवेया

4
  1. अपने मौजूदा 3D ग्रिड का उपयोग करके, उस ऊँचाई पर निर्णय लें, जिस पर आप द्वीप शीर्ष चाहते हैं। उस 2D प्लेन में द्वीपों का एक सेट बनाएं (इसे XY प्लेन कहते हैं) प्लेन के माध्यम से पॉइंट्स को बिखेरते हुए, फिर उन पॉइंट्स पर क्यूब्स रखकर। ताली में उन्हें करीब से खींचने के लिए सामंजस्य का उपयोग करें। किसी भी छेद में भरें और आपके पास द्वीप-टॉप का एक सेट है।
  2. का उपयोग CA काद्वीपों के नीचे की ओर बढ़ने के लिए -similar विधि। (ए) जेड स्तर पर शुरू करना, जहां आपने अपने प्रारंभिक बिंदुओं को प्लॉट किया है, उस वर्तमान जेड स्तर के प्रत्येक सेल के लिए, एक्सवाई विमान में पड़ोसियों की संख्या को देखते हुए अगले निचले स्तर तक विस्तार करने का मौका निर्धारित करें, ० से the तक ( विकर्ण पड़ोसी शामिल हैं), उदाहरण के लिए, प्रत्येक पड़ोसी के लिए अधिकतम 80% संभावना के लिए 10% मौका प्रदान करें। शुरुआती विमान में प्रत्येक कोशिका के लिए इसकी गणना करें। (b) फिर इस मौके के खिलाफ रैंडमाइज करें और यदि आप प्रतिशत सीमा के भीतर हैं तो नीचे की ओर बढ़ाएं। कुल्ला, चरण 2 को दोहराएं (अगले स्तर पर जाएं, प्रत्येक स्वर के लिए पड़ोसियों को निर्धारित करें, उस स्वर के लिए नीचे की ओर बढ़ाएं) जब तक कि कोई और एक्सटेंशन न हो। आपके डाउनवर्ड एक्सटेंशन को संख्या-की-पड़ोसियों के दृष्टिकोण के कारण शंकु बनाना चाहिए, क्योंकि द्वीप के XY- केंद्र की ओर उन स्वरों में आमतौर पर अधिक पड़ोसी होंगे।

चरण 2 के लिए स्यूडोकोड:

int planeNeighbours[x][y]; //stores how many neighbours each voxel in this plane has

for each z level (starting at level where you plotted your points)
    for each x, y voxel in z level
        for each neighbour space bordering this voxel
            if neighbour exists
                ++planeNeighbours[x][y];
    for each x, y voxel in z level
        chance = random(0,8); //depends on your RNG implementation
        if chance < planeNeighbours[x][y]
            worldGrid[x][y][z+1] = new cube

एक बार जब आपके द्वीपों का निर्माण हो जाता है, तो आप वैकल्पिक रूप से उन्हें अलग-अलग ऊंचाइयों पर रखने के लिए अंतरिक्ष में ऊपर और नीचे स्थानांतरित कर सकते हैं।


ठीक है, मुझे आपकी पद्धति में दरार आ गई थी और लगता है कि यह आवक के बजाय भूभाग को बाहर की ओर बढ़ा रहा है। मैं कोड पोस्ट करूँगा ...
Darestium
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.