Sadržaj:

Arduino OLED igra zmija: 3 koraka
Arduino OLED igra zmija: 3 koraka

Video: Arduino OLED igra zmija: 3 koraka

Video: Arduino OLED igra zmija: 3 koraka
Video: Текстовые LCD дисплей на контроллере HD44780, Уроки Arduino 2024, Novembar
Anonim
Arduino OLED igra zmija
Arduino OLED igra zmija

Bok i dobrodošli, našim instrukcijama o tome kako napraviti i arduino OLED igru, ovaj projekt je nastao dok smo pokušavali napraviti našu prvu igru s arduinom, tako da smo razmišljali odakle je bolje početi od nokia classic Snakea (dobro na bar klon zmije:)).

Šta će vam trebati

Supplies

Arduino UNO ili klon

OLED ekran

4 diode

500-1k otpornik

4 dugmeta kontrolera

Pasivni Piezo zujalica

opcionalno

BreadBoard bez lemljenja

Imajte na umu da su ove veze samo za primjer

Korak 1: Krug

The Circuit
The Circuit

Na gornjoj slici možete vidjeti naš krug, koristimo pin d3 na arduinu kao pin za zahtjev za prekidom tako da će arduino dati prednost čitanju ulaza kontrolera d4 d5 d6 d7. Osnove kruga su da se pritisne tipka za smjer koja prelazi visokih 5v, čime se aktivira pin zahtjeva za prekidom (d3 ljubičasta žica) i odgovarajući pin za smjer, funkcija prekida poziva funkciju smjera ažuriranja i taj kod prema tome pomiče zmiju. Pin 9 se koristi kao zvučni pin jer je to PWM (~ impulsno -širinska modulacija) koji je spojen direktno na 5v piezo na + pinu i - vraća se na 0v/uzemljenje.

(FYI na arduino uno i klonovima samo d2 i d3 mogu djelovati kao pinovi zahtjeva za prekid).

Igle za smjer:

d4 Gore NARANČASTO

d5 Dolje PINK

d6 Lijevo PLAVO

d7 Desno BROWN

d9 zvuči SIVO

Svako dugme ima ulaz za 5v vezu i izlaz koji je prvo spojen na odgovarajući digitalni ulaz na arduinu, isti izlaz svakog dugmeta je zatim spojen na svoju diodu, mi koristimo diode da zaustavimo povratak napona na druge tipke i njihovo aktiviranje. Na katodnom (-) kraju sve 4 diode spajamo ih zajedno kako bismo stvorili izlazni spoj koji se spaja na d3, a zatim kroz otpornik na 0v/uzemljenje da arduino pinove povuče nisko kako ne bi ostavio plutajuće pinove kada nisu aktivirano.

(Za informaciju, plutajući pin može primiti fantomski napon i uzrokovati neobično ponašanje)

Za pogon ekrana koriste se 2 analogna pina, to su arduino hardverski i2c pinovi.

A5 je spojen na SCL ŽUTU

A4 je spojen na SDA ZELENU

Izlazi +5v i 0v (uzemljenje) iz arduina koriste se kao izvor napajanja za cijelo kolo koje se može napajati putem USB -a ili punjača za telefon.

Korak 2: Kodeks

// ------------------------ ANJAWARE ZMIJE Igre Uz pomoć mrežnih ljudi --------------- -------

#include

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // skup prikaza (širina, visina) Adafruit_SSD1306 display (128, 64); // definirajte ulazne pinove to su pinovi na arduinu koje se nikada ne mijenjaju pa #define #define INTPIN 3 // samo pinovi 2 i 3 mogu biti prekinuti pinovi na UNO #define UPPIN 4 // to su pinovi povezani tp relevantan prekidač #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // definirajte smjerove #define DIRUP 1 // ove vrijednosti je ono što "zmija" gleda da odluči- #define DIRDOWN 2 // smjer kojim će zmija putovati # define DIRLEFT 3 #define DIRRIGHT 4

// postavljanje varijabli dugmeta

// volitile jer nam je potrebno da se ažurira s prekidom, tako da može biti bilo koji bit vrijednosti ciklusa

// nikad nije veće od 4 pa je potrebno samo 8bitni int za uštedu resursa volatile uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // koristimo ovo za postavljanje true za "otkrivanje" u kojem smjeru je pritisnuta bool butleft = 0; bool butright = 0;

// zmijski dodaci

bajt snakePosX [30]; // niz za izradu tijela zmijskog bajta snakePosY [30];

int snakeX = 30; // položaj zmijske glave

int snakeY = 30; int snakeSize = 1; // broj zmija ograničen na veličinu niza

// svjetski ints

uint8_t worldMinX = 0; // oni postavljaju granice područja za igru

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

// prikupljanje scrana (hrane) i položaj scrana

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

// boduje varijable

dugi rezultat = 0; dugi rezultat = 30; // postavite visoku ocjenu na 3 prikupiti kao polaznu tačku

// --------------------------- ovo se prekida radi pri porastu napona ------------ -------------

void interruptpressed () {odgoda (150); // malo kašnjenje za dodatnu "bounce" zaštitu updatedirection (); } // ------------------ ažurirajte vrijednost smjera pritiskom na tipku ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // provjeravamo koji je ulaz bio visok i postavlja relevantne bool true butdown = digitalRead (DWNPIN); butleft = digitalno čitanje (LFTPIN); butright = digitalRead (RHTPIN); // ovo ako Statemeents gledaju koji je ulaz bio visok i unosi relevantnu vrijednost u "buttonpressed" // varijablu, ova varijabla diktira smjer kretanja if (butup == true) {buttonpressed = DIRUP; // Serial.println ("GORE pritisnuto"); // Serial.println (pritisnuto dugme); butup = false; ton (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOLJE pritisnuto"); // Serial.println (pritisnuto dugme); butdown = false; ton (SND, 1500, 10); }

ako (butleft == tačno)

{buttonpressed = DIRLEFT; // Serial.println ("LIJEVO pritisnuto"); // Serial.println (pritisnuto dugme); butleft = false; ton (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("DESNO pritisnuto"); // Serial.println (pritisnuto dugme); butright = false; ton (SND, 1500, 10); }}

// -------------------------- nacrtajte rutine prikaza ------------------ -----------------

void updateDisplay () // izvlačenje rezultata i obrisa

{// Serial.println ("Ažuriraj prikaz");

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

display.setTextSize (0); display.setTextColor (BIJELO); // izvlačenje rezultata display.setCursor (2, 1); display.print ("Score:"); display.print (String (svira, DEC)); display.setCursor (66, 1); display.print ("Visoko:"); display.print (String (najbolji rezultat, DEC)); // iscrtavanje prostora za igru // poz 1x, 1y, 2x, 2y, display u boji.drawLine (0, 0, 127, 0, WHITE); // vrlo gornji rub display.drawLine (63, 0, 63, 9, BIJELO); // boduje separator display.drawLine (0, 9, 127, 9, WHITE); // ispod ivice teksta display.drawLine (0, 63, 127, 63, WHITE); // donja ivica display.drawLine (0, 0, 0, 63, WHITE); // prikaz lijeve ivice.drawLine (127, 0, 127, 63, BIJELO); // desna granica

}

// ----------------------------------- ažuriraj igralište ---------- --------------------

void updateGame () // ovo ažurira prikaz područja igre

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, BIJELO);

scranAte = scranFood ();

// provjerava rutine zmija

if (outOfArea () || selfCollision ())

{gameOver (); }

// prikaz zmije

za (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // zmiji dodamo dodatni piksel if (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

prekidač (pritisnuto dugme) // bio je zmijaDirection

{slučaj DIRUP: snakeY- = 1; break; slučaj DIRDOWN: snakeY+= 1; break; kućište DIRLEFT: snakeX- = 1; break; kućište DIRRIGHT: snakeX+= 1; break; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- postavite scran -------------------

void placeScran ()

{scranPosX = random (worldMinX+1, worldMaxX-1); scranPosY = slučajno (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; ton (SND, 2000, 10); updateDisplay (); placeScran (); return 1; } else {return 0; }} // --------------------- izvan područja ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } // ---------------------- igra preko ----------------------- --- 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); ton (SND, 2000, 50); display.print ("IGRA"); ton (SND, 1000, 50); display.print ("OVER"); if (playcore> = highscore) // provjerite da li je rezultat veći od visokog skora {highscore = playscore; // single if statment to update high score} for (int i = 0; i <= 16; i ++) // ovo je za crtanje iscrtavanja oko igre preko {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("if loop"); display.display (); rectX1- = 2; // pomak za 2 piksela rectY1- = 2; rectX2+= 4; // pomak preko 2 piksela od zadnje točke rectY2+= 4; ton (SND, i*200, 3); } display.display (); // Brisanje ekrana nakon slave nad rectX1 = 0; // postavlja početni položaj linije rectY1 = 0; rectX2 = 0; rectY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, CRNI); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); playcore = 0; // resetiranje detalja zmije i igrača snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // čekajte da igrač započne igru} // ------------------------- čekajte petlju za štampu ---------- --------------- void waitForPress () {bool čekanje = 0; // petlja završava kada je ovo istina display.clearDisplay (); while (čekanje == 0) {drawALineForMe (BIJELO); // iscrtavanje nasumične bijele linije drawALineForMe (BLACK); // povlačimo nasumičnu crnu liniju tako da ekran ne ispuni do kraja bijeli display.fillRect (19, 20, 90, 32, BLACK); // prazna pozadina za prikaz teksta.setTextColor (BIJELO); display.setCursor (35, 25); display.setTextSize (2); // veći font display.println ("ZMIJA"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, BIJELO); // ivica Snake display.drawRect (19, 20, 90, 32, BIJELO); // rubni okvir - 3 display.setCursor (28, 42); display.setTextSize (0); // font natrag na normalni display.println ("pritisnite bilo koji taster"); display.display (); čekanje = digitalno čitanje (INTPIN); // provjeravamo da li će se pritisnuti taster na čekanju promijeniti u 1 koji se završava dok je dugme pritisnuto = 0; // dugme za resetiranje pritisnite}} // -------------------- NACRTAJ nasumičnu liniju unosa boje uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t linija1X, linija1Y, linija2X, linija2Y = 0; // postavlja nasumične koordinate za liniju, a zatim je crta // varijabla ništa manje ni više line1X = slučajno (worldMinX+1, worldMaxX-1); line1Y = slučajni (worldMinY+1, worldMaxY-1); line2X = slučajni (worldMinX+1, worldMaxX-1); line2Y = slučajno (worldMinY+1, worldMaxY-1); display.drawLine (linija1X, linija1Y, linija2X, linija2Y, clr); } // ------------------------------------- detekcija sudara -------- -----------------------

for (byte i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; ton (SND, 2000, 20); ton (SND, 1000, 20); } return 0; }

//-------------------------------- POSTAVITI--------------- -------------------------------

void setup () {delay (100); // samo dati stvarima priliku za "dizanje" // Serial.begin (9600); // poništite ovu opciju ako želite vidjeti display.begin serijskih izlaza (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // započinjemo sa čistim prikazom display.setTextColor (WHITE); // postavljamo veličinu rotacije boje teksta itd. display.setRotation (0); display.setTextWrap (false); display.dim (0); // postavljamo pinMode svjetline zaslona (INTPIN, INPUT); // postavljamo ispravne portove na ulaze pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // ovo je naredba za prekid koja "zaustavlja" arduino za čitanje ulaza // naredba-funkcija-funkcija-za izvršavanje stanja na pin attachInterrupt (digitalPinToInterrupt (INTPIN), prekinuto, RISING); // Serial.println ("Postavka je prošla"); waitForPress (); // prikazuje ekran za pokretanje zmije placeScran (); // stavite prvi komad hrane} // --------------------- GLAVNA PETLJA ----------------- ---------------------- void loop () {updateGame (); // ova funkcija nosi glavni kod}

Korak 3:

Preporučuje se: