Мазмуну:

Arduino OLED жылан оюну: 3 кадам
Arduino OLED жылан оюну: 3 кадам

Video: Arduino OLED жылан оюну: 3 кадам

Video: Arduino OLED жылан оюну: 3 кадам
Video: Aurduino Snake Project 2024, Ноябрь
Anonim
Arduino OLED жылан оюну
Arduino OLED жылан оюну

Салам, кош келиңиз, биздин OLED Оюнду кантип жасоо боюнча көрсөтмөлөрүбүзгө, бул долбоор биз биринчи оюнубузду arduino, soooo менен ойногонго аракет кылып жатканда пайда болду, биз nokia классикалык Жыланга караганда кайсы жерден баштоо керек деп ойлодук. жок дегенде жыландын клону:)).

Сизге эмне керек болот

Жабдуулар

Arduino UNO же клон

OLED дисплей

4 диоддор

500-1k каршылыгы

4 контроллер баскычы

Пассивдүү пьезо сигналы

милдеттүү эмес

Solderless BreadBoard

Бул шилтемелер мисалы үчүн гана экенин эске алыңыз

1 -кадам: Circuit

Circuit
Circuit

Жогорудагы сүрөттө сиз биздин схеманы көрө аласыз, биз arduino d3 d3 d4 d5 d6 d7 болгон контроллердин кириштерин окууга артыкчылык бериши үчүн үзгүлтүккө учуратуучу пин катары колдонобуз. Райондун негиздери - бул 5в бийиктикке карай багыттоо баскычы басылганда, ал үзгүлтүккө учуроо пинин (d3 кызгылт көк зым) жана тийиштүү багыт пинин иштетет, үзгүлтүк функциясы жаңыртуу багытынын функциясын чакырат жана бул код жыланды ошого жараша жылдырат. Pin 9 үн казыгы катары колдонулат, анткени ал PWM (~ импульстун туурасы модуляциясы) + пиндеги 5v пьезого түз туташкан жана - 0v/жерге кайра кайтат.

(Arduino uno жана d2 жана d3 клондору боюнча FYI үзгүлтүккө учуроо пиндери катары иштей алат).

Багыт казыктары:

d4 ӨРТҮН

d5 Down PINK

d6 Сол КӨК

d7 Right BROWN

d9 үн GRAY

Ар бир баскычтын 5v туташуусундагы кириши жана адегенде ардуинодогу тиешелүү санариптик кирүүсүнө туташкан чыгышы бар, ар бир баскычтын ушул эле чыгышы өз диодуна туташат, диоддорду кайра чыңалууну токтотуу үчүн колдонобуз. башка баскычтар жана аларды иштетүү. Катоддо (-) бардык 4 диоддун аягында биз d3 менен туташкан чыгуу түйүнүн түзүү үчүн аларды бириктиребиз, андан кийин резистор аркылуу 0v/жерге чейин ардуино казыктарын төмөн түшүрүү үчүн калкып жүрүүчү казыктарды калтырбоо үчүн. иштетилди.

(FYI калкып жүрүүчү пин фантомдук чыңалууну кабыл алып, адаттан тыш жүрүм -турумга алып келиши мүмкүн)

Дисплейди айдоо үчүн 2 аналогдук казык колдонулат, булар arduino аппараттык i2c казыктары.

A5 SCL YELLOW менен туташкан

A4 SDA GREEN менен туташкан

Ардуинодон +5v жана 0v (жер) чыгышы USB же телефон заряддагыч түзүлүш аркылуу иштей турган бүтүндөй схема үчүн энергия булагы катары колдонулат.

2 -кадам: Код

// ------------------------ ANJAWARE ЖЫЛАН оюндары Таза элдердин жардамы менен --------------- -------

#кошуу

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // дисплей топтому (туурасы, бийиктиги) Adafruit_SSD1306 дисплейи (128, 64); // кирүү казыктарын аныктаңыз, бул алар эч качан өзгөрбөй турган ардуинодогу казыктар #аныктоо #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 interuppt менен жаңыртууга муктажбыз, андыктан циклдин кандайдыр бир мааниси болушу мүмкүн

// эч качан 4төн жогору болбойт, андыктан ресурстарды сактоо үчүн 8bit int гана керек uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // биз муну чындыкты коюу үчүн колдонобуз bool butleft = 0 кайсы багытта басылганын "аныктоо" үчүн; bool butright = 0;

// жылан инт

байт snakePosX [30]; // массив денени жасоо үчүн жылан байт snakePosY [30];

int snakeX = 30; // жыландын баш абалы

int snakeY = 30; int snakeSize = 1; // жыландын өлчөмү массивдин өлчөмү менен чектелген

// дүйнөлүк инт

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кө баштапкы чекит катары коюңуз

// --------------------------- бул чыңалуунун жогорулашында интерупт аткарган нерсе ------------ -------------

void interruptpressed () {delay (150); // кошулган "секирүү" коргоо үчүн бир аз кечигүү updatedirection (); } // ------------------ баскычтын басуусунан багыттын маанисин жаңыртуу ----------------- void updatedirection () { // Serial.println ("багытты жаңыртуу"); butup = digitalRead (UPPIN); // кайсы кирүү жогору болгонун текшерип, тиешелүү bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // булар, эгер статементтер кайсы кириш жогору болгонун карап, "buttonpressed" // өзгөрмөсүнө тиешелүү маанини киргизсе, бул өзгөрмө кыймылдын багытын белгилейт, эгерде (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, BLACK);

display.setTextSize (0); display.setTextColor (АК); // чийүү упайлары display.setCursor (2, 1); display.print ("Упай:"); display.print (String (playscore, DEC)); display.setCursor (66, 1); display.print ("Жогорку:"); display.print (String (highscore, DEC)); // оюн аянтчасын тартуу // 1x, 1y, 2x, 2y, түстүү дисплей.drawLine (0, 0, 127, 0, АК); // эң жогорку чек ара дисплейи.drawLine (63, 0, 63, 9, АК); // баллды бөлүүчү дисплей.drawLine (0, 9, 127, 9, АК); // тексттин чек арасынын астында display.drawLine (0, 63, 127, 63, АК); // төмөнкү чек дисплей.drawLine (0, 0, 0, 63, АК); // сол чек дисплей.drawLine (127, 0, 127, 63, АК); // оң чек

}

// ----------------------------------- оюн аянтчасын жаңыртуу ---------- --------------------

void updateGame () // бул оюн аймагынын дисплейин жаңыртат

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

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] = жыланY; }

которгуч (басылган) // жылан болгон Багыт

{case DIRUP: snakeY- = 1; тыныгуу; case DIRDOWN: snakeY+= 1; тыныгуу; case DIRLEFT: snakeX- = 1; тыныгуу; case DIRRIGHT: snakeX+= 1; тыныгуу; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- скранды кой -------------------

void placeScran ()

{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 (); return 1; } else {return 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 ("ОЮН"); тон (SND, 1000, 50); display.print ("OVER"); if (playscore> = highscore) // жогорку упайдан жогору болгонун текшерүү {highscore = playscore; // single if statment жогорку баллды жаңыртуу үчүн}} (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; // акыркы чекиттен 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, BLACK); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); playscore = 0; // баштапкы абалга жылан жана оюнчу чоо -жайы snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // оюнчу оюндун башталышын күтөт} // ------------------------- пресс циклин күт ---------- --------------- void waitForPress () {bool күтүү = 0; // цикл бул чыныгы дисплейде бүтөт.clearDisplay (); while (күтүү == 0) {drawALineForMe (WHITE); // туш келди ак сызык тартуу drawALineForMe (КАРА); // экрандын ак Display.fillRect (19, 20, 90, 32, BLACK) толук толтурулбашы үчүн туш келди кара сызык чийиңиз; // текстти көрсөтүү үчүн бош фон.setTextColor (АК); display.setCursor (35, 25); display.setTextSize (2); // чоңураак шрифт display.println ("ЖЫЛАН"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, АК); // чек Snake display.drawRect (19, 20, 90, 32, АК); // чек куту - 3 display.setCursor (28, 42); display.setTextSize (0); // кадимки дисплейге кайтып шрифт.println ("каалаган баскычты басыңыз"); display.display (); күтүү = digitalRead (INTPIN); // баскыч басылганда күтүү 1 баскычка өзгөрөөрүн текшерүү = 0 басылганда; // баштапкы абалга келтирүү баскычын басыңыз}} // -------------------- ТАРТУУ туш келди сызыктын түсү uint8_t -------------- ----- жараксыз drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // сызыкка туш келди координаталарды коюп, андан кийин аны сызыңыз // өзгөрмөсү кем эмес line1X = random (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); } return 0; }

//-------------------------------- ЖАЙГАШУУ--------------- -------------------------------

void setup () {delay (100); // нерселерге "жүктөө" мүмкүнчүлүгүн бериңиз // Serial.begin (9600); // display.begin (SSD1306_SWITCHCAPVCC, 0x3C) сериялык чыгууларын көргүңүз келсе, бул белгини алып салыңыз; display.clearDisplay (); // таза дисплейден баштаңыз display.setTextColor (АК); // тексттин түсүнүн айлануу өлчөмүн ж.б. орнотуу display.setRotation (0); display.setTextWrap (жалган); display.dim (0); // дисплейдин жарыктыгын коюңуз pinMode (INTPIN, INPUT); // pinMode (UPPIN, INPUT) киришине туура портторду коюңуз; pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // бул кириштерди окуу үчүн arduino "токтото турган" интерупт командасы // пин // Serial.println ("Орнотуу өттү"); waitForPress (); // жыландын башталуусун экранды көрсөтүү placeScran (); // тамактын биринчи бөлүгүн коюңуз} // --------------------- НЕГИЗГИ ИЛМ ----------------- ---------------------- void loop () {updateGame (); // бул функция негизги кодду алып жүрөт}

3 -кадам:

Сунушталууда: