किसी क्षेत्र के लिए click'n'drag आंदोलन को कैसे सीमित करें?


11

मैं कुछ सामान्य शीर्षक के लिए माफी माँगता हूँ। मैं वास्तव में इस बारे में बहुत कुछ नहीं जानता कि मैं जो करने की कोशिश कर रहा हूं उसे कैसे पूरा किया जाए, जो एक संभावित समाधान पर शोध करना कठिन बना रहा है।

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

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

पथ मार्कर आरेख

तो मैं अब दो समस्याओं के साथ फंस गया हूं:

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

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

पहला आरेख: ऊपर की ओर बढ़ना दूसरा चित्र: ड्रैग के बाद

मुझे आशा है कि यह सब बहुत भ्रामक नहीं था। धन्यवाद दोस्तों।

संपादित करें: यदि इससे कोई फर्क पड़ता है, तो मैं सी + + का उपयोग मुरब्बा एसडीके के साथ कर रहा हूं।


मुझे लगता है कि आप जिस शब्द की तलाश कर रहे हैं वह "रास्ता" है, और क्या आप गणितीय रूप से ग्रे क्षेत्र को परिभाषित कर सकते हैं? आपकी समस्या का समाधान शायद बहुत आसान होगा यदि यह है।
जॉन मैकडॉनल्ड्स

पैथफाइंडिंग और इस तरह से संबंधित एरेंटप्वाइंट? इसके अलावा, गणितीय रूप से ग्रे क्षेत्र को परिभाषित करना मेरी समस्याओं में से एक है: पीआई को लगता है कि मैं एक आयत या एक सर्कल की तरह कुछ भी समझ सकता हूं, लेकिन इस तरह का आकार, एक कोण पर दो पक्षों और दो अन्य पक्षों के साथ ... यह है मेरे सिर के ऊपर एक सा।
वीक्सिल

आपको यह भी निर्दिष्ट करना होगा कि आप किस भाषा और / या टूलकिट का उपयोग कर रहे हैं, क्योंकि समाधान मुख्य रूप से प्लेटफ़ॉर्म-निर्भर हैं।
रेसिमजिशन

वास्तव में? मुझे लगा कि एक अल्गोरिथमिक समाधान या स्यूडोकोड भी मदद करेगा। मैं वैसे भी प्रश्न संपादित करूँगा, बस मामले में।
वोक्सिल

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

जवाबों:


8

आप अपने प्रश्न में तीन मानों के साथ एक कार्य क्षेत्र को परिभाषित कर सकते हैं:

float innerRadius;
float outerRadius;
float maxAngle;

ये मान एक केंद्र बिंदु पर आधारित होंगे जो खिलाड़ी की स्थिति हो सकती है या नहीं । व्यावहारिक क्षेत्र का आकार इस बात पर निर्भर करता है कि आप इस बिंदु पर कहां हैं।

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

केंद्र की स्थिति के ऊपर के उदाहरण में खिलाड़ी के पीछे एक निश्चित दूरी (मान लीजिए 50 इकाई) है । इसे आसानी से गणना की जा सकती है:

float offset = -50;
Vector2 centerPosition = playerPosition + offset * playerForward;

मार्कर की स्थिति को उस कार्य क्षेत्र में सीमित करने के लिए, मार्कर को पहले ले जाएं जैसा कि आप सामान्य रूप से करते हैं। फिर केंद्र बिंदु और मार्कर के बीच की दूरी को मान्य करें :

Vector2 direction = markerPosition - centerPosition;
float distance = direction.Length();
direction.Normalize();
markerPosition = centerPosition + direction * clamp(distance, innerRadius, outerRadius);

अंत में, मार्कर के कोण को निर्दिष्ट सीमा तक मान्य करें । मैं इसके लिए छद्म कोड का उपयोग करूँगा:

- Find angle between vector C->M and vector playerForward
- If abs(angle) <= maxAngle Then do nothing
- Else If angle > 0 Then rotate M around C by maxAngle-angle
- Else If angle < 0 Then rotate M around C by -maxAngle-angle

एक बिंदु को दूसरे के चारों ओर घुमाने के तरीके के बारे में देखें। इसे त्रिकोणमिति या परिवर्तन मैट्रिक्स के साथ किया जा सकता है।

आप मार्कर के आकार को भी ध्यान में रखना चाहते हैं और इसकी भरपाई के लिए त्रिज्या और कोण को थोड़ा छोटा कर सकते हैं।

संपादित करें: दूसरे विचार पर, यह अधिक स्वाभाविक लग सकता है यदि आप पहले कोण को मान्य करते हैं, तो दूरी, इसलिए दोनों विकल्पों का प्रयास करें!


महान समाधान! मुझे कुछ ऐसा मिला है जिसमें दो मंडलियाँ और एक त्रिभुज शामिल है, लेकिन आपका समाधान सुरुचिपूर्ण ढंग से सरल करता है। कोण के सत्यापन के बारे में, मैंने एक सामान्यीकृत वेक्टर होने की तर्ज पर कुछ सोचा था जो प्लेयरफॉरवर्ड से मैक्सएंगल (और दूसरा -मैक्सएंगल) पर खड़ा था, जिसे C- M की लंबाई से गुणा किया जा सकता था, क्योंकि यह सीमा का था , कोण-वार। मैं मान रहा हूं कि C के चारों ओर M को घुमाने से आपका समाधान कम खर्चीला होगा, क्या यह सही है?
Vexille

@Vexille खैर, घूर्णन में एक cosऔर एक sinऑपरेशन शामिल है , इसलिए मुझे यकीन नहीं है। लेकिन उन दो वैक्टरों की गणना करने के लिए आपको उन्हें घुमाने की भी आवश्यकता होती है, हालाँकि आपको केवल आगे के वेक्टर में बदलाव होने पर ऐसा करने की आवश्यकता होती है। वैसे भी बहुत ज्यादा मायने नहीं रखना चाहिए, जिसे आप लागू करना चाहते हैं उसे चुनें।
डेविड गौविया

10

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

1. अपना क्षेत्र लें:

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

2. और इसे एक मोनोक्रोमैटिक बिटमैप में परिवर्तित करें:

यहाँ छवि विवरण दर्ज करें और इसे स्केल_0 नाम दें

3. बिटमैप को क्लोन करें और इसे 50% तक घटाएं:

यहाँ छवि विवरण दर्ज करें और इसे स्केल 1 नाम दें

4. और इसी तरह, जब तक बिटमैप कम नहीं होता तब तक 4 पिक्सेल चौड़े / लम्बे होते हैं:

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें पैमाना: 2, 3, 4, 5, 6

5. अब हमारे पास विभिन्न प्रस्तावों के मोनोक्रोमैटिक बिटमैप के रूप में हमारा क्षेत्र है: यहाँ छवि विवरण दर्ज करें

6. अंतिम छवि (यहां "स्केल_6") लें और इसे सभी पिक्सेल के माध्यम से पुन: व्यवस्थित करें।

  • स्क्रीन निर्देशांक के लिए प्रत्येक पिक्सेल के निर्देशांक का अनुवाद करें: x = Math.pow ( 2, scale_level );जहां scale_level वह संख्या है जिसे हमने "scale_" के बाद जोड़ा है। हम इसे क्वाड ट्री स्तर भी कह सकते हैं, हालांकि हम वास्तव में क्वाड ट्री के साथ काम नहीं कर रहे हैं। Y के साथ भी ऐसा ही करें।
  • जांच लें कि अनुवादित x & y पर पिक्सेल काला है या नहीं। यदि नहीं, तो यह आकार का हिस्सा नहीं है, और आपको बस continueलूप के अगले चरण के लिए होना चाहिए
  • चेक करें कि क्या पिक्सेल पहले से चेक किए गए पिक्सेल की तुलना में माउस कर्सर के करीब है - यदि हाँ, तो पिक्सेल के निर्देशांक को बचाएं - अनुवाद से पहले निर्देशांक का उपयोग करें, जो बिटमैप के अंदर निर्देशांक है।
  • लूप के अंत में, इन निर्देशांक को 2 से गुणा करें: x *= 2; y*=2;अगली छवि (पिछले पैमाने) में निर्देशांक में उनका अनुवाद करने के लिए।

7. पिछली छवि लें (यहां "स्केल_5"), लेकिन सभी पिक्सेल के माध्यम से लूप न करें; x = save_x पर शुरू करें और x = save_x + 2 के साथ समाप्त करें, वही y के साथ। यही है, अब के बाद से आप हर स्तर के लिए केवल 4 पिक्सल के माध्यम से लूप करेंगे! बाकी पी में जैसा है। 6।

8. पहली छवि लें (सबसे बड़ा = सबसे बड़ा संकल्प वाला), फिर से 4 पिक्सेल के माध्यम से लूप करें, और आपके पास अंततः पिक्सेल है जो माउस कर्सर के सबसे करीब है:

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

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

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

9. हालाँकि, मैं "M" को यहाँ एक बिंदु के रूप में मान रहा हूँ। यदि आप चाहते हैं कि यह एक ऐसा सर्कल हो जो पूरी तरह से फिट हो, तो आपको circle.radiusपहले पिक्सेल द्वारा आकार को सिकोड़ना (सिकोड़ना) चाहिए ।

मैंने सोचा कि मैं यह एल्गोरिथ्म केवल तभी काम करूंगा जब आप मोनोक्रोमैटिक नहीं बल्कि ग्रेस्केल चित्रों का उपयोग करेंगे और "पूर्ण" के रूप में पिक्सेल का इलाज करेंगे यदि यह सफेद नहीं है, और "खाली" के रूप में यदि यह बिल्कुल सफेद है ... या यदि आपका आकार बदल रहा है एल्गोरिदम हर बार 4 पिक्सलों के समूह को 1 ब्लैक पिक्सेल में बदलता है जब इन 4 पिक्सल्स में से कम से कम एक सफेद नहीं था।


2
गणितीय रूप से व्यक्त करने के लिए मुश्किल (यदि असंभव नहीं है) आकृतियों के उत्तर के लिए +1।
साइफर

वाह, बहुत दिलचस्प। +1 भी: D
Vexille

मैंने इसे वास्तविक परियोजना में लागू किया, और मुझे कहना होगा कि कुछ समस्याएं सामने आईं। मूल रूप से, आपको ग्रिड सेल की एक सूची बनाने की आवश्यकता है, जहाँ आप निकटतम ग्रिड सेल का नाम लेते हैं closest, और दूरी को दूर करने के लिए जाँच करते हैंclosest - चलो दूरी का नाम दें furthest_dist। अब आपको सूची से उन सभी कक्षों को हटाने की आवश्यकता है जिनके पास अपने निकटतम बिंदु से आगे furthest_distऔर गहरे स्तर पर हैं। तो इस तरह से कुछ के बजाय: i.imgur.com/4UuFo.png यह कुछ इस तरह है: i.imgur.com/dyTT3.png
मार्कस वॉन Broady
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.