2 डी में कॉर्नर टकराव से कैसे निपटें?


22

मैं नीचे 2d XNA गेम लिख रहा हूं। इसके पहले से मैं इसे सीखने के लिए भौतिक विज्ञान और टकराव सामग्री को लिखने की कोशिश कर रहा हूं।

जब भी मेरा खिलाड़ी चरित्र को एक ऐसी स्थिति में ले जाने का प्रयास करता है, जहां उसकी सीमा एक दीवार के किनारे से टकराती है, तो मैं बाउंस कोण (घटना का कोण = प्रतिबिंब का कोण) का पता लगाता हूं और मैं खिलाड़ी को दीवार से उछाल देता हूं और टकराव से बचता हूं ।

मुझे यह पता लगाने में कठिनाई हो रही है कि एक साथ दो दीवार किनारों के साथ मेरे स्प्राइट इंटरसेक्टिंग की स्थिति से कैसे निपटें, जैसे कि यह एक कोने से टकराता है।

टक्कर

मेरा कोड वर्तमान में मुझे बताता है कि दो दीवार किनारों को काट दिया गया है लेकिन यह किस किनारे पर पहले नहीं मारा गया है और इसलिए किस किनारे से उछलना है।

किस बढ़त को उछालने वाला गणितीय परीक्षण है? इसे देखने पर यह स्पष्ट है लेकिन मैं इसके लिए गणित की परीक्षा का पता लगाने के लिए संघर्ष कर रहा हूं।



धन्यवाद टेट्राद। मैंने देखा कि एक लेकिन ऐसा लग रहा था कि गेंद मेरी आयताकार समस्या के लिए अलग तरह से व्यवहार करेगी। आयताकार स्प्राइट के ऊपर चित्रित मामले में दीवार के निचले किनारे से टकराकर उसे उछाल दिया जाता था। दीवार के किनारे किनारे कभी समीकरण में नहीं आए होंगे। मुझे अभी पता नहीं है कि उस कोड को कैसे व्यक्त करें और वह निर्णय लें।
टेरीबी

जवाबों:


9

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

इसलिए, उदाहरण के लिए, यदि आप अपने आरेख को देखते हैं। (चाल के बाद) xके ऊपरी बाएँ कोने का मान लें Player Sprite, और xनीचे दाएं कोने का मान घटाएँ Wallyमूल्यों के लिए एक ही काम करें और फिर देखें कि कौन सा बड़ा है। कुंजी यह है कि यदि कोई दूसरे से बड़ा है, तो Player Spriteसंभवत: उस तरफ को लगाया गया है।

यहाँ एक छवि उदाहरण है (यह मेरी अपनी पंक्तियों के साथ आपकी छवि का एक उपधारा है):

चौराहे का उदाहरण

अब, आप यहाँ देखते हैं कि ब्लू लाइन ग्रीन लाइन से बड़ी है। इस मामले में नीली रेखा भी उस तरफ है, जिसके Player Spriteबंद होने की उम्मीद होगी।

यदि दो मूल्य समान हैं, तो वे कोने पर सही मारते हैं।

अब, इस तरह से इसे करने में थोड़ी समस्या है। यदि Player Spriteयात्रा बहुत तेजी से हो रही है या टक्कर कोने के बहुत करीब है, तो संभव है कि यह गलत दिशा में Player Spriteआगे बढ़ सकता है Wall। उस स्थिति में आपको संभवतः चलती हुई वस्तु के वेग की जाँच करनी होगी। (देखें नाथन रीड का जवाब ।)

नोट: मुझे लगता है कि मैं मूल रूप से SAT टकराव का पता लगाने की कोशिश कर रहा हूँ, जिसका @Blau ने उल्लेख किया है, लेकिन मैंने इसे लिखने में एक लंबा समय बिताया है, इसलिए मैं इसे पोस्ट करने जा रहा हूँ। उम्मीद है कि यह आपकी कुछ मदद करेगा।


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

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

फिर, जब आप जानते हैं कि यह इसके पास है, तो आप यह देखने के लिए अधिक महंगी गणना कर सकते हैं कि क्या वे कोणों पर प्रतिच्छेद करते हैं (जो कि संभवतः एक और प्रश्न होना चाहिए :))।
रिचर्ड मार्स्केल - Drackir

1
-1 चूंकि न्यूनतम विस्थापन हमेशा "कौन सा किनारा पहले टकरा गया" इसका सही जवाब नहीं देता है; मेरा जवाब देखिए।
नाथन रीड

@NathanReed - यही कारण है कि मैंने अपने "अब, इस तरह से" पैराग्राफ को करने में थोड़ी परेशानी है।
रिचर्ड मार्सेल - Drackir

15

न्यूनतम विस्थापन हमेशा सही जवाब नहीं देता है कि किस बढ़त के लिए पहले मारा गया था। इस मामले पर विचार करें:

मामला जो सबसे कम विस्थापन एल्गोरिथ्म को तोड़ता है

यह तब होता है जब वेग इतना अधिक होता है कि ब्लॉक एक फ्रेम के दौरान बहुत दूर तक चला जाता है। सही ढंग से पता लगाने के लिए कि कौन सा किनारा पहले मारा गया था, आपको प्रत्येक किनारे के साथ टकराव के समय को हल करने के लिए एक रेखीय समीकरण स्थापित करना होगा। ओपी के आरेख में वर्णित इस मामले में, प्रासंगिक समीकरण हैं:

timeXCollision = (player.left - wall.right) / -player.velocity.x
timeYCollision = (wall.bottom - player.top) / player.velocity.y

(यह एक एक्स-राइट, वाई-अप समन्वय प्रणाली मान रहा है।) सामान्य तौर पर, आपको यह निर्धारित करने के लिए खिलाड़ी के संकेतों का उपयोग करना होगा। गति के X और Y घटकों को यह निर्धारित करने के लिए कि किन किनारों की जोड़ी को जांचने की आवश्यकता है। वैसे भी, जब आपके पास टक्कर के समय की गणना होती है, तो दोनों में से पहले वह टक्कर होती है जिसे आपको संभालने की आवश्यकता होती है।


1
क्या आप एक उदाहरण प्रदान कर सकते हैं कि आपके दो चर कैसे लागू किए जा सकते हैं?
BjarkeCK

1

आपको SAT Collision Detection की आवश्यकता है

मूल रूप से आपको न्यूनतम विस्थापन वेक्टर की तलाश करने की आवश्यकता होती है जो किसी एक वस्तु के संपर्क में नहीं आती है।

आपकी छवि में न्यूनतम विस्थापन नारंगी खंड है।

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


4
-1 चूंकि न्यूनतम विस्थापन हमेशा "कौन सा किनारा पहले टकरा गया" इसका सही जवाब नहीं देता है; मेरा जवाब देखिए।
नाथन रीड

कौन पूछ रहा है?
Blau

सवाल वही पूछ रहा है। "मेरा कोड वर्तमान में मुझे बताता है कि दो दीवार किनारों को काट दिया गया है लेकिन यह किस किनारे पर पहले नहीं मारा जाएगा और इसलिए किस किनारे को काटने के लिए है।"
नाथन रीड

प्रथम? समस्या यह नहीं है कि पहले क्या है, यह एक ही समय में दो किनारों से टकराता है, ... मामला यह है कि किस किनारे से उछाल है, आपने एक तरीका चुना है जो आपके लिए अच्छा है, मैंने एक तरीका चुना है जो है मेरे लिए अच्छा है, दोनों वैध हैं
ब्लौ

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

0

यहां एक ऐसे ही सवाल का जवाब दिया

आप पिछली स्थितियों की जाँच करने पर विचार कर सकते हैं-

उदाहरण के लिए: यदि आपका बायाँ भाग पहले उनकी दाईं ओर था और आप टकरा रहे हैं, तो दाहिने हाथ की टक्कर हुई है।

यदि आप ऐसा करते हैं, तो बस y अक्ष टकराव को हल करें, जांचें कि क्या आप किसी चीज से टकरा रहे हैं, तो x अक्ष टकराव को हल करें।

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