সুচিপত্র:

Arduino OLED Snake Game: 3 ধাপ
Arduino OLED Snake Game: 3 ধাপ

ভিডিও: Arduino OLED Snake Game: 3 ধাপ

ভিডিও: Arduino OLED Snake Game: 3 ধাপ
ভিডিও: MAKE THIS ARDUINO GAME, CODE INCLUDED! 2024, নভেম্বর
Anonim
Arduino OLED সাপের খেলা
Arduino OLED সাপের খেলা

হাই এবং স্বাগত, কিভাবে OLED গেম তৈরি এবং arduino আমাদের নির্দেশাবলীতে, এই প্রকল্পটি এসেছিল যখন আমরা একটি arduino, soooo দিয়ে আমাদের প্রথম খেলা করার চেষ্টা করছিলাম, আমরা ভেবেছিলাম নকিয়া ক্লাসিক সাপের চেয়ে কোথায় শুরু করা ভাল (ভাল অন্তত একটি সাপের ক্লোন:))।

আপনার যা দরকার

সরবরাহ

আরডুইনো ইউএনও বা ক্লোন

OLED ডিসপ্লে

4 ডায়োড

500-1k প্রতিরোধক

4 নিয়ামক বোতাম

প্যাসিভ পাইজো বুজার

চ্ছিক

Solderless BreadBoard

দয়া করে মনে রাখবেন এই লিঙ্কগুলি শুধুমাত্র উদাহরণস্বরূপ

ধাপ 1: সার্কিট

সার্কিট
সার্কিট

উপরের ছবিতে আপনি আমাদের সার্কিট দেখতে পাচ্ছেন, আমরা arduino- এ পিন d3 ব্যাবহারের অনুরোধ পিন হিসেবে ব্যবহার করি যাতে arduino নিয়ামক ইনপুট পড়ার ক্ষেত্রে অগ্রাধিকার দেয় যা d4 d5 d6 d7। সার্কিটের মূল বিষয় হল যে একটি দিকনির্দেশ বোতাম চাপানো হয় যা উচ্চ 5v যায় এটি ইন্টারাপ্ট রিকোয়েস্ট পিন (d3 বেগুনি তার) এবং একটি সংশ্লিষ্ট দিকের পিন সক্রিয় করে, ইন্টারাপ্ট ফাংশন একটি আপডেট দিক ফাংশনকে কল করে এবং সেই কোড সেই অনুযায়ী সাপকে সরায়। পিন 9 শব্দ পিন হিসাবে ব্যবহৃত হয় কারণ এটি একটি PWM (~ পালস প্রস্থ মড্যুলেশন) যা সরাসরি + পিনে 5v পাইজোর সাথে সংযুক্ত থাকে এবং - 0v/স্থলে ফিরে যায়।

(Arduino uno এ FYI এবং শুধুমাত্র d2 এবং d3 ক্লোন ইন্টারাপ্ট রিকোয়েস্ট পিন হিসেবে কাজ করতে পারে)।

নির্দেশ পিন:

d4 আপ কমলা

d5 ডাউন পিঙ্ক

d6 বাম নীল

d7 ডান ব্রাউন

d9 সাউন্ড গ্রে

প্রতিটি বোতামে একটি 5v সংযোগ ইনপুট এবং একটি আউটপুট যা প্রথমে তাদের নিজ নিজ ডিজিটাল ইনপুটের সাথে আরডুইনোতে সংযুক্ত থাকে, প্রতিটি বোতামের এই একই আউটপুট তারপর তার নিজস্ব ডায়োডের সাথে সংযুক্ত থাকে, আমরা ডায়োড ব্যবহার করে ভোল্টেজ ফিডিং বন্ধ করতে অন্যান্য বোতাম এবং সেগুলি সক্রিয় করা। সমস্ত 4 ডায়োডের ক্যাথোড (-) প্রান্তে আমরা তাদের সাথে একত্রিত হয়ে একটি আউটপুট জংশন তৈরি করি যা d3 এর সাথে সংযোগ স্থাপন করে এবং তারপর 0v/পৃথিবীতে একটি প্রতিরোধকের মাধ্যমে arduino পিনগুলি কম টেনে আনে যাতে ভাসমান পিনগুলি না থাকাকালীন সক্রিয়।

(FYI একটি ভাসমান পিন ফ্যান্টম ভোল্টেজ গ্রহণ করতে পারে এবং অস্বাভাবিক আচরণের কারণ হতে পারে)

ডিসপ্লে চালানোর জন্য 2 টি এনালগ পিন ব্যবহার করা হয়, এগুলো হল arduino হার্ডওয়্যার i2c পিন।

A5 SCL YELLOW এর সাথে সংযুক্ত

