Съдържание:

Arduino OLED Игра на змия: 3 стъпки
Arduino OLED Игра на змия: 3 стъпки

Видео: Arduino OLED Игра на змия: 3 стъпки

Видео: Arduino OLED Игра на змия: 3 стъпки
Видео: Web Programming - Computer Science for Business Leaders 2016 2024, Ноември
Anonim
Arduino OLED Игра на змия
Arduino OLED Игра на змия

Здравейте и добре дошли, в нашите инструкции за това как да направим и arduino OLED игра, този проект възникна, докато се опитвахме да направим първата си игра с arduino, много, мислехме къде е по -добре да започнем от класическата змия на nokia (добре на поне змийски клонинг:)).

Какво ще ви трябва

Консумативи

Arduino UNO или клонинг

OLED дисплей

4 диода

500-1k резистор

4 бутона на контролера

Пасивен пиезо зумер

по избор

Бледна дъска без запояване

Моля, обърнете внимание, че тези връзки са само за пример

Стъпка 1: Веригата

Веригата
Веригата

На горната снимка можете да видите нашата схема, използваме щифт d3 на arduino като щифт за заявка за прекъсване, така че arduino ще даде приоритет на четенето на входовете на контролера, които са d4 d5 d6 d7. Основите на веригата са, че е натиснат бутон за посока, който достига високи 5v, това активира щифта за искане на прекъсване (d3 лилав проводник) и съответния посочен щифт, функцията за прекъсване извиква функция за посока на актуализация и този код премества змията съответно. Пин 9 се използва като звуков щифт, тъй като е ШИМ (~ модулация с широчина на импулса), който е свързан директно към 5v пиезо на + пина и - връща се към 0v/маса.

(FYI на arduino uno и клонингите само d2 и d3 могат да действат като щифтове за заявка за прекъсване).

Щифтове за посока:

d4 Нагоре ОРАНЖЕВ

d5 надолу розово

d6 Вляво СИН

d7 Дясно кафяво

d9 звук СИВ

Всеки бутон има вход за 5v връзка и изход, който е свързан първо към съответния им цифров вход на arduino, същият изход на всеки бутон след това се свързва със собствен диод, използваме диодите, за да спрем напрежението, което се връща обратно към други бутони и активирането им. В края на катода (-) на всичките 4 диода ги свързваме заедно, за да създадем изходно съединение, което се свързва към d3 и след това през резистора към 0v/земя, за да издърпаме щифтовете arduino ниско, за да не оставим плаващи щифтове, когато не са активиран.

(FYI плаващ щифт може да получи фантомно напрежение и да причини необичайно поведение)

2 аналогови пина се използват за задвижване на дисплея, това са хардуерните i2c щифтове на arduino.

A5 е свързан към SCL ЖЪЛТ

A4 е свързан към SDA GREEN

Изходът +5v и 0v (земя) от arduino се използва като източник на захранване за цялата верига, която може да се захранва от usb или зарядно устройство за телефон.

Стъпка 2: Кодът

// ------------------------ ANJAWARE ЗМИ Игри С помощта на мрежовите народи --------------- -------

#включва

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // набор от дисплеи (ширина, височина) Adafruit_SSD1306 дисплей (128, 64); // дефинирайте входните щифтове, това са щифтовете на arduino, които никога не се променят, така че #дефинирайте #дефинирайте INTPIN 3 // само щифтове 2 и 3 могат да бъдат прекъснати щифтове на UNO #дефинирайте UPPIN 4 // това са щифтове, свързани към съответния превключвател #дефинирайте DWNPIN 5 #дефинирайте LFTPIN 6 #дефинирайте RHTPIN 7 #дефинирайте SND 9 // дефинирайте посоки #дефинирайте DIRUP 1 // тези стойности е това, което "змията" гледа, за да реши- #дефинирайте DIRDOWN 2 // посоката, в която ще се движи змията # дефинирайте DIRLEFT 3 #дефинирайте DIRRIGHT 4

// задаване на променливи на бутоните

// volitile cos ние се нуждаем от него, за да актуализираме с прекъсване, така че може да бъде всеки бит от стойността на цикъла

// никога не е по -високо от 4, така че се нуждаем само от 8bit int, за да спестим ресурси променлив uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // използваме това, за да зададем true за "откриване" в коя посока е натиснат bool butleft = 0; bool butright = 0;

// змийски вдлъбнатини

байт snakePosX [30]; // масив за създаване на тяло от змийски байт snakePosY [30];

int snakeX = 30; // позиция на змийска глава

int змияY = 30; int snakeSize = 1; // брой на змии, ограничен до размера на масива

// световни ints

uint8_t worldMinX = 0; // те задават границите на зоната за игра

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

// събиране на scran (храна) и позиция на scran

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

// оценява променливите

дълго играе = 0; дълъг рекорд = 30; // поставете висок резултат на 3 събиране като отправна точка

// --------------------------- това е, което прекъсването се изпълнява при повишаване на напрежението ------------ -------------

void interruptpressed () {забавяне (150); // леко забавяне за добавена защита "bounce" updatedirection (); } // ------------------ актуализиране на стойността на посоката от натискане на бутона ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // проверява кой вход е висок и задава съответно bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // тези, ако statemeents разглеждат кой вход е висок и въвежда съответната стойност в "buttonpressed" // променливата, тази променлива диктува посоката на движение if (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP натиснат"); // Serial.println (натиснат бутон); butup = false; тон (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("НАДОЛУ натиснат"); // Serial.println (натиснат бутон); butdown = false; тон (SND, 1500, 10); }

ако (butleft == true)

{buttonpressed = DIRLEFT; // Serial.println ("ляв натиснат"); // Serial.println (натиснат бутон); butleft = false; тон (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("НАДЯСНО натиснат"); // Serial.println (натиснат бутон); butright = false; тон (SND, 1500, 10); }}

// -------------------------- начертайте подпрограмите на дисплея ------------------ -----------------

void updateDisplay () // теглене на резултати и очертания

{// Serial.println ("Актуализиране на дисплея");

display.fillRect (0, 0, display.width ()-1, 8, ЧЕРЕН);

display.setTextSize (0); display.setTextColor (БЯЛ); // теглене на резултати display.setCursor (2, 1); display.print ("Резултат:"); display.print (Низ (възпроизвеждане, DEC)); display.setCursor (66, 1); display.print ("Високо:"); display.print (Низ (рекорд, DEC)); // изчертаване на зона за игра // pos 1x, 1y, 2x, 2y, цветен дисплей.drawLine (0, 0, 127, 0, БЯЛ); // дисплей на най -горната граница.drawLine (63, 0, 63, 9, БЯЛ); // разделител на резултата display.drawLine (0, 9, 127, 9, БЯЛ); // под текстовата граница display.drawLine (0, 63, 127, 63, WHITE); // дисплей на долната граница.drawLine (0, 0, 0, 63, WHITE); // дисплей на лявата граница.drawLine (127, 0, 127, 63, БЯЛ); // дясна граница

}

// ----------------------------------- актуализиране на зоната за игра ---------- --------------------

void updateGame () // това актуализира дисплея на игровата област

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, БЯЛ);

scranAte = scranFood ();

// проверяваме змийските процедури

if (outOfArea () || selfCollision ())

{ играта приключи(); }

// показване на змия

for (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // добавя допълнителен пиксел към змията if (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

ключ (натиснат бутон) // беше snakeDirection

{случай DIRUP: snakeY- = 1; прекъсване; случай DIRDOWN: snakeY+= 1; прекъсване; калъф DIRLEFT: snakeX- = 1; прекъсване; калъф DIRRIGHT: snakeX+= 1; прекъсване; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- поставете скрана -------------------

празно място Scran ()

{scranPosX = случаен (worldMinX+1, worldMaxX-1); scranPosY = случаен (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; тон (SND, 2000, 10); updateDisplay (); placeScran (); връщане 1; } else {връщане 0; }} // --------------------- извън района ---------------------- bool outOfArea () {връщане snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- играта приключи----------------------- --- невалиден 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 ("ИГРА"); тон (SND, 1000, 50); display.print ("НАД"); if (playcore> = highscore) // проверете дали резултатът е по -висок от high score {highscore = playscore; // единичен, ако statment за актуализиране на висок резултат} за (int i = 0; i <= 16; i ++) // това е за привличане на правоъгълници около играта над {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("if цикъл"); display.display (); rectX1- = 2; // преместване с 2 пиксела rectY1- = 2; rectX2+= 4; // изместване над 2 пиксела от последната точка rectY2+= 4; тон (SND, i*200, 3); } display.display (); // Изтриване на екрана след известност над rectX1 = 0; // задаваме начална позиция на линия rectY1 = 0; rectX2 = 0; rectY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, ЧЕРЕН); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); playcore = 0; // нулиране на змия и подробности за играча snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // изчакайте играчът да започне играта} // ------------------------- изчакайте цикъла за преси ---------- --------------- void waitForPress () {bool wait = 0; // цикълът завършва, когато това е вярно display.clearDisplay (); while (чакане == 0) {drawALineForMe (БЯЛ); // изтегляне на произволна бяла линия drawALineForMe (BLACK); // начертайте произволна черна линия, така че екранът да не запълни напълно бял display.fillRect (19, 20, 90, 32, BLACK); // празен фон за показване на текст.setTextColor (БЯЛ); display.setCursor (35, 25); display.setTextSize (2); // по -голям шрифт display.println ("ЗМИЯ"); // x y w h r r display display.drawRoundRect (33, 22, 62, 20, 4, БЯЛ); // граничен змийски дисплей.drawRect (19, 20, 90, 32, БЯЛ); // гранично поле - 3 display.setCursor (28, 42); display.setTextSize (0); // шрифт обратно към нормален display.println ("натиснете произволен клавиш"); display.display (); чакане = digitalRead (INTPIN); // проверяваме дали натиснатият клавиш при изчакване ще се промени на 1 завършващ, докато buttonpressed = 0; // бутон за нулиране натиснете}} // -------------------- НАРИСУВАНЕ на цвят за въвеждане на произволен ред uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // задаваме произволни координати за линия, след което я изчертаваме // променлива не по-малко не повече line1X = случаен (worldMinX+1, worldMaxX-1); line1Y = случаен (worldMinY+1, worldMaxY-1); line2X = случаен (worldMinX+1, worldMaxX-1); line2Y = случаен (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- детекция на сблъсък -------- -----------------------

for (байт i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; тон (SND, 2000, 20); тон (SND, 1000, 20); } връщане 0; }

//-------------------------------- НАСТРОЙВАМ--------------- -------------------------------

void setup () {забавяне (100); // просто дайте шанс на нещата да се „заредят“// Serial.begin (9600); // махнете отметката от това, ако искате да видите серийните изходи display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // започваме с чист дисплей display.setTextColor (БЯЛ); // настройваме размера на ротация на цвета на текста и т.н. display.setRotation (0); display.setTextWrap (false); display.dim (0); // задаваме pinMode на яркостта на дисплея (INTPIN, INPUT); // задаваме правилните портове на входове pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // това е командата за прекъсване, която "спира" arduino за четене на входовете // команда-функция-пин-функция за изпълнение на условие за прикачване на пинInterrupt (digitalPinToInterrupt (INTPIN), прекъснато, RISING); // Serial.println ("Настройката е преминала"); waitForPress (); // показва екрана за стартиране на змията placeScran (); // поставете първото парче храна} // --------------------- ОСНОВНА КЪМА ----------------- ---------------------- void loop () {updateGame (); // тази функция носи основния код}

Стъпка 3:

Препоръчано: