আমি কীভাবে একটি মাইনক্রাফ্ট-এর মতো ইঞ্জিনের জন্য ভাসমান স্থল জনতা তৈরি করতে পারি?


19

আমি এক্সএনএ-তে একটি মাইনক্রাফ্টের মতো ইঞ্জিন তৈরি করছি। আমি যা করতে চাই তা হ'ল এই ভিডিওতে দেখানো মতই ভাসমান দ্বীপগুলি তৈরি করা:

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

বেস ল্যান্ডের জন্য, দুটি 2 ডি অবিচ্ছিন্ন শব্দ ক্ষেত্রগুলি তৈরি করুন (পার্লিন, সিম্প্লেক্স, ওয়েভলেট, এর সংমিশ্রণ - যা আপনার পক্ষে কার্যকর হয়), বেশিরভাগই কম ফ্রিকোয়েন্সি সহ। জমির উপরের সীমাটির জন্য কম প্রশস্ততা অংশগুলি, উভয় উচ্চ ফ্রিকোয়েন্সি, উচ্চ প্রশস্ততা অংশ এবং কম ফ্রিকোয়েন্সি সহ জমির নিম্ন সীমাটির জন্য উচ্চ প্রশস্ততা। যেখানে নিম্ন সীমাটি উচ্চতর সীমা ছাড়িয়ে গেছে সেখানে কোনও স্থল ভক্সেল (বা আপনার গেমটি অঞ্চলটিকে উপস্থাপন করতে যা ব্যবহার করবে) অন্তর্ভুক্ত করবেন না। শেষ ফলাফলটি মোটামুটি এরকম দেখাচ্ছে ...


তবে এটি 2 ডি এর জন্য নয় কি?
ডারেস্টিয়াম

তবে আমি এটি বেশ পছন্দ করি :)
ডেরেস্টিয়াম

4
2 ডি / 3 ডি - একই জিনিস
গ্যাভিন উইলিয়ামস

ঠিক আছে, এটি
tommorow

@ ডারেস্টিয়াম: সহজে দেখার জন্য এটি 2D উদাহরণ। একই পদ্ধতি একের চেয়ে বেশি সংখ্যক (বীজগণিত) মাত্রার জন্য কাজ করে।
মার্টিন সোজকা

15

এই মত কিছু যথেষ্ট হবে?

এখানে চিত্র বর্ণনা লিখুন

যদি তাই হয় তবে এই নিবন্ধটি পরীক্ষা করুন । সর্বাধিক প্রাসঙ্গিক অংশ উদ্ধৃত:

আরও আকর্ষণীয় আওয়াজ পাওয়ার জন্য সিমপ্লেক্স গোলমালের একাধিক অক্টেভ একসাথে যুক্ত করা যেতে পারে। [...] যেহেতু আমি মোটামুটি গোলাকৃতির ভাসমান রক পেতে চাই, তাই কেন্দ্র থেকে এর দূরত্বের সাথে আমার গোলমালটি আরও বাড়ানো দরকার। [...] আমি চাই পাথরের নীচের অংশের চেয়ে শীর্ষে চ্যাপ্টা হওয়া উচিত, সুতরাং দ্বিতীয় গুনের ফ্যাক্টরটি y দিকের এক গ্রেডিয়েন্ট। এগুলিকে একত্রিত করে এবং এক্স এবং জ্যা বিটকে সংকুচিত করার সময় শব্দের জন্য y প্রসারিত করার ফলে আমরা ভাসমান শিলাটির মতো কিছু পাই। [...] খোলামেলা গুহাগুলি অন্য শব্দ শোনার আরেকটি উদাহরণ দিয়ে এটি আরও আকর্ষণীয় করে তুলেছে।

  • সুতরাং মূলত আপনি সিমপ্লেক্স বা পার্লিন শব্দ থেকে উত্পন্ন কোনও ডেটা সেট দিয়ে শুরু করবেন (বা একাধিক গোলমাল শব্দের একসাথে যুক্ত )।
  • তারপরে এটিকে আরও গোলাকার করে (শব্দটি এর দ্বারা বহুগুণ করে) ভাসমান ল্যান্ডমাসের কাছাকাছি কিছুতে রূপ দিন কেন্দ্র থেকে দূরত্বের সাথে ) ।
  • এবং এটি চাটুকার করে স্থল তৈরি করুন শীর্ষের কাছাকাছি (এটি একটি উল্লম্ব গ্রেডিয়েন্ট দ্বারা গুণের মাধ্যমে অর্থাৎ শীর্ষে নিম্ন মানের সাথে শুরু করে নীচের দিকে উচ্চতর হওয়া)।
  • এই তিনটি একত্রিত করুন এবং স্কেলিং করে আকারটি সামঞ্জস্য করুন এক্স / ওয়াই / জেড অক্ষের সাথে শব্দটি (নিবন্ধটি ওয়াই অক্ষের উপর প্রসারিত হওয়া এবং এক্স এবং জেড অক্ষগুলিতে সংক্ষেপে পরামর্শ দেয় )।
  • গুহাগুলি খনন করতে একটি অতিরিক্ত শব্দ শোনানো যেতে পারে ।

হ্যাঁ, আমি মনে করি এটির মতো কিছু আমার কাছে যা চান তা তুচ্ছ করে। বিষয়টি হ'ল আমার পার্লিন শব্দের সাথে সামান্য অভিজ্ঞতা আছে তাই কেবলমাত্র আমি যে জিনিসটি উত্পন্ন করতে পারি তা হ'ল সত্যিকার অর্থেই মূল পর্বতমালা এবং "শব্দের টগটারের একাধিক অক্টাভ যোগ করার উপায় সম্পর্কে কোনও ধারণা থাকতে পারে না the" পার্লিন শব্দটি উত্পন্ন করার জন্য আমি কোডটি ব্যবহার করছি যে আমি স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 7575৫০৫৫৫/২ পেয়েছি এবং এটি সি # তে পোর্ট করে রেখেছি Ill আমি আমার সংস্করণটি মূল পোস্টে যুক্ত করব ... আপনি কীভাবে আমি এমন একটি ভূমি ভর অর্জন করতে পারি তার একটি উদাহরণ দিতে রাজি হবেন? কোড?
ডারেস্টিয়াম

2
এই কারণেই আমি নিবন্ধটি সংযুক্ত করেছি। এটিতে সমস্ত পদক্ষেপের ব্যাখ্যা রয়েছে এবং শেষে সোর্স কোড রয়েছে। আপনার এটি অধ্যয়নের চেষ্টা করা উচিত।
ডেভিড গাউভিয়া

4
  1. আপনার বিদ্যমান থ্রিডি গ্রিড ব্যবহার করে আপনি যে উচ্চতায় দ্বীপটি শীর্ষে থাকতে চান সে বিষয়ে সিদ্ধান্ত নিন। 2 ডি প্লেনে দ্বীপের একটি সেট তৈরি করুন (এটিকে XY প্লেন বলতে দিন) বিমানের মাধ্যমে পয়েন্টগুলি ছড়িয়ে দিয়ে, তারপর সেই পয়েন্টগুলিতে কিউব রেখে। একসাথে ক্লাম্পগুলিতে কাছাকাছি টানতে সংহতি ব্যবহার করুন। যে কোনও গর্ত পূরণ করুন এবং আপনার কাছে দ্বীপ-শীর্ষগুলির একটি সেট রয়েছে।
  2. সিএ ব্যবহার করুননীচের দিকে দ্বীপগুলি বৃদ্ধি করার অনুরূপ পদ্ধতি। (ক) জেড লেভেল থেকে শুরু করে যেখানে আপনি আপনার প্রাথমিক পয়েন্টগুলি প্লট করেছেন, সেই বর্তমান জেড স্তরের প্রতিটি কক্ষের জন্য, এক্সওয়াই বিমানের প্রতিবেশীর সংখ্যা প্রদত্ত পরবর্তী স্তরটি 0 থেকে 8 পর্যন্ত বাড়িয়ে দেওয়ার সুযোগটি নির্ধারণ করুন ( তির্যক প্রতিবেশীদের অন্তর্ভুক্ত করা হয়), উদাহরণস্বরূপ প্রতি প্রতিবেশীর জন্য একটি 10% সুযোগ নির্ধারণ করুন, সর্বোচ্চ 80% পর্যন্ত সুযোগ। প্রারম্ভিক বিমানের প্রতিটি কক্ষের জন্য এটি গণনা করুন। (খ) তারপরে এই সুযোগটির বিপরীতে র্যান্ডমাইজ করুন এবং যদি আপনি শতাংশের মধ্যে থাকেন তবে নীচের দিকে প্রসারিত করুন। ধুয়ে ফেলুন, পদক্ষেপ 2 পুনরাবৃত্তি করুন (পরবর্তী স্তরে যান, প্রতিটি ভক্সেলের প্রতিবেশী নির্ধারণ করুন, সেই ভক্সেলের জন্য নীচের দিকে প্রসারিত করুন) যতক্ষণ না আরও কোনও এক্সটেনশন ঘটে। প্রতিবেশী সংখ্যার পদ্ধতির কারণে আপনার নীচের দিকে প্রসারিত শঙ্কু তৈরি হওয়া উচিত, কারণ দ্বীপের XY- কেন্দ্রের দিকে towards ভক্সেলগুলিতে সাধারণত আরও প্রতিবেশী থাকবে।

পদক্ষেপ 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

একবার আপনার দ্বীপগুলি উত্পাদনের কাজ শেষ হয়ে গেলে, আপনি আলাদাভাবে উচ্চতর স্থানগুলিতে রাখার জন্য optionচ্ছিকভাবে এগুলিকে স্থান এবং উপরে স্থানান্তর করতে পারেন।


ঠিক আছে, আপনার পদ্ধতিতে আমার একটি ফাটল ধরেছে এবং মনে হচ্ছে এটি বাহিরের অভ্যন্তরের পরিবর্তে বাহিরের দিকে বৃদ্ধি পাচ্ছে। আমি কোডটি পোস্ট করব ...
ডেরেস্টিয়াম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.