पेरलिन शोर द्वारा बनाई गई दुनिया में स्पैनिंग इकाइयाँ?


16

मेरे पेरलिन शोर-आधारित गेम में कुछ समस्याएँ आई हैं। नीचे दिए गए संलग्न स्क्रीनशॉट पर एक नज़र डालें।

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

आपके द्वारा देखे जाने वाले सफेद क्षेत्र दीवारें हैं, और काले क्षेत्र चलने योग्य हैं। बीच में त्रिकोण खिलाड़ी है।

मैंने इस खेल में एक बनावट (सफेद या काले रंग के पिक्सल) पर ड्राइंग करके, और फिर सीपीयू से प्राप्त करके भौतिकी को लागू किया है।

हालांकि, अब मैं हाथ में एक अलग समस्या के साथ खड़ा हूं। मुझे स्क्रीन के किनारे पर लगातार स्पॉन के लिए इकाइयाँ (या ढोंगी, जो भी आप उन्हें कहते हैं) चाहिए। यहां मुद्दा यह है कि अंतिम गेम में, "युद्ध का कोहरा" होगा जो खिलाड़ी को वैसे भी दूर तक देखने की अनुमति नहीं देता है।

मुझे लगा कि मैं पिक्सेल को स्क्रीन के किनारे पर स्कैन कर सकता हूं और देख सकता हूं कि क्या उनकी भौतिकी की बनावट काली है, और फिर वहां रैंडम सामान बिखरा हुआ है। हालाँकि, यदि आप स्क्रीनशॉट पर दूसरा नज़र डालते हैं, तो (ऊपरी-बाएँ कोने में) एक उदाहरण है जहाँ मैं ढोंगी को नहीं देखना चाहता हूँ (क्योंकि वे वहाँ से खिलाड़ी तक नहीं पहुँच पाएंगे) ।

क्या यह संभव है कि GPU ने मेरे लिए इन स्पॉन-स्पॉट्स का निर्धारण किया है, या कुछ अलग तरीके से? मैंने स्क्रीन और खिलाड़ी के किनारे पर प्रस्तावित बिंदु के बीच वैक्टर बनाने के बारे में सोचा, और उसके बाद हर 10 स्वरों का पालन किया, और देखा कि क्या कोई दीवार टकराती है, इससे पहले कि वहां एक यूनिट को देखा जाए।

हालाँकि, ऊपर प्रस्तावित समाधान सीपीयू गहन भी हो सकता है।

इस मामले पर कोई सुझाव?

नोट 1 इकाइयों के लिए, मैं दीवार टकराव से बचने के लिए किसी भी प्रकार के पथ-प्रदर्शक का उपयोग नहीं करना चाहता क्योंकि ये इकाइयाँ खिलाड़ी की ओर चलती हैं। इसलिए, इकाइयों को स्क्रीन के किनारे पर स्थित होना चाहिए, ऐसे स्थान पर जहां खिलाड़ी की ओर सीधी रेखा में चलना किसी भी दीवार से नहीं टकराएगा।


1
क्या नक्शा खिलाड़ी के साथ घूमता है, या खिलाड़ी नक्शे में घूमता है? यानी क्या नक्शा बदल रहा होगा? यदि नहीं, तो मैं सभी गैर-पहुंच बिंदुओं को पीढ़ी में भरने का सुझाव दूंगा, ताकि आपको उनके बारे में चिंता करने की आवश्यकता न हो।
dlras2

यदि खिलाड़ी आगे बढ़ रहा है, तो इकाइयों को एक रास्ता खोजने की विधि की आवश्यकता होगी। यदि आप अवतल क्षेत्रों को चाहते हैं तो आपको यह समस्या होगी और आपको चलती इकाई के लिए एक समाधान प्रदान करना होगा जो एक गतिशील खिलाड़ी तक पहुंचने की कोशिश कर रहा है ... उर्फ ​​पथ खोज।
बलाउ

1
या, ब्लाउज की टिप्पणी को दूसरे तरीके से रखने के लिए: आपके प्रश्न का कोई मान्य उत्तर नहीं है (यदि कोई दीवार टाइल / पिक्सेल बिल्कुल भी नहीं है तो नक्शे के तुच्छ मामले से अलग) अगर खिलाड़ी आगे बढ़ सकता है। यह अभी भी आवश्यक है कि आप परिभाषित करें कि "स्ट्रेट लाइन" के साथ आपका क्या मतलब है यदि खिलाड़ी स्थिर है, तो इसका उत्तर है।
मार्टिन सोज्का

जवाबों:


3

इस काम के लिए एक बहुत उपयोगी एल्गोरिदम है, इस स्थिति में बाढ़ एल्गोरिथ्म की तुलना में बहुत अधिक कुशल (इसकी जटिलता रनटाइम बाढ़ क्षेत्र के बजाय सीमा के आकार के लिए आनुपातिक है): यह मार्चिंग स्क्वायर एल्गोरिथम है। अवधारणा सरल है: खिलाड़ियों के स्थान (स्क्रीन मिडपॉइंट) को बंद करना, एक दिशा चुनना और एक दीवार मिलने तक चलना। जब आप दीवार से टकराते हैं, तो आप एल्गोरिथ्म शुरू करते हैं: आप एक अभिविन्यास (ऊपर या नीचे) चुनते हैं और पिक्सल को उजागर करते हुए, इस क्षेत्र की सीमा पर मार्च करना शुरू करते हैं। यह आपको अनुमत क्षेत्र के लिए आंतरिक सीमा देता है। बाद में, आप बस जाँच करें कि क्या स्पॉनिंग इकाइयों के लिए उम्मीदवार इस सीमा पर स्थित हैं।

यह वह सिद्धांत है जिसे आपको सीमा को चलाने के लिए पालन करना चाहिए:

http://en.wikipedia.org/wiki/File:Marchsquares.png (meh मैं अभी तक पोस्ट नहीं कर सकता)

विकिपीडिया विवरण (हालांकि इसमें बहुत अधिक जटिलता है क्योंकि इसका उपयोग अन्य अनुप्रयोगों को ध्यान में रखकर किया जाता है):

http://en.wikipedia.org/wiki/Marching_squares


10

एक बनाओ बाढ़ भरण खिलाड़ी की स्थिति से; हर क्षेत्र "बाढ़" तब एक वैध खेल क्षेत्र है, और अन्य सभी दीवारें हैं।

संपादित करें: "एक सीधी रेखा में पहुंच योग्य" अतिरिक्त आवश्यकता के रूप में, ध्यान रखें कि एक असतत जगह में , आपको इसे थोड़ा आगे परिभाषित करना होगा। उदाहरण के लिए, इस तरह के वातावरण में उपरोक्त सभी रास्ते एक वैध "सीधी रेखा" हो सकते हैं, और मैंने उन सभी को किसी न किसी बिंदु पर एक गेम में इस्तेमाल करते देखा है:

"स्ट्रेट लाइन" वेरिएंट

विशेष रूप से, उन लोगों में से अधिकांश कम्यूटेटिव नहीं हैं - जिसका अर्थ है कि सिर्फ इसलिए कि आप "सीधी रेखा" में A से B तक पहुँच सकते हैं इसका मतलब यह नहीं है कि आप B से A तक भी पहुँच सकते हैं; जरूरी नहीं कि विपरीत ही सही हो।

इसके अलावा, यह सवाल है कि आप विकर्ण आंदोलन को कैसे संभालते हैं यदि एक या दोनों "पक्ष" अंक अवरुद्ध हो रहे हैं।


क्या इसे पूरी तरह से एचएलएसएल में लागू किया जा सकता है?
मैथियास लिकेगार्ड लोरेनजेन

