ट्रैक्टर के पेड़ / ग्रिड आधारित टक्कर - तर्क को कार्रवाई में डालते हुए


13

सबसे पहले, मैं केवल थोड़ी देर के लिए अपना गेम तर्क लिख रहा हूं, इसलिए मैं माफी मांगता हूं अगर यह सीधे आगे लग सकता है।

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

मेरे सिर में कब्ज़ेदार तरीके हैं, लेकिन मुझे यकीन नहीं है कि सबसे अच्छा है

सामान्य टक्कर परीक्षण - कोई अनुकूलन नहीं

for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.collidesWith(objectB){

               //handle collision logic
              }
        }

पड़ोसियों को स्टोर करें (विधि 1) लेकिन क्या होगा यदि हम टकरावों का अनुकूलन केवल उन वस्तुओं की जांच करना चाहते हैं जो पास हैं। क्या हम अभी भी सभी वस्तुओं के माध्यम से भागते हैं, या क्या हम पास की वस्तुओं के साथ एक सरणी बनाकर जांच करते हैं?

var objects:Array = new Array();
    var neighbours:Array = new Array();

    for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.isNear(objectB){

               neighbours.push(objectA, objectB);
              }
        }

    }

    //somewhere else
    for(i:int = 0; i < neighbours.length; i++){
        //only check neighbours

        for(j:int = i + 1; j < neighbours.length; j++){

            if(objectA.collidesWith(objectB){

               //handle collision logic
              }
        }
    }

सभी ऑब्जेक्ट्स को लूप करें लेकिन टक्कर के लिए केवल पड़ोसियों की जांच करें (विधि 3) अन्य ऑक्यूबिलिटी यह है कि हम अभी भी सब कुछ के माध्यम से लूप करते हैं लेकिन टकराव का परीक्षण करने से पहले ऑब्जेक्ट्स पास हैं या नहीं इसकी जांच करें।

for(var i:int = 0; i < objects.length; i++){
        //find object A
        var objectA = objects[i];

        for(var j:int = i + 1; j < objects.length; j++){
            //find object B
            var objectB = objects[j];

            if(objectA.isNear(objectB){
               //they are near - check collision!
               if(objectA.collidesWith(objectB){

               //handle collision logic
              }
            }
        }

    }

टाइल डेटा (विधि 3) में वस्तुओं को स्टोर करें टाइल आधारित साइटम का उपयोग करके दूसरे विकल्प के लिए अनुमति दें; उन वस्तुओं को संग्रहीत करें जो टाइल डेटा में एक विशिष्ट टाइल पर हैं। यह देखने के लिए जांचें कि ऑब्जेक्ट किस टाइल पर है आसपास की टाइलों में ऐसी कोई भी वस्तु है जिसके साथ टकरा सकती है:

var ObjectA;

for(var i:int = 0; i < 4; i ++){
//check 4 surrounding tiles from object A

   if(Object.currentTile + surroundingTile[i] CONTAINS collidable object){
   //check collision!
    if(objectA.collidesWith(surroundingTile.object){

    //handle collision logic
     }

}
}

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

यह एक तुलनात्मक तुलना नहीं है क्योंकि टकराव की जाँच में आइटम लगातार आगे बढ़ रहे हैं ताकि ऑर्डर मिश्रित हो जाए। वह मुझे भ्रमित कर रहा है।

क्या प्रत्येक आइटम की जांच करना अधिक कुशल होगा, इस प्रकार पड़ोसियों की एक सरणी उत्पन्न करने के तनाव को दूर करना होगा।

या क्या पड़ोसी को खोजने के लिए यह अधिक कुशल है कि टकराव की जांच करने के लिए कई वस्तुओं के माध्यम से लूप न हो?

प्रत्येक टाइल पर डेटा को बदलते रहें बहुत ही गहन अस्वस्थ लगता है, इसलिए मुझे यकीन नहीं है कि अगर यह एक अच्छा विचार है ..

मैं एक टॉवर रक्षा खेल के बारे में सोच रहा हूँ जहाँ टॉवर को वस्तुओं का पता लगाने की आवश्यकता होती है यदि ऑब्जेक्ट उस पर गोली मारने से पहले सीमा में हैं। और यह सिर्फ मूर्खतापूर्ण लगता है कि सभी वस्तुओं की जांच करें जबकि कुछ समय में कोई भी वस्तु बिल्कुल भी पास नहीं होगी।

मैं लंबी पोस्ट के लिए माफी माँगता हूँ, हमेशा खुद को समझाने में परेशानी होती है!


यह कौनसी भाषा है? जावास्क्रिप्ट?
काइल सी

2
Actionscript 3, लेकिन भाषा बहुत ही अप्रासंगिक है। बस यह पता लगाने का सबसे अच्छा तरीका क्या है और इस संरचना को बनाना चाहते हैं :)
omgnoseat

जवाबों:


8

आपको वास्तविक टकराव की जांच की संख्या को कम करने की आवश्यकता है। हाँ स्पष्ट मुझे पता है। तो इस पर विस्तार से बताए:

बिना किसी अनुकूलन के आपका पहला टक्कर चेक एल्गोरिथम: एक बार में कितने चेक करेगा? यदि n ऑब्जेक्ट्स की गिनती है, तो यह n * (n-1) चेक के आसपास होगा। बहुत सी वस्तुओं (> 100) के लिए यह बहुत धीमी गति से होगा।

आपकी पड़ोसी जाँच विधि अधिक तेज़ नहीं होगी। यदि आपकी वस्तुएं स्थिर नहीं हैं और बहुत अधिक घूमती हैं, तो आपको अपने गेम लूप में प्रत्येक वस्तु के लिए इन पड़ोसियों की सूची बनाने की आवश्यकता होगी। पड़ोसी सूची बनाने के लिए n * (n-1) करने के बाद से यह वास्तव में पहले एल्गोरिथ्म से भी बदतर है और अगर यह उसके किसी पड़ोसी से टकराता है तो प्रत्येक वस्तु की जांच करें।

आपको अपने खेल स्थान को विभाजित करने की आवश्यकता है। कहते हैं कि आपका खेल स्थान 400x400 पिक्सेल चौड़ा है। आप इसे प्रत्येक 200x200 में 4 उप-स्थान में विभाजित कर सकते हैं और प्रत्येक वस्तु की जांच कर सकते हैं कि यह किस उप-स्थान में है (एक वस्तु एक से अधिक उप-अंतरिक्ष के अंदर हो सकती है)। तब आपको केवल यह जांचने की आवश्यकता होगी कि क्या प्रत्येक उप-स्थान की वस्तुएं एक ही उप-स्थान में अन्य वस्तु से टकराती हैं।

तो रनटाइम लागत होगी: n 4 उप-अंतरिक्ष सूची + (n / 4) * ((n-1) / 4) के निर्माण के लिए जो पिछले रनटाइम लागत से बहुत बेहतर है। उप-रिक्त स्थान को छोटा करके (उदाहरण 50x50) को घटाकर इसे और कम किया जा सकता है।

तो हमारा एल्गोरिथ्म अब कुछ इस तरह दिखता है:

for each (object in objects)
  check into which subspace the object belongs

for each (subspace in subspaces)
  for each (object in subspace)
    check object for collision with other objects in same subspace

यह कुछ हद तक आपके टाइल डेटा विचार के समान है। लेकिन सब-स्पेस को टाइल्स के समान आकार की आवश्यकता नहीं है।

हम आगे एक quadtree का उपयोग कर इसे अनुकूलित करने के लिए एक अंतिम चरण कर सकते हैं। आज्ञा देना k की उपप्रजातियों की गिनती। यदि आप अपने खेल की दुनिया में बड़े हो जाते हैं, तो हमारे द्वारा k * n चेक किए जा रहे रिक्त स्थान ऑब्जेक्ट सूचियों का निर्माण करने के लिए।

इस लागत को कम करने के लिए हम एक क्वाडट्री का उपयोग करते हैं। एक क्वाडट्री हमारे गेम स्पेस को विभाजित करने का एक और तरीका है। हमारे 400x400 स्थान को 64 50x50 उप-भागों में विभाजित करने और प्रत्येक वस्तु की जाँच करने के बजाय, जिसमें वर्तमान में 64 उप-स्थान हैं, खेल स्थान को 4 उप-भागों में विभाजित किया गया है जो खेल स्थान (200x200) के आधे आकार में विभाजित होता है, जो बदले में विभाजित होते हैं छोटे उप-स्थान (100x100), जो बदले में फिर से 50x50 उप-भागों में विभाजित होते हैं। यह हमारी चौहद्दी है।

अब यदि हम यह जानना चाहते हैं कि किस वस्तु का ५०x५० उप-भाग है तो हम इसकी जांच करते हैं कि यह २००x२०० में से किस उप-स्थान से संबंधित है। फिर हम अपने क्वाडट्री में एक स्तर को गहराई तक जाते हैं और उन 4 100x100 सबस्पेस के खिलाफ जांचते हैं जो 200x200 उप-क्षेत्र के अंदर हैं जो हमने अभी पाया है। यह तब तक दोहराया जाता है जब तक हमें पता नहीं हो जाता है कि किस वस्तु का 50x50 उप-वर्ग है। तो अब कितने चेक जरूरी थे? क्वाडट्री के प्रत्येक स्तर के लिए 4 (याद रखें कि एक वस्तु दो उप-भागों के किनारे पर हो सकती है)। इसलिए हमें सही 50x50 उप-स्थान पर ऑब्जेक्ट असाइन करने के लिए 4 * 3 चेक चाहिए। 64 जाँचों से बहुत बेहतर।

तो हमारे quadtree एल्गोरिथ्म को सबसपेस सूचियों के निर्माण के लिए 4 * 3 * n चेक की आवश्यकता होती है और फिर प्रत्येक वस्तु के टकराव की जांच के लिए k * (n / k) चेक की तरह कुछ होता है।


यह एक बहुत स्पष्ट और समझने योग्य awnser है, बहुत बहुत धन्यवाद! यह कैसे नियंत्रित किया जाता है कि एक वस्तु किस उप-क्षेत्र पर है? क्या उप-वस्तु को एक वस्तु के रूप में संभाला जाता है, जहां उस पर मौजूद वस्तु को सरण के रूप में सहेजा जाता है और एक-दूसरे के खिलाफ जांच की जाती है? या आप मुख्य लूप के अंदर एक्स और वाई की जांच करके सिर्फ किस उप-स्थान पर हैं? निर्माण और बदलते सरणियों की तरह लगता है हर समय बहुत अक्षम है। इसलिए मैं यह सुनिश्चित करना चाहता हूं कि मैं उपयुक्त विधि का उपयोग करूं :) मैं एक समस्या भी देख सकता हूं जब ऑब्जेक्ट आकार में भिन्न हो रहे हों। मुझे लगता है कि सबसे छोटी उप-भूमि सबसे बड़ी वस्तु जितनी बड़ी होनी चाहिए?
omgnoseat

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

धन्यवाद, भूल गए कि हम वास्तविक वस्तुओं के बीच टकराव की जाँच भी करेंगे सबसे छोटी उप-भूमि में, यह समझ में आता है कि यह अब कई वस्तुओं को रखने में सक्षम होना चाहिए। मैंने एक परीक्षण शुरू कर दिया है और यह अच्छी तरह से आ रहा है। मुझे जो सबसे बड़ी परेशानी हो रही है, वह यह पता लगा रही है कि कौन सी वस्तु किसी वस्तु की है। मैं subspaces childs X और Y मानों के माध्यम से लूपिंग करता रहता हूं, क्या यह एक उचित पद्धति है?
omgnoseat

आप उन वस्तुओं को कैसे संभालते हैं जो एक से अधिक उप-श्रेणियों में विस्तारित होती हैं (अर्थात जिसका स्थान सीमा पर या निकट है)?
मुगिक्स

सरल: मैं नहीं। यदि वे प्रत्येक उप-सीमा की सीमा पर हैं, तो वस्तुएँ कई उप-भागों का हिस्सा हो सकती हैं। तो एक वस्तु अधिकतम 4 उप-भागों का हिस्सा हो सकती है। लेकिन यह अल्पसंख्यक है।
स्टीफन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.