टकराव आयत प्रतिक्रिया


10

मुझे एक आयत को एक से अधिक आयतों से टकराने में कठिनाई हो रही है।

मैं एसएफएमएल का उपयोग कर रहा हूं और इसका एक आसान कार्य है, जिसे intersects2 आयत लगते हैं और चौराहों को वापस करते हैं। मेरे पास आयतों से भरा एक वेक्टर है जिसे मैं चाहता हूं कि मेरी जंगम आयत टकरा जाए। मैं निम्नलिखित कोड का उपयोग करके इसके माध्यम से लूप कर रहा हूं (p गतिपूर्ण आयत है)।

IsCollidingWithintersectsचौराहों पर काम करने के लिए एसएफएमएल का उपयोग करने के लिए एक बूल लौटाता है ।

while(unsigned i = 0; i!= testRects.size(); i++){
   if(p.IsCollidingWith(testRects[i]){
        p.Collide(testRects[i]);
   }
}

और वास्तविक Collide()कोड:

void gameObj::collide( gameObj collidingObject ){

 printf("%f %f\n", this->colliderResult.width, this->colliderResult.height);

if (this->colliderResult.width < this->colliderResult.height) {
    // collided on X
    if (this->getCollider().left < collidingObject.getCollider().left ) {
        this->move( -this->colliderResult.width , 0);
    }else {
        this->move( this->colliderResult.width, 0 );
    }

}

if(this->colliderResult.width > this->colliderResult.height){
    if (this->getCollider().top < collidingObject.getCollider().top ) {
        this->move( 0, -this->colliderResult.height);
    }else {     
        this->move( 0, this->colliderResult.height );
    }

}

और IsCollidingWith()कोड है:

bool gameObj::isCollidingWith( gameObj testObject ){
if (this->getCollider().intersects( testObject.getCollider(), this->colliderResult )) {
    return true;
}else {
    return false;
}

यह ठीक है जब Rectदृश्य में केवल 1 है। हालाँकि, जब एक से अधिक बार Rectयह एक समस्या का कारण बनता है जब 2 टकरावों को एक बार में पूरा किया जाता है।

किसी भी विचार कैसे इस के साथ सही ढंग से निपटने के लिए? मैंने अपनी समस्या दिखाने के लिए youtube पर एक वीडियो अपलोड किया है। दूर-दाईं ओर कंसोल चौराहों की चौड़ाई और ऊंचाई को दर्शाता है। आप कंसोल पर देख सकते हैं कि यह एक साथ 2 टकरावों की गणना करने की कोशिश कर रहा है, मुझे लगता है कि यह वह जगह है जहां समस्या पैदा हो रही है।

अंत में, नीचे दी गई छवि मेरी समस्या को अच्छी तरह से समझाती है:

आयत कई अन्य आयतों से टकराती है


वीडियो लिंक टूट गया है।
जिओचुआन यू

क्या colliderवस्तुओं को this->getCollider()अपडेट करके लौटाया जाता है this->move()??
XiaoChuan यू

क्या आप कृपया कुछ और जानकारी जोड़ सकते हैं? वास्तव में समस्या क्या है? YouTube वीडियो पूर्वानुमानित व्यवहार दिखाता है, और दृश्य में केवल एक अन्य आयत है।
वाकीदेव

जवाबों:


3

आपकी छवि कई समस्याओं में से एक को उत्तल आकृतियों का उपयोग करने की कोशिश के साथ दर्शाती है - विशेष रूप से आयताकार - एक फर्श की तरह एक सपाट सतह का अनुकरण करने के लिए। एल्गोरिथ्म पात्रों को फर्श बनाने वाले आकृतियों के अंदरूनी किनारों पर अटक जाता है।

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

और भी सरल हो सकता है - और अधिक प्रदर्शन करने वाला - इसके बजाय अपनी दुनिया के लिए किनारों की एक सूची तैयार करना है। यही है, अपने बक्से को फर्श बनाने के लिए, एक ध्वज सेट करें जो दर्शाता है कि केवल उनका शीर्ष किनारा वास्तव में टकरा रहा है, और फिर अन्य किनारों के साथ टकराव को अनदेखा करें। आप इसके लिए एसएफएमएल की टक्कर की दिनचर्या का उपयोग नहीं कर पाएंगे, लेकिन ईमानदारी से बस बॉक्स टक्कर संभवतः सबसे आसान बिट कोड है जिसे आप कभी भी गेम में लिखेंगे। यह तकनीक विशेष रूप से अच्छी तरह से काम करती है अगर आपकी दुनिया ग्रिड से जुड़ी हो। मैं उस तकनीक के लिए उत्कृष्ट मेटानेट ट्यूटोरियल (http://www.metanetsoftware.com/technique.html/) की जांच करूंगा।

आप कई अन्य समस्याओं में भाग लेने जा रहे हैं जैसे आप एक सरल 2D platformer गेम बनाने की कोशिश कर रहे हैं। अब तक, मैंने जो सबसे अच्छा संसाधन देखा है, वह निम्नलिखित है, जिसे आपको पढ़ना चाहिए, और फिर दोबारा पढ़ना चाहिए:

http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/


1

हो सकता है कि एक सरल समाधान हर आयत के साथ टकराव की जांच करना और आंदोलन की विपरीत दिशा में वापस जाना हो, जब तक कि कोई टक्कर का पता न चले। यदि यह समस्या हल करती है, तो कार्यान्वयन काफी सरल होना चाहिए।


+1, मैंने वास्तव में इसके बारे में यहां लिखा है: gamedev.stackexchange.com/questions/38252/…
मार्कस वॉन ब्रॉडी

0

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

आशा है कि सहायक है?


0

यह वास्तव में एक इष्टतम तरीका नहीं है, आपको जल्द से जल्द समय निर्धारित करने की कोशिश करनी चाहिए जब या पहले ऑब्जेक्ट के साथ चलती वस्तु पथ जहां टकराव होता है और वस्तुओं को उस स्थिति (या परिकलित समय पर स्थिति) में ले जाने का प्रयास करता है, आंदोलन के बाद मर्मज्ञ पदों के आधार पर सही बहुत समस्याग्रस्त है, लेकिन आप अपनी वर्तमान प्रक्रिया का उपयोग एक छोटे से बदलाव के साथ कर सकते हैं। बस टकराव की जाँच करते रहें जब तक कि कोई न हो।

bool collided = true;
while(collided) {
   collided = false
   while(unsigned i = 0; i!= testRects.size(); i++){
      if(p.IsCollidingWith(testRects[i]){
         collided = true
         p.Collide(testRects[i]);
      }
   }
}

ध्यान दें कि ऐसी परिस्थितियाँ हैं जहाँ यह एक अनंत लूप का कारण बनेगी (ऐसी स्थिति के बारे में सोचें जहाँ टकराव से बॉक्स को बाहर निकालने से दूसरे संग्रह में परिणाम हो और उस टक्कर से बॉक्स को हिलाने से यह पहले की तरह टकराकर वापस आ जाए)

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