विषयसूची:

Arduino OLED स्नेक गेम: 3 चरण
Arduino OLED स्नेक गेम: 3 चरण

वीडियो: Arduino OLED स्नेक गेम: 3 चरण

वीडियो: Arduino OLED स्नेक गेम: 3 चरण
वीडियो: Arduino Project - Star Wars Game #oled #arduinoproject #starwars 2024, जुलाई
Anonim
Arduino OLED स्नेक गेम
Arduino OLED स्नेक गेम

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

तुम क्या आवश्यकता होगी

आपूर्ति

Arduino UNO या क्लोन

ओएलईडी डिस्प्ले

4 डायोड

500-1k रोकनेवाला

4 नियंत्रक बटन

निष्क्रिय पीजो बजर

ऐच्छिक

सोल्डरलेस ब्रेडबोर्ड

कृपया ध्यान दें कि ये लिंक केवल उदाहरण के लिए हैं

चरण 1: सर्किट

सर्किट
सर्किट

उपरोक्त चित्र में आप हमारे सर्किट को देख सकते हैं, हम arduino पर पिन d3 का उपयोग एक इंटरप्ट अनुरोध पिन के रूप में करते हैं ताकि arduino नियंत्रक इनपुट को पढ़ने को प्राथमिकता देगा जो d4 d5 d6 d7 हैं। सर्किट की मूल बातें यह है कि एक दिशा बटन दबाया जाता है जो उच्च 5v जाता है यह इंटरप्ट अनुरोध पिन (डी 3 बैंगनी तार) और संबंधित दिशा पिन को सक्रिय करता है, इंटरप्ट फ़ंक्शन एक अद्यतन दिशा फ़ंक्शन को कॉल करता है और वह कोड सांप को तदनुसार ले जाता है। पिन 9 का उपयोग साउंड पिन के रूप में किया जाता है क्योंकि यह एक PWM (~ पल्स चौड़ाई मॉड्यूलेशन) है जो सीधे + पिन पर 5v पीजो से जुड़ा होता है और - 0v/ग्राउंड पर वापस चला जाता है।

(Arduino uno और क्लोन पर FYI करें केवल d2 और d3 इंटरप्ट अनुरोध पिन के रूप में कार्य कर सकते हैं)।

दिशा पिन:

d4 ऊपर ऑरेंज

d5 नीचे गुलाबी

d6 बायां नीला

d7 दायां भूरा

d9 ध्वनि ग्रे

प्रत्येक बटन में 5v कनेक्शन इनपुट और एक आउटपुट होता है जो पहले arduino पर उनके संबंधित डिजिटल इनपुट से जुड़ा होता है, प्रत्येक बटन का यही आउटपुट फिर अपने डायोड से जुड़ा होता है, हम डायोड का उपयोग वोल्टेज फीडिंग को रोकने के लिए करते हैं। अन्य बटन और उन्हें सक्रिय करना। सभी 4 डायोड के कैथोड (-) छोर पर हम एक आउटपुट जंक्शन बनाने के लिए एक साथ जुड़ते हैं जो d3 से जुड़ता है और फिर एक रेसिस्टर के माध्यम से 0v/धरती के माध्यम से आर्डिनो पिन को कम खींचता है ताकि फ्लोटिंग पिन को नहीं छोड़ा जा सके। सक्रिय।

(FYI करें एक फ्लोटिंग पिन प्रेत वोल्टेज प्राप्त कर सकता है और असामान्य व्यवहार का कारण बन सकता है)

डिस्प्ले को चलाने के लिए 2 एनालॉग पिन का उपयोग किया जाता है, ये arduino हार्डवेयर i2c पिन हैं।

A5 SCL येलो से जुड़ा है

A4 एसडीए ग्रीन से जुड़ा है

Arduino से +5v और 0v (पृथ्वी) आउटपुट का उपयोग पूरे सर्किट के लिए शक्ति के स्रोत के रूप में किया जाता है जिसे USB या फोन चार्जर द्वारा संचालित किया जा सकता है।

चरण 2: कोड

//------------------------ अंजावरे सांप के खेल नेट लोगों की मदद से --------------- --------

#शामिल

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // डिस्प्ले सेट (चौड़ाई, ऊंचाई) Adafruit_SSD1306 डिस्प्ले (128, 64); // इनपुट पिन को परिभाषित करें ये arduino पर पिन हैं जो वे कभी नहीं बदलते हैं इसलिए #define #define INTPIN 3 // केवल पिन 2 और 3 UNO पर इंटरप्ट पिन हो सकते हैं #define UPPIN 4 // ये पिन से जुड़े tp प्रासंगिक स्विच #define हैं DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // दिशाओं को परिभाषित करें #define DIRUP 1 // ये मान हैं जो "साँप" तय करने के लिए देखता है- #define DIRDOWN 2 // जिस दिशा में सांप यात्रा करेगा # DIRLEFT 3 को परिभाषित करें #DIRRIGHT 4 परिभाषित करें

// बटन चर सेट करें

// अस्थिर क्योंकि हमें इसे इंटरप्ट के साथ अपडेट करने की आवश्यकता है, इसलिए चक्र मूल्य का कोई भी बिट हो सकता है

// कभी भी 4 से अधिक नहीं होता है इसलिए संसाधनों को बचाने के लिए केवल 8bit int की आवश्यकता होती है अस्थिर uint8_t बटनप्रेस = 0; बूल बटअप = 0; बूल बटडाउन = 0; // हम इसका उपयोग "पता लगाने" के लिए सही सेट करने के लिए करते हैं कि किस दिशा में बूल बटलेफ्ट = 0 दबाया गया; बूल बटराइट = 0;

// सांप ints

बाइट स्नेकPosX [३०]; // सर्प बाइट स्नेकपोसी का शरीर बनाने के लिए सरणी [३०];

इंट स्नेकएक्स = 30; // सांप के सिर की स्थिति

इंट स्नेकवाई = 30; इंट स्नेकसाइज = 1; // सांप के आकार की गिनती सरणी के आकार तक सीमित है

// दुनिया ints

uint8_t दुनियामिनएक्स = 0; // ये खेल क्षेत्र की सीमा निर्धारित करते हैं

uint8_t वर्ल्डमैक्स = 128; uint8_t दुनियामिनी=10; uint8_t वर्ल्डमैक्सवाई=63;

// स्कैन (भोजन) और स्कैन की स्थिति एकत्र करें

बूल स्क्रैनएट = 0; uint8_t स्कैनपोसएक्स = 0; uint8_t स्कैनपोसवाई = 0;

// स्कोर चर

लंबा प्लेस्कोर = 0; लंबा हाईस्कोर = 30; // प्रारंभिक बिंदु के रूप में 3 संग्रह के लिए उच्च स्कोर सेट करें

//-------------------------- वोल्टेज बढ़ने पर यह इंटरप्ट निष्पादित होता है ------------- -------------

शून्य बाधित () {देरी (150); // जोड़ा "बाउंस" सुरक्षा अद्यतन दिशा () के लिए थोड़ी देरी; } // ------------------ बटन प्रेस से दिशा मान अपडेट करें ----------------- शून्य अद्यतन दिशा () { // Serial.println ("अपडेटिंग डायरेक्शन"); बटअप = डिजिटल रीड (यूपीपीआईएन); // जांचें कि कौन सा इनपुट उच्च चला गया और प्रासंगिक बूल ट्रू बटडाउन = डिजिटलरेड (DWNPIN) सेट करें; बटलेफ्ट = डिजिटल रीड (एलएफटीपिन); butright=digitalRead(RHTPIN); // ये अगर स्टेटमेंट देखते हैं कि कौन सा इनपुट उच्च गया और "बटनप्रेस्ड" // वेरिएबल में प्रासंगिक मान में प्रवेश करता है, तो यह वेरिएबल मूवमेंट की दिशा तय करता है अगर (butup == true) {buttonpressed=DIRUP; // Serial.println ("यूपी दबाया गया"); // सीरियल.प्रिंट्लन (बटनप्रेस्ड); बटअप = झूठा; टोन (एसएनडी, 1500, 10); } अगर (बटडाउन == सच) {बटनप्रेस = डरडाउन; // Serial.println ("नीचे दबाया गया"); // सीरियल.प्रिंट्लन (बटनप्रेस्ड); बटडाउन = झूठा; टोन (एसएनडी, 1500, 10); }

अगर (लेकिन बाएं == सच)

{बटनप्रेस्ड = डिरलेफ्ट; // Serial.println ("बाएं दबाया गया"); // सीरियल.प्रिंट्लन (बटनप्रेस्ड); बटलेफ्ट = झूठा; टोन (एसएनडी, 1500, 10); } अगर (लेकिन सही == सच) {बटन दबाया = सही; // Serial.println ("राइट दबाया गया"); // सीरियल.प्रिंट्लन (बटनप्रेस्ड); बटराइट = झूठा; टोन (एसएनडी, 1500, 10); } }

//-------------------------- डिस्प्ले रूटीन ड्रा करें--------------------- -----------------

शून्य अद्यतन प्रदर्शन () // स्कोर और रूपरेखा तैयार करें

{// Serial.println ("अपडेट डिस्प्ले");

display.fillRect(0, 0, display.width()-1, 8, BLACK);

डिस्प्ले.सेटटेक्स्टसाइज (0); display.setTextColor (सफेद); // ड्रा स्कोर डिस्प्ले।सेट कर्सर (2, 1); डिस्प्ले.प्रिंट ("स्कोर:"); डिस्प्ले.प्रिंट (स्ट्रिंग (प्लेस्कोर, डीईसी)); डिस्प्ले.सेट कर्सर (66, 1); डिस्प्ले.प्रिंट ("उच्च:"); डिस्प्ले.प्रिंट (स्ट्रिंग (हाईस्कोर, डीईसी)); // ड्रा प्ले एरिया // पॉज़ 1x, 1y, 2x, 2y, कलर डिस्प्ले। ड्रालाइन (0, 0, 127, 0, व्हाइट); // बहुत शीर्ष सीमा प्रदर्शन। ड्रालाइन (63, 0, 63, 9, सफेद); // स्कोर सेपरेटर डिस्प्ले। ड्रालाइन (0, 9, 127, 9, व्हाइट); // टेक्स्ट बॉर्डर डिस्प्ले के नीचे। ड्रालाइन (0, 63, 127, 63, व्हाइट); // निचला बॉर्डर डिस्प्ले। ड्रालाइन (0, 0, 0, 63, व्हाइट); // लेफ्ट बॉर्डर डिस्प्ले। ड्रालाइन (127, 0, 127, 63, व्हाइट); // दाहिनी सीमा

}

//------------------------------------- अद्यतन खेल क्षेत्र ---------- ------------------------

शून्य अपडेटगेम () // यह गेम एरिया डिस्प्ले को अपडेट करता है

{डिस्प्ले। क्लियरडिस्प्ले ();

display.drawPixel (scranPosX, scanPosY, WHITE);

स्क्रैनएट = स्क्रैनफूड ();

// सांप की दिनचर्या की जाँच करें

अगर (आउटऑफएरिया ()||सेल्फकॉलिशन ())

{ खेल खत्म(); }

// सांप प्रदर्शित करें

for(int i=0;i0;i--) {स्नेकपॉसएक्स = स्नेकपॉसएक्स[i-1]; स्नेकपोसी = स्नेकपोसी [i-1]; } // सांप में एक अतिरिक्त पिक्सेल जोड़ें अगर (स्क्रैनएट) {सांपसाइज + = 1; सांपपोसएक्स [सांप आकार -1] = सांपएक्स; सांप पॉसी [सांप आकार -1] = सांप वाई; }

स्विच (बटनप्रेस्ड) // स्नेकडायरेक्शन था

{केस डीआईआरयूपी: स्नेकवाई- = 1; टूटना; केस DIRDOWN: साँपY+=1; टूटना; मामला DIRLEFT: सांपएक्स- = 1; टूटना; केस DIRRIGHT: स्नेकएक्स+=1; टूटना; } सांपपोसएक्स [0] = सांपएक्स; स्नेकपोसी [0] = स्नेकवाई; अद्यतन प्रदर्शन (); डिस्प्ले.डिस्प्ले (); // --------------------- स्कैन लगाएं -------------------

शून्य स्थानस्कैन ()

{scranPosX=random(worldMinX+1, worldMaxX-1); scranPosY=random(worldMinY+1, worldMaxY-1); } //-------------------------- स्कैन ने प्वाइंट अप खाया ---------------- बूल स्कैनफूड () {अगर (स्नेकएक्स==स्क्रैनपॉसएक्स&&स्नेकवाई==स्क्रैनपॉसी) {प्लेस्कोर=प्लेस्कोर+10; टोन (एसएनडी, 2000, 10); अद्यतन प्रदर्शन (); प्लेसक्रैन (); वापसी १; } और {वापसी 0; } } //--------------------- इलाके से बाहर---------------------- बूल आउटऑफएरिया () {रिटर्न स्नेकएक्स =वर्ल्डमैक्स ||स्नेकवाई=वर्ल्डमैक्स; } //---------------------- खेल खत्म----------------------- --- शून्य गेमओवर () {uint8_t rectX1, rectY1, rectX2, rectY2; रेक्टएक्स1=38; रेक्टवाई1=28; रेक्टएक्स2=58; रेक्टवाई2=12; डिस्प्ले.क्लियरडिस्प्ले (); डिस्प्ले.सेट कर्सर (40, 30); display.setTextSize(1); टोन (एसएनडी, 2000, 50); डिस्प्ले.प्रिंट ("गेम"); टोन (एसएनडी, 1000, 50); डिस्प्ले.प्रिंट ("ओवर"); अगर (प्लेस्कोर> = हाईस्कोर) // यह देखने के लिए जांचें कि क्या स्कोर उच्च स्कोर से अधिक है {हाईस्कोर = प्लेस्कोर; // सिंगल इफ स्टेटमेंट टू अपडेट हाई स्कोर} फॉर (इंट आई = 0; आई <= 16; आई ++) Serial.println ("अगर लूप"); डिस्प्ले.डिस्प्ले (); rectX1-=2; // 2 पिक्सेल द्वारा शिफ्ट करें rectY1-=2; rectX2+=4; // अंतिम बिंदु rectY2+=4 से 2 पिक्सेल से अधिक शिफ्ट करें; टोन (एसएनडी, आई * 200, 3); } डिस्प्ले.डिस्प्ले (); // rectX1=0 पर प्रसिद्धि के बाद स्क्रीन वाइप करें; // लाइन rectY1=0 की प्रारंभ स्थिति सेट करें; rectX2 = 0; रेक्टवाई2=63; के लिए (int i =0;i<=127;i++) { uint8_t cnt=0; display.drawLine (rectX1, rectY1, rectX2, rectY2, BLACK); रेक्टएक्स1++; रेक्टएक्स2++; डिस्प्ले.डिस्प्ले (); } डिस्प्ले.क्लियरडिस्प्ले (); प्लेस्कोर = 0; // सांप और खिलाड़ी के विवरण को रीसेट करें सांप का आकार = 1; सांपएक्स = डिस्प्ले। चौड़ाई ()/2; स्नेकवाई = डिस्प्ले। हाइट ()/2; प्रतीक्षाफोरप्रेस (); // खेल शुरू करने के लिए खिलाड़ी की प्रतीक्षा करें } //-------------------------- प्रेस लूप के लिए प्रतीक्षा करें ---------- --------------- शून्य प्रतीक्षाफोरप्रेस () { बूल प्रतीक्षा = 0; // लूप समाप्त होता है जब यह सही प्रदर्शन होता है। clearDisplay (); जबकि (प्रतीक्षा == 0) {drawALineForMe (सफेद); // एक यादृच्छिक सफेद रेखा खींचना drawALineForMe(BLACK); // एक यादृच्छिक काली रेखा बनाएं ताकि स्क्रीन पूरी तरह से सफेद डिस्प्ले न भरें।फिलरेक्ट (19, 20, 90, 32, ब्लैक); // टेक्स्ट डिस्प्ले के लिए रिक्त पृष्ठभूमि। सेटटेक्स्टकोलर (सफेद); डिस्प्ले.सेट कर्सर (३५, २५); display.setTextSize(2); // बड़ा फ़ॉन्ट डिस्प्ले।प्रिंटल ("स्नेक"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, सफेद); // बॉर्डर स्नेक डिस्प्ले। ड्रारेक्ट (19, 20, 90, 32, व्हाइट); // बॉर्डर बॉक्स - 3 डिस्प्ले।सेट कर्सर (28, 42); डिस्प्ले.सेटटेक्स्टसाइज (0); // फ़ॉन्ट सामान्य डिस्प्ले पर वापस आ जाता है। प्रिंट्लन ("कोई भी कुंजी दबाएं"); डिस्प्ले.डिस्प्ले (); प्रतीक्षा = digitalRead (INTPIN); // यह देखने के लिए जांचें कि बटन दबाए गए = 0 के दौरान कुंजी दबाए गए प्रतीक्षा 1 में बदल जाएगी या नहीं; // रीसेट बटन दबाएं } } //-------------------------- एक यादृच्छिक लाइन इनपुट रंग uint8_t-------------- खींचें ----- शून्य ड्राएलाइनफोरमी (uint8_t clr) { uint8_t line1X, line1Y, line2X, line2Y=0; // एक लाइन के लिए रैंडम को-ऑर्डिनेट्स सेट करें और फिर उसे ड्रा करें लाइन 1 वाई = यादृच्छिक (वर्ल्डमिनी + 1, वर्ल्ड मैक्सवाई -1); लाइन 2 एक्स = यादृच्छिक (वर्ल्डमिनएक्स + 1, वर्ल्डमैक्स -1); लाइन 2 वाई = यादृच्छिक (वर्ल्डमिनी + 1, वर्ल्ड मैक्सवाई -1); डिस्प्ले.ड्रालाइन (लाइन 1 एक्स, लाइन 1 वाई, लाइन 2 एक्स, लाइन 2 वाई, क्लियर); } //------------------------------------- टक्कर का पता लगाने -------- -----------------------

for(बाइट i=4;i<snakeSize;i++) {if(snakeX==snakePosX&&snakeY==snakePosy) {रिटर्न 1; टोन (एसएनडी, 2000, 20); टोन (एसएनडी, 1000, 20); } वापसी 0; }

//-------------------------------- सेट अप--------------- -----------------------------

शून्य सेटअप () {देरी (100); // बस सामान को "बूट" करने का मौका दें // Serial.begin(9600); // अगर आप सीरियल आउटपुट डिस्प्ले देखना चाहते हैं तो इसे अनचेक करें। (SSD1306_SWITCHCAPVCC, 0x3C); डिस्प्ले.क्लियरडिस्प्ले (); // एक साफ डिस्प्ले डिस्प्ले के साथ शुरू करें। सेटटेक्स्टकोलर (व्हाइट);// टेक्स्ट कलर रोटेशन साइज आदि डिस्प्ले सेट करें। display.setTextWrap (झूठा); डिस्प्ले.डिम (0); // डिस्प्ले ब्राइटनेस पिनमोड (INTPIN, INPUT) सेट करें; // पिनमोड (UPPIN, INPUT) इनपुट करने के लिए सही पोर्ट सेट करें; पिनमोड (DWNPIN, INPUT); पिनमोड (एलएफटीपिन, इनपुट); पिनमोड (RHTPIN, INPUT); // यह इंटरप्ट कमांड है जो इनपुट को पढ़ने के लिए आर्डिनो को "रोकता है" // Serial.println ("सेटअप पास हुआ"); प्रतीक्षाफोरप्रेस (); // स्नेक स्टार्ट अप स्क्रीन प्लेसक्रैन () प्रदर्शित करें; // भोजन का पहला हिस्सा रखें } //--------------------- मुख्य लूप ----------------- ---------------------- शून्य लूप () {अपडेटगेम (); // यह फ़ंक्शन वह है जो मुख्य कोड वहन करता है}

चरण 3:

सिफारिश की: