विषयसूची:

जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम: 3 चरण (चित्रों के साथ)
जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम: 3 चरण (चित्रों के साथ)

वीडियो: जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम: 3 चरण (चित्रों के साथ)

वीडियो: जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम: 3 चरण (चित्रों के साथ)
वीडियो: Day 17 Interfacing joystick & arduino with Unity | 21 Days Free Master Class on Virtual Reality 2024, नवंबर
Anonim
जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम
जॉयस्टिक और IR रिसीवर के साथ Arduino- नियंत्रित प्लेटफ़ॉर्मर गेम

आज, हम एक साधारण C#-आधारित प्लेटफ़ॉर्मर गेम को नियंत्रित करने के लिए Arduino माइक्रोकंट्रोलर का उपयोग करने जा रहे हैं। मैं जॉयस्टिक मॉड्यूल से इनपुट लेने के लिए Arduino का उपयोग कर रहा हूं, और उस इनपुट को C# एप्लिकेशन को भेजता हूं जो एक सीरियल कनेक्शन पर इनपुट को सुनता और डिकोड करता है। यद्यपि आपको प्रोजेक्ट को पूरा करने के लिए वीडियो गेम बनाने में किसी पिछले अनुभव की आवश्यकता नहीं है, लेकिन "गेम लूप" में चल रही कुछ चीजों को अवशोषित करने के लिए कुछ समय की आवश्यकता हो सकती है, जिस पर हम बाद में चर्चा करेंगे।

इस परियोजना को पूरा करने के लिए, आपको आवश्यकता होगी:

  • विजुअल स्टूडियो समुदाय
  • एक Arduino Uno (या समान)
  • एक जॉयस्टिक नियंत्रक मॉड्यूल
  • धीरज

यदि आप शुरू करने के लिए तैयार हैं, तो जारी रखें!

चरण 1: जॉयस्टिक और आईआर एलईडी को हुक करें

जॉयस्टिक और आईआर एलईडी को हुक करें
जॉयस्टिक और आईआर एलईडी को हुक करें
जॉयस्टिक और आईआर एलईडी को हुक करें
जॉयस्टिक और आईआर एलईडी को हुक करें

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

सेटअप में प्रयुक्त पिन हैं:

  • A0 (एनालॉग) <- क्षैतिज या X-अक्ष
  • A1 (एनालॉग) <- लंबवत या Y-अक्ष
  • पिन 2 <- जॉयस्टिक स्विच इनपुट
  • पिन 2 <- इन्फ्रारेड एलईडी इनपुट
  • वीसीसी <- 5 वी
  • ज़मीन
  • ग्राउंड #2

चरण 2: एक नया स्केच बनाएं

एक नया स्केच बनाएं
एक नया स्केच बनाएं

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

तो, पहले Arduino कोड एडिटर प्रोग्राम में एक नया स्केच बनाएं। मैं अपना कोड दिखाऊंगा और फिर समझाऊंगा कि यह क्या करता है:

#शामिल "IRremote.h"

// आईआर चर int रिसीवर = 3; // IR रिसीवर का सिग्नल पिन IRrecv irrecv (रिसीवर); // 'irrecv' decode_results परिणामों का उदाहरण बनाएं; // 'decode_results' का उदाहरण बनाएं // जॉयस्टिक/गेम वैरिएबल int xPos = 507; इंट yPos = ५०७; बाइट जॉयएक्सपिन = ए0; बाइट जॉयवाईपिन = ए1; बाइट जॉयस्विच = 2; अस्थिर बाइट क्लिककाउंटर = -1; int minMoveHigh = ५३०; int minMoveLow = ४९०; इंट करंटस्पीड = ५५०; // डिफ़ॉल्ट = एक औसत गति int speedIncrement = 25; // वाई इनपुट के साथ गति बढ़ाने / घटाने की राशि अहस्ताक्षरित लंबी धारा = 0; // वर्तमान टाइमस्टैम्प रखता है int प्रतीक्षा = 40; // संदेशों के बीच प्रतीक्षा करने के लिए एमएस [नोट: कम प्रतीक्षा = तेज फ्रैमरेट] अस्थिर बूल बटन दबाया गया = झूठा; // गेज अगर बटन दबाया जाता है तो शून्य सेटअप () {Serial.begin (९६००); पिनमोड (जॉयस्विच, INPUT_PULLUP); अटैचइंटरप्ट (0, जंप, फॉलिंग); वर्तमान = मिली (); // वर्तमान समय सेट करें // इन्फ्रारेड रिसीवर सेट करें: irrecv.enableIRIn (); // रिसीवर शुरू करें} // सेटअप शून्य लूप () {int xMovement = एनालॉगरेड (joyXPin); int yPos = analogRead (joyYPin); // समय की परवाह किए बिना जॉयस्टिक एक्स आंदोलन को संभालें: अगर (xMovement> minMoveHigh || xMovement वर्तमान + प्रतीक्षा करें) {currentSpeed = yPos> minMoveLow && yPos < minMoveHigh // यदि केवल थोड़ा ही स्थानांतरित किया गया है …? currentSpeed // … बस वर्तमान गति लौटाएं: getSpeed(yPos); // केवल yPos बदलें यदि जॉयस्टिक महत्वपूर्ण रूप से आगे बढ़े //int दूरी =; Serial.print((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\n'); वर्तमान = मिली (); } } // लूप इंट गेटस्पीड (इंट yPos) {// नकारात्मक मान इंगित करते हैं कि जॉयस्टिक ऊपर चला गया है (yPos 1023? 1023: currentSpeed + speedIncrement; } और अगर (yPos> minMoveHigh) // व्याख्या की गई "डाउन" {// से सुरक्षित करें 0 रिटर्न करंट स्पीड के तहत जा रहा है - स्पीड इंक्रीमेंट <0? 0: करंटस्पीड - स्पीड इंक्रीमेंट; }} // getSpeed शून्य कूद () {बटन दबाया = सच; // इंगित करें बटन दबाया गया था। } // कूद // जब एक बटन दबाया जाता है रिमोट, उचित प्रतिक्रिया को संभालें शून्य अनुवादआईआर (decode_results परिणाम) // प्राप्त आईआर कोड के आधार पर कार्रवाई करता है {स्विच (परिणाम। मूल्य) {केस 0xFF18E7: // Serial.println ("2"); currentSpeed + = speedIncrement * 2; ब्रेक; केस 0xFF10EF: // Serial.println ("4"); xPos = -900; ब्रेक; केस 0xFF38C7: // Serial.println ("5"); कूद (); ब्रेक; केस 0xFF5AA5: // Serial. println("6"); xPos = 900; ब्रेक; केस 0xFF4AB5: //Serial.println("8"); currentSpeed -= speedIncrement * 2; ब्रेक; डिफ़ॉल्ट: // Serial.println ("अन्य बटन"); ब्रेक; }// अंत स्विच } // अंत अनुवादआईआर

मैंने ज्यादातर आत्म-व्याख्यात्मक होने के लिए कोड बनाने की कोशिश की, लेकिन कुछ चीजें ध्यान देने योग्य हैं। एक चीज जिसे मैंने ध्यान में रखने की कोशिश की वह निम्नलिखित पंक्तियों में थी:

int minYMoveUp = ५२०;

int minYMoveDown = ५००;

जब प्रोग्राम चल रहा होता है, तो जॉयस्टिक से एनालॉग इनपुट इधर-उधर उछलता है, आमतौर पर लगभग 507 पर रहता है। इसे ठीक करने के लिए, इनपुट तब तक नहीं बदलता है जब तक कि यह minYMoveUp से बड़ा न हो, या minYMoveDown से छोटा न हो।

पिनमोड (जॉयस्विच, INPUT_PULLUP);

अटैचइंटरप्ट (0, जंप, फॉलिंग);

अटैचइंटरप्ट () विधि हमें किसी भी समय सामान्य लूप को बाधित करने की अनुमति देती है, ताकि हम इनपुट ले सकें, जैसे कि जॉयस्टिक बटन पर क्लिक करने पर बटन दबाएं। यहां, हमने पिनमोड () विधि का उपयोग करते हुए, इससे पहले लाइन में इंटरप्ट को संलग्न किया है। यहां एक महत्वपूर्ण नोट यह है कि Arduino Uno पर एक इंटरप्ट संलग्न करने के लिए, आपको या तो पिन 2 या 3 का उपयोग करना होगा। अन्य मॉडल अलग-अलग इंटरप्ट पिन का उपयोग करते हैं, इसलिए आपको यह जांचना पड़ सकता है कि आपका मॉडल Arduino वेबसाइट पर कौन से पिन का उपयोग करता है। दूसरा पैरामीटर कॉलबैक विधि के लिए है, जिसे यहां ISR या "इंटरप्ट सर्विस रूटीन" कहा जाता है। इसे कोई पैरामीटर नहीं लेना चाहिए या कुछ भी वापस नहीं करना चाहिए।

सीरियल.प्रिंट (…)

यह वह लाइन है जो हमारे डेटा को C# गेम में भेजेगी। यहां, हम एक्स-एक्सिस रीडिंग, वाई-एक्सिस रीडिंग और गेम के लिए एक स्पीड वेरिएबल भेजते हैं। खेल को और अधिक रोचक बनाने के लिए अन्य इनपुट और रीडिंग को शामिल करने के लिए इन रीडिंग का विस्तार किया जा सकता है, लेकिन यहां, हम केवल एक जोड़े का उपयोग करेंगे।

यदि आप अपने कोड का परीक्षण करने के लिए तैयार हैं, तो इसे Arduino पर अपलोड करें, और सीरियल मॉनिटर खोलने के लिए [Shift] + [Ctrl] + [M] दबाएं और देखें कि क्या आपको कोई आउटपुट मिल रहा है। यदि आप Arduino से डेटा प्राप्त कर रहे हैं, तो हम कोड के C# भाग में जाने के लिए तैयार हैं…

चरण 3: C# प्रोजेक्ट बनाएं

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

प्रोजेक्ट के C# भाग के लिए, केवल.zip फ़ाइल को डाउनलोड करना और इसे अपने फ़ोल्डर में निकालना सबसे अच्छा है, फिर इसे संशोधित करें। ज़िप फ़ाइल में दो फ़ोल्डर होते हैं। Visual Studio में प्रोजेक्ट खोलने के लिए, Windows Explorer में RunnerGame_CSharp फ़ोल्डर दर्ज करें। यहां,.sln (समाधान) फ़ाइल पर डबल-क्लिक करें, और VS प्रोजेक्ट को लोड करेगा।

मैंने खेल के लिए कुछ अलग-अलग वर्ग बनाए हैं। मैं प्रत्येक वर्ग के बारे में सभी विवरणों में नहीं जाऊंगा, लेकिन मैं मुख्य कक्षाओं के लिए क्या हैं, इसका एक सिंहावलोकन दूंगा।

द बॉक्स क्लास

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

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

हालाँकि, मैं अपने "बॉक्स" वर्ग के कुछ तर्क प्रस्तुत करूँगा:

सार्वजनिक वर्चुअल बूल IsCollidedX (बॉक्स अन्य ऑब्जेक्ट) {…}

यहां हम एक्स-दिशा में वस्तुओं के साथ टकराव की जांच करते हैं, क्योंकि खिलाड़ी को केवल वाई दिशा (ऊपर और नीचे) में टकराव की जांच करने की आवश्यकता होती है यदि वह स्क्रीन पर इसके साथ पंक्तिबद्ध है।

सार्वजनिक आभासी बूल IsCollidedY (बॉक्स अन्य ऑब्जेक्ट) {…}

जब हम किसी अन्य गेम ऑब्जेक्ट के ऊपर या नीचे होते हैं, तो हम Y टकराव की जांच करते हैं।

सार्वजनिक आभासी बूल IsCollided (बॉक्स अन्य ऑब्जेक्ट) {…}

यह एक्स और वाई टकराव को जोड़ता है, यह लौटाता है कि कोई वस्तु इससे टकराती है या नहीं।

सार्वजनिक आभासी शून्य ऑनपेंट (ग्राफिक्स ग्राफिक्स) {…}

उपरोक्त विधि का उपयोग करके, हम किसी भी ग्राफिक्स ऑब्जेक्ट को पास करते हैं और प्रोग्राम के चलने के दौरान उसका उपयोग करते हैं। हम कोई भी आयत बनाते हैं जिसे खींचने की आवश्यकता हो सकती है। हालाँकि, इसका उपयोग विभिन्न प्रकार के एनिमेशन के लिए किया जा सकता है। हमारे उद्देश्यों के लिए, आयतें प्लेटफॉर्म और खिलाड़ी दोनों के लिए ठीक काम करेंगी।

चरित्र वर्ग

चरित्र वर्ग मेरे बॉक्स वर्ग का विस्तार करता है, इसलिए हमारे पास कुछ निश्चित भौतिकी बॉक्स से बाहर है। मैंने टकराव के लिए हमारे द्वारा बनाए गए सभी प्लेटफार्मों को जल्दी से जांचने के लिए "चेकफॉर कॉलिशन" विधि बनाई है। "जंप" विधि खिलाड़ी के ऊर्ध्व वेग को जम्पस्पीड चर पर सेट करती है, जिसे बाद में मेनविंडो वर्ग में फ्रेम-दर-फ्रेम संशोधित किया जाता है।

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

प्लेटफार्म क्लास

इस खेल में, मैं केवल इस वर्ग के निर्माता का उपयोग करता हूं जो एक इनपुट के रूप में एक्स-समन्वय लेता है, मेनविंडो कक्षा में सभी प्लेटफार्मों के एक्स स्थानों की गणना करता है। प्रत्येक प्लेटफ़ॉर्म को स्क्रीन की ऊंचाई के 1/2 से 3/4 तक यादृच्छिक Y-निर्देशांक पर सेट किया गया है। ऊंचाई, चौड़ाई और रंग भी बेतरतीब ढंग से उत्पन्न होते हैं।

मेनविंडो क्लास

यह वह जगह है जहाँ हम खेल के चलने के दौरान उपयोग किए जाने वाले सभी तर्क रखते हैं। सबसे पहले, कंस्ट्रक्टर में, हम प्रोग्राम के लिए उपलब्ध सभी COM पोर्ट्स को प्रिंट करते हैं।

foreach (SerialPort. GetPortNames () में स्ट्रिंग पोर्ट)

कंसोल। राइटलाइन ("उपलब्ध पोर्ट:" + पोर्ट);

हम चुनते हैं कि हम किस पर संचार स्वीकार करेंगे, जिस पोर्ट के अनुसार आपका Arduino पहले से उपयोग कर रहा है:

सीरियलपोर्ट = नया सीरियलपोर्ट (सीरियलपोर्ट। गेटपोर्टनाम () [2], 9600, समानता। कोई नहीं, 8, स्टॉपबिट्स। वन);

कमांड पर पूरा ध्यान दें: SerialPort. GetPortNames()[2]। [2] यह दर्शाता है कि किस सीरियल पोर्ट का उपयोग करना है। उदाहरण के लिए, यदि प्रोग्राम "COM1, COM2, COM3" प्रिंट करता है, तो हम COM3 पर सुन रहे होंगे क्योंकि नंबरिंग सरणी में 0 से शुरू होती है।

कंस्ट्रक्टर में भी, हम स्क्रीन पर Y दिशा में सेमी-रैंडम स्पेसिंग और प्लेसमेंट के साथ सभी प्लेटफॉर्म बनाते हैं। सभी प्लेटफार्मों को एक सूची वस्तु में जोड़ा जाता है, जो सी # में एक सरणी जैसी डेटा संरचना को प्रबंधित करने का एक बहुत ही उपयोगकर्ता के अनुकूल और कुशल तरीका है। फिर हम प्लेयर बनाते हैं, जो कि हमारा कैरेक्टर ऑब्जेक्ट है, स्कोर को 0 पर सेट करें और गेमओवर को गलत पर सेट करें।

निजी स्थैतिक शून्य DataReceived (वस्तु प्रेषक, SerialDataReceivedEventArgs e)

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

अंत में, यह सेटअप गेम को प्रयोग करने योग्य कुछ में विस्तारित करने के लिए एक अच्छा आधार देता है। यद्यपि भौतिकी बिल्कुल सही नहीं है, यह हमारे उद्देश्यों के लिए पर्याप्त रूप से काम करता है, जो कि Arduino का उपयोग किसी ऐसी चीज़ के लिए करना है जिसे हर कोई पसंद करता है: गेम खेलना!

सिफारिश की: