मतदान बनाम घटना संचालित इनपुट


19

मैं इनपुट पद्धति के लिए मतदान का उपयोग करके एक गेम विकसित कर रहा हूं। हालाँकि, अब जब मैं गेम मेनू और अन्य UI घटकों में गहराई से जान रहा हूँ, तो मुझे पता चल रहा है कि मैं शायद इवेंट संचालित इनपुट लेना चाहूंगा। शायद दोनों होने पर भी, यूआई के लिए संचालित घटना और "दुनिया" इनपुट के लिए मतदान का उपयोग करते हुए। मैं उत्सुक हूं कि जाने का सबसे अच्छा तरीका क्या है।

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

मैं इवेंट को परिभाषित के रूप में संचालित कर रहा हूं: जब कोई ईवेंट होता है, तो इंटरप्ट आधारित इवेंट, और इंटरग्रेन ट्रिगर होता है और इवेंट के आधार पर एक कोड ब्लॉक चलाया जाता है।

क्या आपको लगता है कि सभी इवेंट संचालित, सभी मतदान करना सबसे अच्छा है, या दोनों स्वीकार्य है? यदि आपके पास पेशेवरों और विपक्षों के लिए या तो कृपया उन्हें सूचीबद्ध करें। धन्यवाद।

संपादित करें

गेम जावा / ओपनजीएल आधारित है, इसलिए विंडोज / मैक / लिनक्स के लिए जारी किया जाएगा। मोबाइल उपकरणों के विस्तार की संभावना कम है। खेल आरटीएस शैली, 3 डी व्यक्ति 3 डी है।

EDIT 2

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

@Override  
private boolean handleEvent(Event event) {  
    if(hud.handleEvent(event)) {  
        return true;  
    }  
    return WORLD.handleEvent(event);  
}

इस तरह से बटन के पीछे की वस्तुओं का चयन करने के लिए मुझे UI के माध्यम से लीक होने वाले क्लिक नहीं मिलते हैं और क्या नहीं।

वर्तमान में मेरे कैमरा नियंत्रण अभी भी मतदान पर आधारित हैं, और लगता है कि अभी के लिए काम कर रहा है, लेकिन मैं बाद में इसे अपडेट कर सकता हूं।

मैं सभी उत्तरों की सराहना करता हूं, क्षमा करें मैं केवल एक चुन सकता हूं!


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

मेरी राय में ध्यान देने का सबसे प्रासंगिक बिंदु एक इवेंट लूप तैयार करना है जो इनपुट संग्रह की तुलना में किसी भी अन्य भार से मुक्त है। मुझे समझाएं: ऑपरेटिंग सिस्टम इनपुट संचालित रुकावट को करेगा और इसे वैश्विक "इनपुट थ्रेड" में व्यवहार करेगा, फिर यह ओएस-थ्रेड संदेशों को वर्तमान में इन-फोकस एप्लिकेशन में रीडायरेक्ट करेगा और इंटेल को इसकी संदेश कतार में लिख देगा। संदेश कतार PeekMessage, या GetMessage द्वारा परागण करना है। इसे प्राप्त करने का सबसे तेज़ तरीका GetMessage का उपयोग करना है और शेड्यूलर को आपको जगा देना है, फिर आप संदेश को बहुत सटीक रूप से टाइमस्टैम्प कर सकते हैं।
v.oddou

जवाबों:


17

यह आपके गेम और हार्डवेयर की आवश्यकताओं पर निर्भर करता है। अधिकांश गेम आमतौर पर इनपुट स्थिति में बदलाव में रुचि रखते हैं, अर्थात उपयोगकर्ता फायर कुंजी दबाता है और उनका हथियार फायर करना शुरू कर देता है, उपयोगकर्ता फायर कुंजी जारी करता है और उनका हथियार फायरिंग बंद कर देता है, उपयोगकर्ता चाल कुंजी दबाता है और चलना शुरू करता है, चाल कुंजी जारी करता है और आगे बढ़ना बंद कर देता है , आदि, इसलिए एक घटना-चालित इनपुट सिस्टम उन मामलों में सबसे अधिक समझ में आता है क्योंकि जानकारी पहले से ही एक उपयुक्त प्रारूप में है। विंडोज प्लेटफॉर्म पर प्लस, आप पहले से ही कीबोर्ड और माउस राज्य में परिवर्तन के लिए इवेंट प्राप्त करते हैं, इसलिए यह अक्सर निम्न-स्तरीय इनपुट इवेंट से उच्च-स्तरीय गेम इवेंट में 1: 1 होता है। मतदान के साथ, आप अक्सर स्वयं को वर्तमान और अंतिम फ्रेम के बीच स्थिति की तुलना करके ऐसी घटनाओं को मैन्युअल रूप से उत्पन्न करने के लिए पाएंगे। असल में, "अब कौन से बटन दबाए जाते हैं?"

कहा जा रहा है कि, कुछ प्लेटफार्मों पर आप एक निम्न-स्तर पर मतदान इनपुट के साथ फंस गए हैं और किनारे की जाँच करने का कोई तरीका नहीं है। हालाँकि, मैंने हमेशा सभी उच्च-स्तरीय तर्क के लिए घटनाओं का उपयोग करके सर्वोत्तम परिणाम प्राप्त किए हैं क्योंकि स्वाभाविक रूप से उन प्रणालियों का संचालन कैसे होता है।


धन्यवाद, मैंने खेल के मंच और उद्देश्य के बारे में अतिरिक्त जानकारी शामिल की है।
माइकलहाउस

1
ध्यान दें कि GetAsyncKeyStateWin32 पर मतदान का उपयोग करने का एक सरल तरीका है।
मैके

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

@ मैके: कभी-कभी एंटीवायरस ऐसे कार्यक्रमों की रिपोर्ट करते हैं जो इस एपीआई का उपयोग करते हैं क्योंकि वे पूरे वैश्विक सिस्टम से की-प्रेस प्राप्त कर सकते हैं, इस प्रकार मैलवेयर कुंजीकरण को सक्षम कर सकते हैं। पूरे इंटरनेट पर इसके बारे में सबसे भयानक लेख (मुझे पता है) यह एक है: Securelist.com/analysis/publications/36358/…
v.oddou

7

मुझे कोई कारण नहीं दिखता कि आप दोनों नहीं कर सकते, और दोनों दुनियाओं में सर्वश्रेष्ठ प्राप्त कर सकते हैं।

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

mouseInput = GetMouse();
kbInput = GetKeyboard();


// refactor this out to its own method if it makes sense
if menuState == Showing
    if mouseInput.LeftButton == State.Pressed
        LeftButton(mouseInput.X, mouseInput.Y)

// rest of game input code processing

void LeftButton(int x, int y)
{
    // left button event handler
}

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


1
मैं उपकरणों से इनपुट प्राप्त करने की प्रकृति के बारे में उत्सुक हूं। क्या डिवाइस ड्राइवर स्तर पर मतदान के परिणामस्वरूप OS द्वारा कीबोर्ड की घटनाओं को भेज दिया जाता है? या एक कीबोर्ड घटना एक रुकावट के साथ मेल खाती है? या वहाँ व्यवधान हैं, लेकिन ओएस उन्हें बफ़र करता है और फिट होने पर उन्हें भेज देता है?
michael.bartnett

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

5

यहां दो अलग-अलग मुद्दे हैं:

  1. आप OS / हार्डवेयर से उपयोगकर्ता इनपुट कैसे पढ़ते हैं?

  2. आप अपने इंजन में उपयोगकर्ता इनपुट को कैसे संसाधित करते हैं?

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

प्रसंस्करण के लिए, कुछ अलग विकल्प हैं:

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

    जैसे कुछ speed += 1 if button.down else -1; clamp(speed, 0, 42);

  • असतत घटनाओं (अग्नि मिसाइल, ठहराव का खेल, ग्रह के दूसरी तरफ टेलीपोर्ट) के लिए, घटना प्रसंस्करण बेहतर है, अन्यथा आपका कोड maybeLaunchMissile(key_state);कॉल के साथ लिट जाएगा , और यह सिर्फ ... बुरा, m'kay। ;)

आशा करता हूँ की ये काम करेगा।

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