टाइल नक्शा बनाना


25

मैं एक टाइल आधारित गेम की प्रोग्रामिंग कर रहा हूं और मेरे पास कुछ बुनियादी टाइलें (घास, गंदगी, आदि) हैं, लेकिन मैं यह पता नहीं लगा सकता कि अच्छे यादृच्छिक मानचित्र पीढ़ी कैसे बनाई जाए, क्योंकि जब मैं कुछ वास्तव में यादृच्छिक चयन करता हूं, तो टाइल घास / गंदगी होनी चाहिए, मुझे यह मिलता है:

खेल में चित्र

मैं समझता हूं कि ऐसा क्यों हो रहा है, लेकिन मैं चाहता हूं कि घास या गंदगी के कुछ यादृच्छिक निरंतर क्षेत्र बनाएं। कुछ ऐसा जो अधिक समझ में आता है, जैसे:

वांछित परिणाम


1
प्रस्तावित उत्तरों के अलावा, आप इस तरह के नक्शे बनाने के लिए अपना खुद का सेलुलर ऑटोमेटन इंजन लिख सकते हैं। ऑटोमेटन के नियमों को संशोधित करने से आप बहुत भिन्न व्यवहार उत्पन्न कर सकते हैं, जिससे बहुत भिन्न प्रकार के मानचित्र बन सकते हैं। उदाहरण के लिए, जीवन के समान एक 2 डी ऑटोमेटन, बाढ़ के नियमों से "महासागर और द्वीप समूह" हो सकते हैं (ऊपर आपकी तस्वीर की तरह), और 1267/17 जैसा एक नियम सुंदर प्रयोगशालाओं का नेतृत्व कर सकता है।
मनु ३४३ Man२६

जवाबों:


19

आप जो कर सकते हैं वह बेतरतीब ढंग से इस तरह से एक वोरोनोई मानचित्र उत्पन्न करें:

  1. center pointsबेतरतीब ढंग से उठा (काले डॉट्स देखें) और बेतरतीब ढंग से तय करें कि क्या वे घास या गंदगी हैं।
  2. फिर सभी टाइलों के लिए, जांचें कि क्या यह center pointगंदगी या घास के सबसे करीब है ।
  3. किया हुआ!

यदि आपने पहले किया था तो प्रत्येक टाइल (शोर) के लिए "एक सिक्का फ्लिप करें", वोरोनोई आरेख बनाने से बहुत बेहतर परिणाम मिलेगा।

एक एल्गोरिथ्म के साथ center pointsमें विभाजित करके आप इस पर सुधार कर सकते हैं islands:

  1. के एक छोटे समूह को पसंद करता है centers pointsऔर उन्हें नामित करता है leaders
  2. Iteratively प्रत्येक बारी में एक यादृच्छिक आसन्न केंद्र बिंदु जोड़ता है।
  3. किया हुआ!

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


1
धन्यवाद, लेकिन यह एक बहुत मुश्किल समाधान की तरह लगता है।
विल्दा

2
यह बहुत मुश्किल समाधान नहीं है। पहले बेतरतीब ढंग से उठाओ center points। फिर तय करें कि वे घास हैं या गंदगी। अब सरणी पर लूप करें और तय करें कि क्या प्रत्येक टाइल गंदगी बिंदु या घास बिंदु के सबसे करीब है। शायद मुझे बताएं कि कौन सा हिस्सा चुनौतीपूर्ण है?
वूल्फडॉन

की दूरी नापना। वैसे भी, मैं कोशिश करूंगा और आपको बताऊंगा।
विल्दा

ठीक है, इसलिए मैंने सफलतापूर्वक कुछ बिंदु उत्पन्न किए हैं। ( Dropbox.com/s/dlx9uxz8kkid3kc/random_tile_map2.png ) और इसलिए इस तरह पैदा दिखता के लिए मेरी पूरी कक्षा: dropbox.com/s/pxhn902xqrhtli4/gen.java । लेकिन यह अभी भी काम नहीं करता है।
विल्दा

3
@ViliX आपके लिंक टूट गए हैं
Artur Czajka

24

आप पेरीलिन के शोर का उपयोग कर सकते हैं, जो सामान्य रूप से ऊँचाई वाली पीढ़ी के लिए उपयोग किया जाता है। खेलों में पेर्लिन का शोर

तब आप एक सलाहकार के रूप में ऊंचाइयों का उपयोग कर सकते थे, नक्शे के एक क्षेत्र में घास / गंदगी की संभावना कितनी अधिक है।

उदाहरण (0-256 से पर्लिन शोर मान): यदि मान 200 से अधिक है, तो घास को 80% (गंदगी 20%) रखा गया है। यदि मान 100 और 200 के बीच है तो मौका है कि घास रखी गई है 50% (गंदगी भी 50%)। यदि मान 100 से कम है तो मौका है कि घास 20% है (गंदगी 80%)।


ठीक है, चलो कहते हैं कि मेरे पास फ्लोट (संभावना की 0-1) की एक सरणी [] [] है और मैं इसका उपयोग प्रायिकता के साथ टाइलों को फैलाने के लिए कर सकता हूं। लेकिन मैं इस संभावना सरणी को कैसे भरूं? सरणी है (मान लें) 400x200, इसे प्रायिकता मानों से कैसे भरें?
विल्दा

वह इसे पर्लिन नॉइज़ (सफ़ेद शोर के बजाय सिक्के के फ़्लिप) से भरने का सुझाव दे रहा है।
भेड़ियाडॉन

हां, लेकिन मैं इसे कैसे हासिल कर सकता हूं?
विल्दा

मैंने जो लिंक पोस्ट किया है वह इस प्रश्न को स्पष्ट कर सकता है। पहले एक शोर उत्पन्न करें और फिर इस शोर को सुचारू करें। परिणाम एक 2 आयामी सरणी होगा जिसका उपयोग आप आगे की पीढ़ी के तिलमप के लिए कर सकते हैं। लिंक
क्लिट्ज़

यह वास्तव में अच्छा उत्तर है, लेकिन यह शायद ही कभी आपके द्वारा प्रस्तुत किए गए परिणामों के समान होगा।
वूल्फडॉन

8

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

http://gamedevelopment.tutsplus.com/tutorials/generate-random-cave-levels-using-cellular-automata--gamedev-9664

यहाँ सेलुलर ऑटोमेटा पद्धति का मेरा संस्करण ग्रिड को यादृच्छिक रूप से भरने के द्वारा शुरू होता है, फिर उस पर इन कुंडलाकार ऑटोमेटा नियमों को एक दो बार चलाएं

  • यदि एक जीवित कोशिका में दो जीवित पड़ोसी कम हैं, तो यह मर जाता है।
  • यदि एक जीवित कोशिका में दो या तीन जीवित पड़ोसी होते हैं, तो यह जीवित रहता है।
  • यदि एक जीवित कोशिका में तीन से अधिक जीवित पड़ोसी होते हैं, तो यह मर जाता है।
  • यदि एक मृत कोशिका में तीन जीवित पड़ोसी होते हैं, तो यह जीवित हो जाता है।

और यह गुफा की तरह दिखाई देता है

सूचकांक को x और y स्थिति में और इस कोड के साथ वापस परिवर्तित किया जा सकता है

public int TileIndex(int x, int y)
{
    return y * Generator.Instance.Width + x;
}
public Vector2 TilePosition(int index)
{
    float y = index / Generator.Instance.Width;
    float x = index - Generator.Instance.Width * y;
    return new Vector2(x, y);
}

मैं सिर्फ बस्ट की एक सूची वापस करता हूं क्योंकि मैं कई चीजों के लिए इस सूची का उपयोग करता हूं: गुफाएं, पेड़, फूल, घास, कोहरे, पानी आप यहां तक ​​कि कई सूचियों को अलग-अलग तरीकों से जोड़ सकते हैं मैं पहले सभी छोटी गुफाओं को हटाता हूं फिर दो यादृच्छिक सूचियों का संघटन करता हूं

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

private int GetAdjacentCount(List<bool> list, Vector2 p)
{
    int count = 0;
    for (int y = -1; y <= 1; y++)
    {
        for (int x = -1; x <= 1; x++)
        {
            if (!((x == 0) && (y == 0)))
            {
                Vector2 point = new Vector2(p.x + x, p.y + y);
                if (PathFinder.Instance.InsideMap(point))
                {
                    int index = PathFinder.Instance.TileIndex(point);
                    if (list[index])
                    {
                        count++;
                    }
                }
                else
                {
                    count++;
                }
            }
        }
    }
    return count;
}
private List<bool> GetCellularList(int steps, float chance, int birth, int death)
{
    int count = _width * _height;
    List<bool> list = Enumerable.Repeat(false, count).ToList();
    for (int y = 0; y < _height; y++)
    {
        for (int x = 0; x < _width; x++)
        {
            Vector2 p = new Vector2(x, y);
            int index = PathFinder.Instance.TileIndex(p);
            list[index] = Utility.RandomPercent(chance);
        }
    }
    for (int i = 0; i < steps; i++)
    {
        var temp = Enumerable.Repeat(false, count).ToList();
        for (int y = 0; y < _height; y++)
        {
            for (int x = 0; x < _width; x++)
            {
                Vector2 p = new Vector2(x, y);
                int index = PathFinder.Instance.TileIndex(p);
                if (index == -1) Debug.Log(index);
                int adjacent = GetAdjacentCount(list, p);
                bool set = list[index];
                if (set)
                {
                    if (adjacent < death)
                        set = false;
                }
                else
                {
                    if (adjacent > birth)
                        set = true;
                }
                temp[index] = set;
            }
        }
        list = temp;
    }
    if ((steps > 0) && Utility.RandomBool())
        RemoveSmall(list);
    return list;
}

2
कृपया बताएं कि आपका कोड क्या करता है, इसके बजाय एक नमूना पोस्ट करता है, एक लिंक, और स्वयं कोड। आपका उत्तर स्व-सम्‍मिलित होना चाहिए, ताकि भले ही लिंक टूट जाए, फिर भी यह प्रयोग करने योग्य है।
निधि मोनिका का मुकदमा

6

मानचित्र पर एक बिंदु चुनें। वांछित टाइल प्रकार को आधार मान के साथ रखें जैसे कि 40। जहाँ आपने अपना नया वांछित टाइल रखा है, उस पर नज़र रखें। सूची में प्रारंभिक बिंदु जोड़ें।

इस सूची के प्रत्येक बिंदु के लिए, आप सभी पड़ोसियों से मिलते हैं। जबकि आपके पास पर्याप्त शक्ति बची हुई है (40 से शुरू हुई) एक वांछित टाइल जोड़ें और इसे विज़िट की जाने वाली सूची में जोड़ें। आपके द्वारा निर्धारित नई टाइल को कम शक्ति दें। सबसे आसान = यादृच्छिक कम करना। सूची से टाइल का दौरा करने के बाद, इसे हटा दें। किसी भी गैर-निर्मित लेकिन बनाई गई टाइल पर जाकर फिर से शुरू करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.