A4 SDA GREEN এর সাথে সংযুক্ত

আরডুইনো থেকে +5v এবং 0v (আর্থ) আউটপুট পুরো সার্কিটের শক্তির উৎস হিসাবে ব্যবহৃত হয় যা ইউএসবি বা ফোন চার্জার দ্বারা চালিত হতে পারে।

ধাপ 2: কোড

// ------------------------ নেট জনগণের সাহায্যে আনজোয়ার সাঁকে গেম -------

#অন্তর্ভুক্ত

#অন্তর্ভুক্ত // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // display set (width, height) Adafruit_SSD1306 display (128, 64); // ইনপুট পিন সংজ্ঞায়িত করুন এগুলি আরডুইনোতে থাকা পিনগুলি তারা কখনই পরিবর্তন করে না তাই #ডিফাইন #ডিফাইন ইনটিপিন 3 // শুধুমাত্র পিন 2 এবং 3 ইউএনও তে ইন্টারপুট পিন হতে পারে #ডিফাইন ইউপিন 4 // এই পিন সংযুক্ত টিপি প্রাসঙ্গিক সুইচ #ডিফাইন DWNPIN 5 #ডিফাইন এলএফটিপিআইএন 6 #ডিফাইন RHTPIN 7 #ডিফাইন এসএনডি 9 // দিকনির্দেশ দিন #ডিফাইন ডাইরুপ 1 // এই মানগুলি "সাপ" সিদ্ধান্ত নেওয়ার দিকে তাকিয়ে থাকে- DIRLEFT 3 সংজ্ঞায়িত করুন #DIRRIGHT 4 নির্ধারণ করুন

// সেট বোতাম ভেরিয়েবল

// ভলিটিল কারণ আমরা এটি ইন্টারপুট সঙ্গে আপডেট করার জন্য প্রয়োজন তাই চক্র মান কোন বিট হতে পারে

// কখনই 4 এর চেয়ে বেশি নয় তাই অস্থিতিশীল uint8_t buttonpressed = 0 সংরক্ষণ করতে কেবল 8bit int প্রয়োজন। bool butup = 0; bool butdown = 0; // আমরা এটিকে "সনাক্ত করতে" সত্য সেট করতে ব্যবহার করি কোন দিকটি বুল বাটলেফট = 0 টিপছে; bool butright = 0;

// সাপ ints

বাইট স্নেকপসএক্স [30]; // সাপের বাইট সাপের শরীর তৈরির জন্য অ্যারে [30];

int snakeX = 30; // সাপের মাথার অবস্থান

int snakeY = 30; int snakeSize = 1; // সাপের আকার গণনা অ্যারের আকারের মধ্যে সীমাবদ্ধ

// বিশ্ব ints

uint8_t worldMinX = 0; // এইগুলি খেলার ক্ষেত্রের সীমা নির্ধারণ করে

uint8_t worldMaxX = 128; uint8_t worldMinY = 10; uint8_t worldMaxY = 63;

// স্ক্রান (খাদ্য) এবং স্ক্রানের অবস্থান সংগ্রহ করুন

bool scranAte = 0; uint8_t scranPosX = 0; uint8_t scranPosY = 0;

// স্কোর ভেরিয়েবল

দীর্ঘ নাটক = 0; দীর্ঘ উচ্চমান = 30; // একটি প্রারম্ভিক বিন্দু হিসাবে সংগ্রহ 3 উচ্চ স্কোর সেট

// ---------------------- -------------

অকার্যকর interruptpressed () {বিলম্ব (150); // যোগ করা "বাউন্স" সুরক্ষার জন্য সামান্য বিলম্ব আপডেট নির্দেশনা (); } // ------------------ বাটন প্রেস থেকে দিকের মান আপডেট করুন ----------------- ভয়েড আপডেট নির্দেশনা () { // Serial.println ("আপডেট করার দিকনির্দেশ"); butup = digitalRead (UPPIN); // যাচাই করুন কোন ইনপুট উচ্চতর হয়েছে এবং প্রাসঙ্গিক বুল ট্রু butdown = digitalRead (DWNPIN) সেট করুন; butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // এইগুলি যদি স্টেটমেন্টগুলি দেখে যে কোন ইনপুট বেশি হয়েছে এবং "buttonpressed" // ভেরিয়েবলে প্রাসঙ্গিক মান প্রবেশ করে, এই পরিবর্তনশীলটি আন্দোলনের দিক নির্দেশ করে যদি (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP চাপানো"); // Serial.println (buttonpressed); butup = মিথ্যা; স্বর (SND, 1500, 10); } যদি (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOWN চাপা"); // Serial.println (buttonpressed); butdown = মিথ্যা; স্বর (SND, 1500, 10); }

যদি (butleft == true)

{buttonpressed = DIRLEFT; // Serial.println ("LEFT pressed"); // Serial.println (buttonpressed); butleft = মিথ্যা; স্বর (SND, 1500, 10); } যদি (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("RIGHT চাপা"); // Serial.println (buttonpressed); butright = মিথ্যা; স্বর (SND, 1500, 10); }}

// -------------------------- প্রদর্শন রুটিন আঁকা ------------------ -----------------

অকার্যকর আপডেট প্রদর্শন () // স্কোর এবং রূপরেখা আঁকুন

{// Serial.println ("আপডেট ডিসপ্লে");

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

display.setTextSize (0); display.setTextColor (সাদা); // অঙ্ক স্কোর display.setCursor (2, 1); display.print ("স্কোর:"); display.print (স্ট্রিং (প্লেস্কোর, DEC)); display.setCursor (66, 1); display.print ("High:"); display.print (স্ট্রিং (হাইস্কোর, DEC)); // ড্র খেলার এলাকা // পোজ 1x, 1y, 2x, 2y, কালার ডিসপ্লে।ড্রলাইন (0, 0, 127, 0, হোয়াইট); // খুব উপরের সীমানা প্রদর্শন। DrawLine (63, 0, 63, 9, সাদা); // স্কোর বিভাজক display.drawLine (0, 9, 127, 9, সাদা); // নীচের টেক্সট বর্ডার ডিসপ্লে। DrawLine (0, 63, 127, 63, WHITE); // নিচের সীমানা প্রদর্শন। DrawLine (0, 0, 0, 63, সাদা); // বাম সীমান্ত প্রদর্শন। DrawLine (127, 0, 127, 63, সাদা); // ডান সীমানা

}

// ----------------------------------- খেলার এলাকা আপডেট করুন ---------- --------------------

void updateGame () // এটি গেম এরিয়া ডিসপ্লে আপডেট করে

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, White);

scranAte = scranFood ();

// সাপের রুটিন চেক করুন

if (outOfArea () || selfCollision ())

{ খেলা শেষ(); }

// প্রদর্শন সাপ

জন্য (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; সর্পপোসি = সর্পপোসি [আই -1]; } // সাপে অতিরিক্ত পিক্সেল যোগ করুন যদি (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = সর্পএক্স; সর্পপসাই [সাপসাইজ -১] = সর্পওয়াই; }

সুইচ (বাটন চাপানো) // ছিল সাপ নির্দেশ

{case DIRUP: snakeY- = 1; বিরতি; কেস ডারডাউন: স্নেকওয়াই+= 1; বিরতি; কেস DIRLEFT: snakeX- = 1; বিরতি; কেস ডিরিঘট: সর্পএক্স+= 1; বিরতি; } snakePosX [0] = snakeX; SnakePosY [0] = snakeY; আপডেট ডিসপ্লে (); display.display (); // --------------------- স্ক্রান রাখুন -------------------

অকার্যকর স্থান স্ক্রান ()

{scranPosX = এলোমেলো (worldMinX+1, worldMaxX-1); scranPosY = এলোমেলো (worldMinY+1, worldMaxY-1); } // ------------------------ স্ক্রেন এটে পয়েন্ট আপ ---------------- বুল স্ক্রানফুড () {যদি (snakeX == scranPosX && snakeY == scranPosY) {playcore = playcore+10; স্বর (SND, 2000, 10); আপডেট ডিসপ্লে (); placeScran (); ফেরত 1; } অন্য {রিটার্ন 0; } } //--------------------- এলাকার বাইরে---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- খেলা শেষ----------------------- --- void gameOver () {uint8_t rectX1, rectY1, rectX2, rectY2; rectX1 = 38; rectY1 = 28; rectX2 = 58; rectY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); স্বর (SND, 2000, 50); display.print ("GAME"); স্বর (SND, 1000, 50); display.print ("OVER"); যদি (playscore> = highscore) // চেক করে দেখুন উচ্চ স্কোরের চেয়ে বেশি স্কোর {highscore = playscore; // একক যদি স্ট্যাটমেন্টটি উচ্চ স্কোর আপডেট করে} এর জন্য (int i = 0; i <= 16; i ++) // এটি হল {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE) এর উপর খেলার চারপাশে আয়তক্ষেত্র আঁকতে; Serial.println ("if loop"); display.display (); rectX1- = 2; // 2 পিক্সেল দ্বারা স্থানান্তর rectY1- = 2; rectX2+= 4; // শেষ বিন্দু recty2+= 4 থেকে 2 পিক্সেলের উপর স্থানান্তর; স্বর (SND, i*200, 3); } display.display (); // rectX1 = 0 এর উপর খ্যাতির পরে স্ক্রিন মুছুন; // লাইন rectY1 = 0 এর শুরুর অবস্থান সেট করুন; rectX2 = 0; rectY2 = 63; জন্য (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, BLACK); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); প্লেস্কোর = 0; // রিসেট সাপ এবং প্লেয়ার বিবরণ সর্প সাইজ = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // খেলোয়াড়ের খেলা শুরুর জন্য অপেক্ষা করুন} // ------------------------- প্রেস লুপের জন্য অপেক্ষা করুন ---------- --------------- void waitForPress () {bool wait = 0; // লুপ শেষ হয় whjen এটি সত্য display.clearDisplay (); যখন (অপেক্ষা == 0) {drawALineForMe (সাদা); // একটি এলোমেলো সাদা রেখা drawALineForMe (BLACK) আঁকুন; // একটি এলোমেলো কালো রেখা আঁকুন যাতে পর্দা পুরোপুরি সাদা ডিসপ্লে পূরণ না করে। ফিলরেক্ট (19, 20, 90, 32, কালো); // টেক্সট প্রদর্শনের জন্য ফাঁকা পটভূমি। display.setCursor (35, 25); display.setTextSize (2); // বড় ফন্ট display.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // সীমানা সাপ প্রদর্শন। DrawRect (19, 20, 90, 32, সাদা); // সীমানা বাক্স - 3 display.setCursor (28, 42); display.setTextSize (0); // স্বাভাবিক ডিসপ্লেতে ফন্ট ফিরে। display.display (); অপেক্ষা = ডিজিটাল রিড (INTPIN); // চাপা চাপা অপেক্ষা 1 শেষ হলে পরিবর্তিত হবে কিনা তা দেখুন বাটনপ্রেসড = 0; // রিসেট বাটন চাপুন}} // -------------------- একটি এলোমেলো রেখার ইনপুট রঙ আঁকুন uint8_t -------------- ----- অকার্যকর drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // একটি লাইনের জন্য এলোমেলো কো-অর্ডিনেট সেট করুন তারপর এটি আঁকুন // ভেরিয়েবল কম কোন লাইন 1X = এলোমেলো (worldMinX+1, worldMaxX-1); লাইন 1Y = এলোমেলো (worldMinY+1, worldMaxY-1); line2X = এলোমেলো (worldMinX+1, worldMaxX-1); line2Y = এলোমেলো (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- সংঘর্ষ বিচ্ছেদ -------- -----------------------

জন্য (বাইট i = 4; i <snakeSize; i ++) {যদি (snakeX == snakePosX && snakeY == snakePosy ) {return 1; স্বর (SND, 2000, 20); স্বর (SND, 1000, 20); } রিটার্ন 0; }

// -------------------------------- সেটআপ --------------- -------------------------------

অকার্যকর সেটআপ () {বিলম্ব (100); // শুধু জিনিসগুলিকে "বুট" করার সুযোগ দিন // Serial.begin (9600); // যদি আপনি সিরিয়াল আউটপুট display.begin দেখতে চান তবে এটি আনচেক করুন (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // একটি পরিষ্কার প্রদর্শন display.setTextColor (সাদা) দিয়ে শুরু করুন; // পাঠ্য রঙ ঘূর্ণন আকার ইত্যাদি প্রদর্শন সেট করুন display.setTextWrap (মিথ্যা); display.dim (0); // প্রদর্শন উজ্জ্বলতা পিনমোড সেট করুন (INTPIN, INPUT); // ইনপুট পিনমোডে সঠিক পোর্ট সেট করুন (UPPIN, INPUT); পিনমোড (DWNPIN, ইনপুট); পিনমোড (এলএফটিপিন, ইনপুট); পিনমোড (RHTPIN, ইনপুট); // এটি ইন্টারপুট কমান্ড যা আর্ডুইনোকে ইনপুট পড়ার জন্য "থামায়" // কমান্ড-ফাংশন-পিন-ফাংশনটি পিন অ্যাটাচ ইন্টারট্রাপ্ট (ডিজিটালপিন্টোইন্টারপার্ট (আইএনটিপিআইএন), ইন্টারাপ্টপ্রেসড, রাইজিং) -এ চালানোর শর্ত; // Serial.println ("সেটআপ পাস"); waitForPress (); // সাপ স্টার্ট আপ স্ক্রিন প্লেসস্ক্রান () প্রদর্শন করুন; // খাবারের প্রথম বিট রাখুন} // --------------------- প্রধান লুপ ----------------- ---------------------- অকার্যকর লুপ () {updateGame (); // এই ফাংশনটি মূল কোড বহন করে}

ধাপ 3:

প্রস্তাবিত: