SDL में ट्रैप माउस


12

मैं अपने गेम के अंदर उपयोगकर्ता के माउस को कैसे फँसा सकता हूँ? यह फुलस्क्रीन गेम नहीं है, लेकिन मैं इसे चाहता हूं ताकि उपयोगकर्ता स्क्रीन के बाहर माउस को न खींच सके।

क्या मुझे विंडो (मैन्युअल रूप से) के अंदर यह कहने के लिए माउस और SDL_WarpCursor के निर्देशांक की जांच करनी है, या कोई स्वचालित तरीका है?

धन्यवाद।


क्या आपने कर्सर को छुपाने और इसे वापस केंद्र में लाने पर विचार किया है? फिर, बस ओएस कर्सर के स्थान पर स्क्रीन के केंद्र में अपनी क्रॉसहेयर खींचें।
वॉन हिल्ट्स

जवाबों:


24

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

यह भी याद रखें कि कई प्लेटफार्मों पर, कर्सर को आपके ऐप की तुलना में उच्च आवृत्ति पर नियंत्रित किया जाता है। यदि आप 60fps से नीचे चल रहे हैं तो यह विशेष रूप से सच है! इसलिए भले ही प्लेटफ़ॉर्म आपके गेम के हर फ्रेम पर माउस को सफलतापूर्वक घुमा रहा हो, अगर यह आपके रेंडर फ्रेम के बीच अपडेट प्राप्त कर रहा है, तो भी कर्सर आपकी विंडो से दूर जा सकता है।

एसडीएल के तहत माउस को फंसाने की सही विधि है:

SDL_WM_GrabInput( SDL_GRAB_ON );

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

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

एसडीएल 2 के लिए अपडेट - 9 दिसंबर, 2013

यह इंटरफ़ेस SDL2 के लिए बदल गया है। यदि आप SDL1.2 का उपयोग कर रहे हैं, तो ऊपर दिया गया उत्तर अभी भी सही है। हालाँकि, SDL2 के तहत SDL_WM_GrabInput(SDL_GrabMode)फ़ंक्शन अब उपलब्ध नहीं है। SDL2 माउस को पकड़ने का नया तरीका है:

SDL_SetRelativeMouseMode(SDL_TRUE);

अन्यथा, यह पहले के फ़ंक्शन के समान है - इस मोड में आप SDL_MOUSEMOTIONईवेंट प्राप्त करना जारी रखेंगे, हालांकि माउस को विंडो के अंदर बाधित नहीं किया गया था।


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

यह पूरी तरह से काम किया है, और यह मैनुअल तरीके से बहुत आसान है। धन्यवाद!
डेविड गोम्स

3

जबकि ट्रेवर का अपडेट किया गया उत्तर SDL2 की वर्तमान स्थिति को दर्शाता है, आप सेट के SDL_Windowसाथ अपना माउस भी डाल सकते हैं SDL_WINDOW_INPUT_GRABBED। ज्ञात हो कि मैंने लिनक्स पर कुछ अजीब मुद्दों में भाग लिया है (संभवतः कुछ एक्स विंडोिंग क्विक के कारण) जहां आप कभी भी खिड़की से बाहर नहीं निकल सकते हैं जब तक कि SDL_QUIT को नहीं बुलाया जाता है (भले ही कोई अन्य ओएस घटना फोकस को चुरा ले)।


धन्यवाद, SDL_WINDOW_INPUT_GRABBED मेरे SDL2 कोड पर पूरी तरह से काम करता है।
एड्रियन मायेर


2

माउस चलने पर पता लगाने के लिए आप एसडीएल मोशन इवेंट का उपयोग कर सकते हैं । उसके बाद, आप WarpCursor को कॉल कर सकते हैं, यहां तक ​​कि किसी घटना को फायर करने के बाद भी relX और rely मानों को पाइप करने के लिए। आप अपने ओएस कर्सर को भी छिपा सकते हैं और स्क्रीन के केंद्र में एक क्रॉसहेयर या कुछ इसी तरह आकर्षित कर सकते हैं। यह सुनिश्चित करता है कि माउस उपयोगकर्ता के लिए हमेशा मध्य में रहे और आप अभी भी गति और पसंद के लिए मान प्राप्त कर सकते हैं।

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