C # / XNA को हार्डवेयर माउस पोजीशन मिलती है


10

मैं C # का उपयोग कर रहा हूं और हार्डवेयर माउस स्थिति प्राप्त करने की कोशिश कर रहा हूं। पहली बात जो मैंने कोशिश की थी वह सरल XNA कार्यक्षमता थी जो उपयोग करने के लिए सरल है

Vector2 position = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

उसके बाद मैं माउस की ड्राइंग भी करता हूं, और विंडोज़ हार्डवेयर माउस की तुलना में, xna प्रदान किया गया निर्देशांक वाला यह नया माउस "स्लैकिंग ऑफ" है। मेरा मतलब है कि यह कुछ फ्रेम से पीछे है। उदाहरण के लिए यदि गेम 600 एफपीएस पर चल रहा है, तो यह उत्तरदायी होगा, लेकिन 60 एफपीएस सॉफ्टवेयर माउस में देरी अब स्वीकार्य नहीं है। इसलिए मैंने कोशिश की कि मुझे लगा कि हार्डवेयर माउस है,

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);

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

GraphicsDeviceManager.SynchronizeWithVerticalRetrace = true/false
Game.IsFixedTimeStep = true/fale

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


2
मुझे नहीं लगता Mouse.GetState()कि टूटा हुआ है। क्या आप सुनिश्चित हैं कि आप उसी स्थिति में माउस स्थिति प्राप्त कर रहे हैं जैसे आप उसे खींच रहे हैं? यह भी याद रखें कि विंडोज कर्सर में त्वरण / मंदी सक्षम है, इसलिए यह अधिक उत्तरदायी लगता है । यदि आप हार्डवेयर के करीब जाना चाहते हैं, तो आपको DirectInput को हिट करना चाहिए, जो आपको पूर्ण माउस पोजीशन के बजाय मूवमेंट डेल्टास देगा। लेकिन मेरा मानना Mouse.GetState()है कि यह अभी भी XNA में करने का सही तरीका है।
पांडा पायजामा

नहीं, Mouse.GetState()टूटा हुआ नहीं है, और जब तक IsFixedTimeStep == trueलोग दिखाई देने वाले विंडोज़ माउस के साथ सीधे तुलना नहीं करते हैं, तब तक विलंब को देखने में सक्षम नहीं होना चाहिए। हालाँकि, कम फ्रैमरेट में झूठे को IsFixedTimeStep सेट करना यह सभी के लिए दृश्यमान हो जाता है। प्रत्यक्ष इनपुट के बारे में मैंने माना कि एक सकारात्मकता (अंतिम उपाय)।
सुंदर

सुनिश्चित नहीं है कि यह वही है जो आप चाहते हैं, लेकिन कर्सर को बदलने के बारे में क्या है जबकि यह आपकी खिड़की में है, और फिर इसे हमेशा दृश्यमान बनाएं?
विलियम मैरीजर

ठीक यही मैं कर रहा हूँ, बात यह है कि मैं न केवल इसे दिखाना चाहता हूं, बल्कि माउस की सटीक स्थिति भी जानना चाहता हूं। लेकिन मुझे जो मिल रहा है, वह उससे थोड़ा पीछे है।
सुंदर

जवाबों:


17

आप जो देख रहे हैं वह इनपुट लैग नहीं है

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

यह वही है जो एक्सएनए उपयोग करता है । विशेष रूप से GetCursorPos( MSDN )। इसका मतलब यह है कि, जब आप कॉल करते हैं, तो आपको Mouse.GetStateकर्सर की सही स्थिति मिल रही है क्योंकि विंडोज इसे देखता है - व्यावहारिक रूप से शून्य विलंब के साथ।

अब, आप उपयोग कर सकते हैं WM_INPUT(या DirectInput, हालांकि यह पदावनत है)। यह आपको कच्चे सूचक डेटा देता है। इससे पहले कि विंडोज त्वरण जैसी चीजों को लागू कर सकता है, और आमतौर पर वह नहीं है जो आप चाहते हैं।

आप जो देख रहे हैं वह आउटपुट लैग है।

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

दूसरी ओर, आपके गेम को GPU पाइपलाइन से गुजरना पड़ता है। यह अपने आप में बहुत देरी जोड़ता है। आपके लिए इनमें से सबसे समस्याग्रस्त डबल-बफ़रिंग है - जो (मुझे पूरा यकीन है) आप XNA 4 में बंद नहीं कर सकते। आप सीधे फ्रेम बफर पर आकर्षित नहीं होते हैं - आप बैकबफ़र पर आकर्षित होते हैं। जिसे हर ~ 16ms (60FPS पर) प्रस्तुत किया जाता है। इसका मतलब है कि आप उस परिणाम के Mouse.GetStateआधार पर स्क्रीन पर कुछ प्राप्त करने के परिणाम के बीच कम से कम 16ms देख रहे हैं। शायद ज्यादा लंबा। निश्चित रूप से हार्डवेयर कर्सर की तुलना में बहुत धीमा है।

तो उपाय क्या हैं?

हार्डवेयर कर्सर द्वारा प्रदर्शित होने वाली छवि को बदलने के लिए एक SetCursor( MSDN ) का उपयोग करना है, यह छवि है कि आपके गेम को बेहतर सूट करता है (या बस विंडोज कर्सर के साथ रहते हैं)।

और अन्य (बहुत आसान) केवल अंतराल को स्वीकार करना है, और Game.IsMouseVisible = falseसापेक्ष अंतराल को छिपाने के लिए निर्धारित है। खेल में अपना खुद का कर्सर प्रदर्शित करें। यह छिपे हुए विंडोज कर्सर से 16ms धीमा होगा - लेकिन कौन परवाह करता है? गेमर्स इसका उपयोग करते हैं। और 16ms वैसे भी लगभग नेत्रहीन है (इसलिए हम 60FPS में चीजों को प्रस्तुत करते हैं)।


मामले की विस्तृत व्याख्या के लिए धन्यवाद। सबसे अधिक संभावना है कि मैं सिर्फ XNA माउस के साथ रहूँगा। मामले में किसी को स्वीकार करने से पहले थोड़ा इंतजार करने के लिए जाना इसके लिए कुछ अतिरिक्त समाधान है।
सुंदर

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