एकता - 2 डी टॉप-डाउन गेम में एक जहाज को वास्तविक रूप से एक बिंदु पर कैसे स्थानांतरित किया जाए


14

मैं एक नौकायन जहाज को उस स्थान पर ले जाने की कोशिश कर रहा हूँ जहाँ मैंने माउस से क्लिक किया था। यह गति यथार्थवादी होनी चाहिए (जहां जहाज पीछे घूमता है) पर अगर माउस क्लिक बाकी है और जहाज के सामने जहाज को आगे की ओर एक घुमावदार मार्ग के साथ घूमना चाहिए ताकि सही घुमाव हो सके

मुझे खुशी होगी अगर कोई मुझे इस मुद्दे पर धन्यवाद देने में मदद कर सके जहाज की चाल


1
जैसा कि आपकी छवि पाल को दर्शाती है: क्या हवा को ध्यान में रखा जाना चाहिए? कुछ युद्धाभ्यास गलत हवा या इसके अभाव के साथ करना असंभव है।
कोई नहीं

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

Usualy एक "गोटो पॉइंट" को रोटेशन चरण और आगे के आंदोलन चरण में विभाजित किया जा सकता है। एक ही aproach ले लो लेकिन रोटेशन के लिए एक आगे आंदोलन थोपना। उदाहरण के रोटेशन के प्रत्येक एक्स रेड, नाव को y मीटर से आगे बढ़ाते हैं
dnk drone.vs.drones

जवाबों:


7

इस पेज को देखें

यथार्थवादी मोड़ जोड़ना

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

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

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

चित्रा 5 में सबसे छोटा मार्ग स्पष्ट रूप से नीचे की ओर हरी रेखा है। चित्रा 6 में चित्रित कुछ ज्यामितीय संबंधों के कारण गणना करने के लिए यह मार्ग काफी सीधा है।

चित्र 6: पथ की लंबाई की गणना करना।

पहले हम बिंदु P के स्थान की गणना करते हैं, जो हमारे मोड़ का केंद्र है, और हमेशा शुरुआती बिंदु से दूर त्रिज्या है। यदि हम अपनी प्रारंभिक दिशा से दाहिनी ओर मुड़ रहे हैं, तो इसका मतलब है कि P मूल से (initial_direction - 90) के कोण पर है, इसलिए:

angleToP = initial_direction - 90
P.x = Origin.x + r * cos(angleToP)
P.y = Origin.y + r * sin(angleToP)

अब जब हम केंद्र बिंदु P का स्थान जानते हैं, तो हम P से गंतव्य तक की दूरी की गणना कर सकते हैं, जिसे चित्र पर h के रूप में दिखाया गया है:

dx = Destination.x - P.x
dy = Destination.y - P.y
h = sqrt(dx*dx + dy*dy)

इस बिंदु पर हम यह भी जांचना चाहते हैं कि गंतव्य सर्कल के भीतर तो नहीं है, क्योंकि अगर यह होता तो हम कभी भी इस तक नहीं पहुँच पाते:

if (h < r)
    return false

अब हम खंड d की लंबाई की गणना कर सकते हैं, क्योंकि हम पहले से ही सही त्रिकोण के अन्य दो पक्षों की लंबाई जानते हैं, अर्थात् एच और आर। हम समकोण त्रिभुज संबंध से कोण भी निर्धारित कर सकते हैं:

d = sqrt(h*h - r*r)
theta = arccos(r / h)

अंत में, उस बिंदु Q का पता लगाने के लिए जिस पर वृत्त को छोड़ना और सीधी रेखा पर शुरू करना है, हमें कुल कोण + जानना होगा, और आसानी से P से गंतव्य तक के कोण के रूप में निर्धारित किया जाता है:

phi = arctan(dy / dx) [offset to the correct quadrant]
Q.x = P.x + r * cos(phi + theta)
Q.y = P.y + r * sin(phi + theta)

उपरोक्त गणना सही-मोड़ वाले मार्ग का प्रतिनिधित्व करती है। बाएं हाथ के पथ की गणना ठीक उसी तरह से की जा सकती है, सिवाय इसके कि हम कोण से गणना करने के लिए 90_ initial_direction जोड़ते हैं, और बाद में हम + के बजाय - का उपयोग करते हैं। दोनों की गणना करने के बाद, हम बस देखते हैं कि कौन सा मार्ग छोटा है और उस एक का उपयोग करें।

इस एल्गोरिथ्म के हमारे कार्यान्वयन में और जो अनुसरण करते हैं, हम एक डेटा संरचना का उपयोग करते हैं जो चार अलग-अलग "लाइन सेगमेंट" तक संग्रहीत करता है, प्रत्येक एक या तो सीधा या घुमावदार होता है। यहां वर्णित घुमावदार रास्तों के लिए, केवल दो खंडों का उपयोग किया जाता है: एक चाप जिसके बाद एक सीधी रेखा होती है। डेटा संरचना में ऐसे सदस्य होते हैं जो निर्दिष्ट करते हैं कि क्या खंड एक चाप है या एक सीधी रेखा, खंड की लंबाई और इसकी प्रारंभिक स्थिति। यदि खंड एक सीधी रेखा है, तो डेटा संरचना भी कोण निर्दिष्ट करती है; आर्क्स के लिए, यह सर्कल के केंद्र, सर्कल पर शुरुआती कोण और चाप द्वारा कवर किए गए कुल रेडियंस को निर्दिष्ट करता है।

एक बार जब हमने दो बिंदुओं के बीच पाने के लिए आवश्यक घुमावदार मार्ग की गणना कर ली है, तो हम आसानी से किसी भी समय अपनी स्थिति और दिशा की गणना कर सकते हैं, जैसा कि लिस्टिंग 2 में दिखाया गया है।

सूची 2. किसी विशेष समय पर स्थिति और अभिविन्यास की गणना करना।

distance = unit_speed * elapsed_time
loop i = 0 to 3:
    if (distance < LineSegment[i].length)
        // Unit is somewhere on this line segment
        if LineSegment[i] is an arc
            //determine current angle on arc (theta) by adding or
            //subtracting (distance / r) to the starting angle
            //depending on whether turning to the left or right
            position.x = LineSegment[i].center.x + r*cos(theta)
            position.y = LineSegment[i].center.y + r*sin(theta)
        //determine current direction (direction) by adding or
        //subtracting 90 to theta, depending on left/right
        else
            position.x = LineSegment[i].start.x 
              + distance * cos(LineSegment[i].line_angle)
            position.y = LineSegment[i].start.y
              + distance * sin(LineSegment[i].line_angle)
        direction = theta
        break out of loop
    else
        distance = distance - LineSegment[i].length

4
यह उत्तर वास्तव में जहाजों के भौतिकी में नहीं दिखता है। मुझे यह भी समस्याग्रस्त लगता है कि यह मूल रूप से एक लिंक है और एक अन्य वेबसाइट से लंबा उद्धरण है (मैं कानूनी मामलों के बारे में अनिश्चित हूं)।
कोई नहीं

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

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

यदि बिंदु सर्कल के भीतर है तो आप थोड़ा बाहर जा सकते हैं और वापस आ सकते हैं।
user253751

(Ps। इन दोनों सवालों को मेटा पर भी देखें। )
इल्मरी करोनें

7

सरल समाधान के रूप में, जैसा कि मैंने पहले ही एक टिप्पणी में कहा था, आप इस aproach की कोशिश कर सकते हैं:

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

turnAngSpeed = 0.4 --direction changing speed
ForwordSpeed = 40 -- full forward speed
turnForwordSpeed = ForwordSpeed *0.6 -- forward speed while turning
function ent:update(dt)
            dir = getVec2(self.tx-self.x,self.ty-self.y) -- ship --> target direction (vec2)
            dir = dir.normalize(dir) --normalized                               
            a= dir:angle() - self.forward:angle() --angle between target direction e current forward ship vector
            if (a<0) then
             a=a+math.pi *2 -- some workaround to have all positive values
            end

            if a > 0.05 then -- if angle difference 
                if a < math.pi then
                    --turn right
                    self.forward = vec2.rotate(self.forward,getVec2(0,0),turnAngSpeed * dt)
                else
                    --turn left
                    self.forward = vec2.rotate(self.forward,getVec2(0,0),-turnAngSpeed * dt)
                end             
                --apply turnForwordSpeed
                self.x = self.x+ self.forward.x * turnForwordSpeed * dt
                self.y = self.y+ self.forward.y * turnForwordSpeed * dt
            else 
                --applly ForwordSpeed
                self.x = self.x+ self.forward.x * ForwordSpeed * dt
                self.y = self.y+ self.forward.y * ForwordSpeed * dt
            end
end

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

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


यह एक अच्छा जवाब है, लेकिन यह ओपी के लिए पर्याप्त रूप से यथार्थवादी हो सकता है या नहीं। इसके विपरीत, कारों, जहाजों में वास्तव में "टर्निंग त्रिज्या" नहीं है: अधिकांश स्व (इंजन / मानव) संचालित जहाज अनिवार्य रूप से एक डाइम पर मुड़ सकते हैं, जबकि नौकायन जहाज हवा पर निर्भर करते हैं, और वास्तव में एक नकारात्मक प्रभावी मोड़ हो सकते हैं त्रिज्या से निपटने के दौरान, इस अर्थ में कि हवा में बाएं मुड़ने से जहाज दाईं ओर बह सकता है। जहाजों के पास जो जड़ता है (और खींचें): वे तुरंत नहीं मुड़ सकते हैं और न ही चल सकते हैं, और एक बार हिलने या मुड़ने के बाद, कुछ समय और रुकने के लिए मजबूर करें। फिर भी, एक +1 है।
इल्मरी करोनें

उत्तर देने के लिए आपका धन्यवाद!!! :) आप सर मेरे हीरो हैं!
डेविड टीटी

@DavidT उसके / उसके जवाब को स्वीकार किए गए के रूप में चिह्नित करने पर विचार करें, अगर यह आपकी समस्या को संतोषजनक ढंग से हल करने में सक्षम था। :)
एमएंड

-2

एकता नव जाल प्रणाली, यह संभव है कि आप क्या नव एजेंट मूल्यों के साथ थोड़ा खेल के साथ चाहते हैं।

नव मेष उपयोग करने के लिए बहुत सरल हैं। और केवल टॉप डाउन सेटअप में प्रयोग करने योग्य (या कम से कम केवल x / z मूवमेंट के लिए उपलब्ध है)

एक नौसेना जाल स्थापित करने पर एकता मैनुअल पेज

मूल रूप से आप नेविगेशन क्षेत्र को सेंकने के लिए किसी भी आकार की जाली का उपयोग कर सकते हैं, और अपनी वस्तुओं में नौसेना के एजेंटों को जोड़ सकते हैं और उन्हें एक नेविगेशन जाल में अपने रास्ते ढूंढ सकते हैं


मुझे लगता है कि इस संबंध में ड्रेको 18 के उत्तर का भी अभाव है। हालाँकि, तुम्हारा कोई वास्तविक जवाब नहीं है और टिप्पणी का अधिक है।
कोई नहीं

2
यह एक अच्छा सुझाव है लेकिन, एक अच्छा जवाब होने के लिए, इसे कार्यान्वयन पर समर्थन और जानकारी की आवश्यकता है। कृपया इसे अच्छा उत्तर देने के लिए नेवी मेश को कॉन्फ़िगर करने के संबंध में कुछ जानकारी जोड़ें। मुझे लगता है कि उपरोक्त टिप्पणी करने वाले क्या कहना चाह रहे हैं :)
श्रीडंक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.