किस तरह का स्टीयरिंग बिहेवियर या लॉजिक है कि मैं मोबाइलों का इस्तेमाल दूसरे को घेरने के लिए करूं?


10

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

हालांकि, जब कई मॉब मोबाइल का पीछा कर रहे होते हैं तो वे कभी-कभी "एक दूसरे के ऊपर ढेर" होते हैं। इससे बचने का सबसे अच्छा तरीका क्या है? मैं मॉब को अपारदर्शी और अवरुद्ध के रूप में नहीं मानना ​​चाहता (क्योंकि वे नहीं हैं, आप उनके माध्यम से चल सकते हैं) लेकिन मैं चाहता हूं कि संरचना की कुछ समझ हो।

उदाहरण:

कल्पना कीजिए कि प्रत्येक सांप ने मुझे निर्देशित किया और "सेत्सुना" को घेर लिया। ध्यान दें कि दोनों सांपों ने मुझे चुभने के लिए कैसे चुना है? यह एक सख्त आवश्यकता नहीं है; यहां तक ​​कि थोड़ा ऑफसेट ठीक है। लेकिन उन्हें सेत्सुना को "घेरना" चाहिए।

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


1
क्या गंतव्य पर स्टैकिंग केवल एक चिंता का विषय है या पारगमन के दौरान भी? मैं बाद का अनुमान लगा रहा हूं।
स्पार्टनडोनट

यह बाद की बात है,
@SpartanDonut

@KromStern मैंने एक तस्वीर जोड़ी, आशा है कि यह मदद करता है।
वॉन हिल्ट्स

जवाबों:


15

कूलम्ब के नियम की तर्ज पर, अपने एजेंटों को एक-दूसरे को पीछे हटाने के लिए एक कमजोर "इलेक्ट्रोस्टैटिक चार्ज" दें ।

सादगी के लिए यह मानते हुए कि मॉब को एक दूसरे को समान शक्ति के साथ दूर धकेलना चाहिए, यह हर जोड़ी के बीच एक बल को एक परिमाण के साथ लागू करने के लिए पर्याप्त होना चाहिए some_constant / distance^2, जहां some_constantएक विन्यास प्रतिकर्षण शक्ति है और distanceदूरी उन्हें अलग कर रही है।

प्रतिकर्षण ताकत तब दूरी के वर्ग के साथ गिर जाती है।

कोड की प्रकृति का यहां एक शानदार उदाहरण (लाइव डेमो के साथ) है । यह इस तरह दिख रहा है:

संयुक्त अनुसरण और अलग व्यवहार

प्रत्येक तत्व का हर दूसरे के खिलाफ मिलान एक द्विघात-समय ( O(n^2)) ऑपरेशन है। यदि आपके पास वास्तव में कई एजेंट हैं, तो आप बार्न्स-हट सन्निकटन के साथ बल गणनाओं को अनुकूलित करना चाह सकते हैं , जो इसे लॉग-लीनियर ( O(n log n)) में ले जाता है, लेकिन इसके लिए क्वाडट्री की आवश्यकता होती है ।


महान लिंक, Anko। बहुत सराहना की! मैं इस पूरे साइट को एक रीड ओवर देने के लिए रक्षा करूँगा।
वॉन हिल्ट्स

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

@ शिवनड्रगन एससी 2 समान व्यवहार प्रस्तुत करता है, वे सभी एक भीड़ में गंतव्य के लिए अभिसरण करते हैं, फिर तरह-तरह के यथार्थवादी और सौंदर्य की दृष्टि से आकर्षक दिखते हैं (इसलिए उनके हिस्से चारों ओर क्लिप नहीं करते हैं)।
क्रोल्टन

2
किसी प्रकार का बल देने वाला बल एक अच्छा विचार हो सकता है, लेकिन विवरण मुश्किल हैं। मैंने आरटीएस के एक स्थान पर इनका प्रयोग किया और भौतिकी का बहुत बारीकी से पालन न करने की सलाह दी और इसे मॉडलिंग किया, इसलिए यह अच्छी तरह से व्यवहार करता है। कुछ अवलोकन: 1) चूंकि यह कोई भौतिकी सिमुलेशन नहीं है, मैं केवल कम दूरी पर बल लागू करूंगा। 2) यह परिमित निकायों को ओवरलैपिंग 3 से नहीं रोक सकता है) कठिन क्षमता आसानी से संख्यात्मक त्रुटियों का कारण बनती है, जैसे कि उच्च वेग पर कणों का अपवर्तित होना। 4) एक बार जब आप कणों की एक महत्वपूर्ण संख्या और मध्य किरणों में दबाव डालते हैं, तो चीजें बदसूरत हो जाती हैं।
संहिताओंइंचौस

1

मेरा दृष्टिकोण @ Anko के समान है, लेकिन खेल के लिए आर्टिफिशियल इंटेलिजेंस से मिलिंगटन और फंज द्वारा काम पर आधारित है ।

यह एक पृथक्करण व्यवहार कैसा दिखेगा, लेकिन आपको इस बात पर ध्यान देने की आवश्यकता है कि इस वेग की गणना इसके अद्यतन कार्य में एजेंट की गति के साथ की जानी चाहिए।

public Vector3 GetSeparationVel (float threshold, float decayCoefficient)
{
    threshold = threshold * threshold;
    Vector3 separationVelocity = Vector3.Zero;
    for (int i = 0; i < enemies.Length; i++) {
        if (enemies[i] == this) {
            continue;
        }
        Vector3 direction = this.position - enemies[i].position;
        float distance = direction.LengthSquared();
        float strenght = 0.0f;
        if (distance < (threshold)) {
            strenght = Math.Min(decayCoefficient / distance, this.maxAccel);
            direction.Normalize();
            separationVelocity += strenght * direction;
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.