मैं अपने प्लेटफ़ॉर्मर के चरित्र को दीवार की टाइलों पर चढ़ने से कैसे रोकूँ?


9

वर्तमान में, मेरे पास इलाके के लिए टाइल्स वाला एक प्लेटफ़ॉर्मर है (गुफा कहानी से उधार लिया गया ग्राफिक्स)। खेल को XNA का उपयोग करते हुए खरोंच से लिखा गया है, इसलिए मैं एक मौजूदा इंजन या भौतिकी इंजन का उपयोग नहीं कर रहा हूं।

इस उत्तर में वर्णित (सरल आयत के लिए आयताकार और वृत्त) के साथ टाइल की टकरावों को बहुत सटीक रूप से वर्णित किया गया है , और सब कुछ ठीक काम करता है।

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

चरित्र को पकड़ने की छवि

इस स्क्रीनशॉट में, खिलाड़ी दाईं ओर घूम रहा है और नीचे की ओर गिर रहा है। इसलिए आंदोलन के बाद, टकरावों की जांच की जाती है - और सबसे पहले, यह पता चलता है कि खिलाड़ी का चरित्र फर्श से टाइल 3 से टकरा रहा है, और आगे की ओर धकेल दिया गया है। दूसरा, वह उसके बगल वाली टाइल से टकराता हुआ पाया गया, और बग़ल में धकेल दिया गया - अंतिम परिणाम खिलाड़ी के चरित्र के बारे में सोचता है कि वह जमीन पर है और गिर नहीं रहा है, और जब तक वह उसमें चल रहा है, तब तक टाइल पर 'पकड़ता' है। ।

मैं इसके बजाय ऊपर से नीचे तक टाइलों को परिभाषित करके इसे हल कर सकता था, जिससे वह आसानी से गिर जाता है, लेकिन फिर उलटा मामला होता है और वह छत से टकराएगा जो दीवार के खिलाफ ऊपर की ओर कूदने पर नहीं होता है।

मुझे इसे हल करने के लिए कैसे दृष्टिकोण करना चाहिए, ताकि खिलाड़ी का चरित्र सिर्फ दीवार के साथ गिर सकता है जैसा कि इसे करना चाहिए?


इस सवाल के समान? gamedev.stackexchange.com/questions/14486/...
MichaelHouse

@ बाइट 56 सवाल ही नहीं है, लेकिन इसका जवाब मदद कर सकता है।
doppelgreener

एक नोट: मेरे पास पिछले कुछ हफ्तों में जवाबों के साथ प्रयोग करने के लिए बहुत कम समय है। मैंने विश्व टकराव संकल्प को लागू किया है जैसा कि प्रश्न @ बाइट 56 से जुड़ा हुआ है, जिसमें उच्च वेग पर अलग-अलग कीड़े हैं, और अभी तक इस प्रश्न के उत्तर की कोशिश नहीं कर पाए हैं। मैं उन लोगों की कोशिश करूंगा जब मैं कर सकता हूं या तो एक उत्तर को स्वीकार कर सकता हूं जब मैं खुद को हल कर सकता हूं या खुद को पोस्ट कर सकता हूं।
doppelgreener

जवाबों:


8

सबसे सरल, अधिक असफल-प्रूफ दृष्टिकोण केवल छिपे हुए किनारों पर टकराव की जांच नहीं करना है। यदि आपके पास दो दीवार टाइलें हैं, तो सीधे एक के ऊपर एक, तो ऊपरी टाइल के निचले किनारे और निचली टाइल के ऊपरी किनारे को खिलाड़ी के खिलाफ टक्कर के लिए नहीं जांचना चाहिए।

आप यह निर्धारित कर सकते हैं कि टाइल के नक्शे पर एक साधारण पास के दौरान कौन से किनारे वैध हैं, प्रत्येक टाइल स्थान पर झंडे के रूप में बाहरी किनारों को संग्रहीत करना। आप इसे केवल रनटाइम डिटेक्शन के दौरान आसन्न टाइल्स की जाँच करके भी कर सकते हैं।

इस तकनीक के अधिक उन्नत संस्करण हैं जो गैर-वर्ग टाइलों के साथ-साथ समर्थन करने के लिए इसे आसान और तेज़ बनाते हैं।

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

http://www.metanetsoftware.com/technique/tutorialA.html http://www.metanetsoftware.com/technique/tutorialB.html


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

हाँ, बस एक आयत-लाइन टक्कर करें। केवल सरलीकृत क्योंकि रेखा हमेशा अक्ष-संरेखित होती है। आप बस अपने बॉक्स-बॉक्स चेक को विघटित कर सकते हैं।
सीन मिडलिचच

5

यहाँ आदेश मैं बातें करना होगा ...।

1) चरित्र के वर्तमान एक्स, वाई सहेजें

2) एक्स दिशा स्थानांतरित करें

3) टाइल डेटा प्राप्त करके चरित्र के सभी कोने की जांच करें और जांचें कि क्या यह निम्न करके ठोस है: (एक्स और वाई चरित्र तथ्य है)

  • शीर्ष बाएं के लिए: फर्श (एक्स / टाइलविदथ), फर्श (वाई / टाइलहाइट);
  • शीर्ष दाईं ओर: मंजिल ((X + characterWidth) / टाइलवाइट), फर्श (Y / टाइलहाइट);
  • नीचे बाईं ओर: फर्श (X + / टाइलवार्ड), फर्श ((Y + characterHeight) / टाइलहाइट);
  • नीचे के दाईं ओर: मंजिल ((X + characterWidth) / टाइलवार्ड), फर्श ((Y + characterHeight) / टाइलहाइट);

... मैप डेटा से सही टाइल डेटा प्राप्त करने के लिए

4) यदि कोई भी टाइल ठोस है, तो आपको X को सहेजने के लिए X को सर्वोत्तम स्थिति में लाने के लिए मजबूर करने की आवश्यकता है और ...

  • यदि आप जहां बाएं घूम रहे हैं: X = फर्श (X / टाइलवीड्थ) * टाइलविद;
  • अगर आप सही तरीके से आगे बढ़ रहे हैं: X = (((X + characterWidth) / टाइल की चौड़ाई) + 1) * टाइल की चौड़ाई) - characterWidth;

5) Y का उपयोग करके 2-4 दोहराएं

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

int characterBlockHeight = 3;

// check all tiles and intermediate tiles down the character body
for (int y = 0; y < characterBlockHeight - 1; y++) {
    tile = getTile(floor(characterX / tileWidth), floor((characterY + (y * tileHeight)) / tileHeight));
    ... check tile OK....
}

// finally check bottom
tile = getTile(floor(characterX / tileWidth), floor((characterY + characterHeight) / tileHeight);
... check tile OK....

यदि चरित्र 1 ब्लॉक से अधिक चौड़ा है, तो ऐसा ही करें, लेकिन characterX, characterWidth, आदि के साथ characterY, characterHeight, टाइलहाइट आदि को बदलें।


2

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


1

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

आपके उदाहरण में, x- अक्ष टकराव का क्षेत्र y- अक्ष से अधिक होगा, इसलिए इसे पहले संभाला जाएगा। फिर y- अक्ष टक्कर को संभालने का प्रयास करने से पहले, यह जाँच करेगा और देखेगा कि यह x- अक्ष पर ले जाने के बाद टकरा नहीं रहा है। :)


1

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


1

इस ट्यूटोरियल में एक समान समस्या को कवर किया गया था: गेम डेवलपमेंट का परिचय । वीडियो का प्रासंगिक भाग 1:44 पर है , आरेख और कोड स्निपेट के साथ समझाता है।

नोटिस 14-tilemap.py क्लिपिंग समस्या प्रदर्शित करता है, लेकिन यह 15-blocker-sides.py में तय किया गया है

मैं बिल्कुल नहीं समझा सकता कि अंतिम ट्यूटोरियल उदाहरण आपके कोड के होने पर क्लिप क्यों नहीं करता है, लेकिन मुझे लगता है कि इसके साथ कुछ करना है:

  • टाइल के प्रकार के आधार पर सशर्त टकराव की प्रतिक्रिया (जो किनारों वास्तव में सक्रिय हैं।)
  • खिलाड़ी हमेशा 'गिर रहा है।' हालाँकि खिलाड़ी एक टाइल पर आराम करता दिख रहा है, खिलाड़ी वास्तव में बार-बार टाइल के माध्यम से गिर रहा है, फिर वापस शीर्ष पर धकेल दिया जा रहा है। ( self.restingकोड में सदस्य का उपयोग केवल यह जांचने के लिए किया जाता है कि क्या खिलाड़ी कूद सकता है। इसके बावजूद मुझे खिलाड़ी को एक दीवार से 'डबल' कूदने के लिए नहीं मिल सकता है। सैद्धांतिक रूप से यह संभव हो सकता है, हालांकि)

0

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

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


0

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

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