@ मैथियास लाइकेगार्ड लोरेंजेन: हाँ, एक शैडर के रूप में एल्गोरिथ्म के प्रत्येक चरण को करने में संदेह है और उदाहरण के लिए दो बनावट लक्ष्यों के बीच प्रतिपादन, लेकिन ... क्यों ? आपको सीपीयू पर एल्गोरिदम से जानकारी प्राप्त करने की आवश्यकता होगी, वैसे भी पथ खोजने के लिए बहुत कम से कम।
मार्टिन सोज्का

1
@ मैथियास लिकेगार्ड लोरेंजेन: यह आपके द्वारा पूछे गए से थोड़ा अलग है, हालांकि। इस मामले में: आप "सीधी रेखा" को कैसे परिभाषित करते हैं, यह आपके असतत अंतरिक्ष विभाजन स्कीमा को देखते हुए है?
मार्टिन सोज्का

2
यहां तक ​​कि अगर आप पाथफाइंडिंग का उपयोग नहीं करना चाहते हैं, तो सीपीयू को फ्लडफिल जॉब करने के लिए कहना संभव है, याद रखें कि आपको केवल एक बार फ्लडफिल को कॉल करने की आवश्यकता है और फिर आपके पास 3 रंगों की दीवार, फ्री स्पेस और स्पैनेबल स्पेस को परिभाषित करने की आवश्यकता होगी। 4096x4096 बनावट के लिए यह फ्लडफिल जॉब को पूरा करने के लिए सीपीयू के लिए एक सेकेंड से कम समय लगेगा।
अली

1
मुद्दा यह है कि आपको केवल एक बार इस बाढ़ को भरना है, और यहां तक ​​कि अगर आपके इलाक़े में बदलाव होता है, तो गेमप्ले के दौरान आपको केवल उन वर्गों को अपडेट करना होगा जो बाढ़ से प्रभावित हैं और उनके माध्यम से बाढ़ के रास्ते चलते हैं जो कि नारकीय रूप से तेज़ है।
ट्रैविसग

1

कैसे के बारे में सिर्फ spawns होने दे? मुझे इसमें कोई विशेष समस्या नहीं दिख रही है।


और अगर वे एक दीवार के पीछे भागते हैं तो क्या होगा? आप उन्हें खिलाड़ी तक कैसे पहुंचाएंगे?
मैथियास लिकेगार्ड लोरेनजेन

1
यह एक समस्या हो सकती है यदि खेल में सभी दुश्मनों को मारने का परिदृश्य है, और यह 50 दुश्मनों को जन्म देता है, लेकिन कुछ को दीवार के पीछे रखा गया था। खिलाड़ी दुश्मनों को मारने में सक्षम नहीं होगा और परिदृश्य खत्म नहीं होगा।
रेयान

1
अन्य इकाइयां अभी भी खिलाड़ी तक पहुंचने में सक्षम नहीं हो सकती हैं, यह इस बात पर निर्भर करता है कि खिलाड़ी के जाने के बाद वे कैसे आगे बढ़ते हैं, आपको किसी भी स्थिति में कुछ इकाइयों को खोलना होगा।
आआआआआआआआआआआ आआआआ आआआ स स स स

युद्ध का कोहरा भद्दे
भिखारियों

1
जब खिलाड़ी चलता है तो वैसे भी काम नहीं करेगा।
आआआआआआआआआआआआ आआआआ आआआआ आआआ आआआआआ

1

यदि आपके लिए यह महत्वपूर्ण है कि आप केवल उस खिलाड़ी को मान्य स्ट्रेट लाइन के साथ अंक चिह्नित करें जिसे आप निम्न की तरह एक एल्गोरिथ्म का उपयोग कर सकते हैं (यह एक c ++ कोड है), तो यह सामान्य फ्लडफिल से अधिक खपत करता है। कुछ छोटे कीड़े हो सकते हैं (मुझे खुशी होगी अगर किसी ने उन्हें सही किया है) क्योंकि मैंने खुद कोड का परीक्षण नहीं किया है, लेकिन आपको विचार मिलेगा।

void straightlineFill(Point startPoint, Texture target)
{
    queue<Point> pointQueue;
    for (int dx = -1;dx <=1;dx ++)
            for(int dy = -1;dy <=1;dy++)
                if(dx != 0 && dy != 0)
                    pointQueue.push(point(startPoint.x + dx, startPoint.y + dy));
    while (!pointQueue.empty())
    {
        point front = pointQueue.front();
        pointQueue.pop();
        if (target.pixelAt(front) == COLOR_SPAWNABLE||
            target.pixelAt(front) == COLOR_WALL||
            target.pixelAt(front) == COLOR_NOT_SPAWNABLE)
                continue;
        taraget.setPixelAt(front, colorFilled); 
        for (int dx = -1;dx <=1;dx ++)
            for(int dy = -1;dy <=1;dy++)
                if(dx != 0 && dy != 0)
                    pointQueue.push(point(front.x + dx, front.y + dy));
        // up until now was the normal floodfill code
        // and here is the part that will do the real straight line checking

        // lineDX & lineDY will keep how much the line we are checking is skewed
        int lineDX = front.x - startPoint.x;
        int lineDY = front.y - startPoint.y;

        // step will show us how much we have to travel to reach each point of line
        point step;
        if (abs(lineDX) < abs(lineDY))
        {
            if (lineDX < 0)
                step = point(-1,0);
            if (lineDX == 0)
                if (lineDY < 0)
                    step = point(0,-1);
                else
                    step = point(0,1);
            if (lineDX > 0)
                step = point(1,0);
        }

        if (abs(lineDX) < abs(lineDY))
        {
            if (lineDY < 0)
                step = point(0,-1);
            if (lineDY == 0)
                if (lineDX < 0)
                    step = point(-1,0);
                else
                    step = point(1,0);
            if (lineDY > 0)
                step = point(0,1);
        }

        // moved will keep how much we have traveled so far, it's just some value that will speed up calculations and doesn't have any mathematical value
        point moved = 0;

        // spawnable will keep if the current pixel is a valid spawnpaint

        bool spawnable = true;

        // now we will travel on the straight line from player position to the edges of the map and check if whole line is valid spawn points or not.

        while (target.isInside(front))
        {
            front = front + step;
            moved = moved + point(step.x * lineDX, step.y * lineDY);
            if (step.x != 0 && moved.x < moved.y)
            {
                moved.x = moved.x - lineDY * sign(lineDY);
                front.y = front.y + sign(lineDY);
            }
            if (step.y != 0 && moved.y < moved.x)
            {
                moved.y = moved.y - lineDX * sign(lineDX);
                front.x = front.x + sign(lineDX);
            }

            if (target.getPixelAt(front) == COLOR_WALL)
                spawnable = false;

            if (spawnable)
            {
                target.setPixelAt(front,COLOR_SPAWNABLE);
                for (int dx = -1;dx <=1;dx ++)
                    for(int dy = -1;dy <=1;dy++)
                        if(dx != 0 && dy != 0)
                            pointQueue.push(point(front.x + dx, front.y + dy));             
            }
            else
            {
                target.setPixelAt(front,COLOR_NOT_SPAWNABLE);
            }
        }
    }
}

1

आप मानचित्र को रंगों से भर सकते हैं जो उत्तल क्षेत्रों का प्रतिनिधित्व करता है ..., इस तरह से आप अपनी इकाई को उसी क्षेत्र में स्थित कर सकते हैं। या आप आसानी से उपलब्ध क्षेत्रों के लिए खोज कर सकते हैं।

यह स्थैतिक डेटा है ताकि आप इसे पहले से बता सकें।

आपको इमेज फाइंडिंग पॉइंट्स को भरना था, जहाँ कॉनवे से कॉनवेक्स में बदलाव होता है, दृष्टिगत रूप से इसे ढूंढना आसान है, आपको दो स्थितियाँ मिलेंगी:

  1. क्षैतिज: जहां नारंगी से नीले रंग में परिवर्तन होता है।
  2. कार्यक्षेत्र: जहां लाल ओटी हरे और नारंगी रंग बदलता है।

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


यह काम नहीं करता है। नीचे दाईं ओर देखें, विशेष रूप से लाल क्षेत्र में बूँद। यह पूरी तरह से उत्तल है इसलिए किसी अन्य रंग का उपयोग करने के लिए कोई बदलाव नहीं है, लेकिन स्पष्ट रूप से कोई सीधी रेखा लाल किनारे के नीचे से दाहिने किनारे पर लाल रंग के सबसे निचले हिस्से में मौजूद नहीं है।
लोरेन Pechtel

@ लॉरेन Pechtel यह हाथ से बनाया गया है, आप सही हैं, वहाँ एक त्रुटि है, यह मेरी गलती है, लेकिन आप महसूस कर सकते हैं कि यह वही स्थिति है जो नारंगी से नीला संक्रमण है।
Blau

@ लॉरेन Pechtel, याद दिलाते हैं कि पीत जैसे क्षेत्रों में स्पजेट से बचा जाता है। यह विधि सुनिश्चित करती है कि यदि आप एक ही क्षेत्र में एक दुश्मन को छोड़ते हैं जिसमें खिलाड़ी शामिल है, तो यह उपलब्ध है। बेशक, इसे लागू करना मुश्किल हो सकता है, लेकिन यह विचार वैध है।
ब्लाउ

आपका संशोधन मदद नहीं करता है। उत्तल वक्र पर दो बिंदुओं के बीच कभी भी कानूनी सीधी रेखा नहीं होगी। अधिक विभाजन मदद नहीं करेगा।
लोरेन पेचटेल

कृपया क्षेत्रों या बिंदुओं के समूह का संदर्भ देते हुए उत्तल की परिभाषा की जाँच करें ... en.wikipedia.org/wiki/Convex
Blau

1

यहाँ कुछ ऐसा है जो मैं वास्तव में अपने खेल (2d सिंप्लेक्स शोर उत्पन्न दुनिया में, लगभग आपकी तरह) का उपयोग करता था - किरणें। खिलाड़ी पर शुरू करें, एक अभिविन्यास निर्धारित करें (यदि आप चाहते हैं तो यादृच्छिक), और जब तक आप कुछ हिट न करें (स्क्रीन या क्षुद्रग्रह के किनारे) तब तक उस रेखा के साथ जाएं। यदि आप स्क्रीन के किनारे पर हिट करते हैं (और क्षुद्रग्रह / सफेद बूँद नहीं), तो आप जानते हैं कि स्क्रीन के किनारे से खिलाड़ी तक एक सीधी, खुली रेखा है। फिर आप मारा बिंदु पर एक राक्षस छिड़क। यदि आप एक क्षुद्रग्रह को मारते हैं, तो परीक्षण फिर से करें।


0

एक और (गैर-जीपीयू) समाधान जिसका आप उपयोग कर सकते हैं वह है पथ-खोज। नक्शा खींचने से पहले, नक्शे के प्रत्येक किनारे पर प्रत्येक संभावित स्पॉन-पॉइंट से पथ-खोजें और देखें कि क्या केंद्र के लिए कोई रास्ता है। ए * पाथ-फाइंडिंग कॉस्ट / परफॉर्मेंस पर काफी ठीक है, लेकिन गेम शुरू होने से पहले आप ऐसा कर सकते हैं, अगर यह कोई समस्या है।

कोई भी स्पॉन पॉइंट जिसमें एक पथ नहीं है उसे बहिष्करण सूची में रखा जा सकता है; या इसके विपरीत (पथ के साथ किसी भी बिंदु को शामिल किए जाने की सूची में रखा जा सकता है)।

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