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, Studeni
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 svoju prvu igru s arduinom, tako da, mislili smo odakle je bolje početi nego nokia classic Snake (dobro na barem klon zmije:)).

Ono što će vam trebati

Pribor

Arduino UNO ili klon

OLED zaslon

4 diode

500-1k otpornik

4 tipke kontrolera

Pasivni zujalica Piezo

izborno

BreadBoard bez lemljenja

Imajte na umu da su ove veze samo za primjer

Korak 1: Krug

Krug
Krug

Na gornjoj slici možete vidjeti naš sklop, 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 (ljubičasta žica d3) 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 izravno na 5v piezo na + pinu i - vraća se na 0v/masu.

(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 SMEĐA

d9 zvuči SIVO

Svaki gumb ima ulazni utikač od 5 V i izlaz koji je prvo spojen na odgovarajući digitalni ulaz na arduinu, isti izlaz svakog gumba zatim je 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 povuče arduino pinove nisko kako ne bi ostavili plutajuće pinove kad nisu aktivirano.

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

Za pogon zaslona 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 cijeli krug koji se može napajati putem USB -a ili punjača za telefon.

Korak 2: Kôd

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

#uključi

#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 kako bi odlučila- #define DIRDOWN 2 // smjer kojim će zmija putovati # definirati DIRLEFT 3 #define DIRRIGHT 4

// postavljanje varijabli gumba

// volitile cos trebamo ga ažurirati s prekidom pa može biti bilo koji dio ciklusa

// nikad nije veći od 4 pa je potrebno samo 8bitni int za spremanje 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;

// zmijske inte

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

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

int zmijaY = 30; int snakeSize = 1; // broj zmija veličina 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;

// prikupiti scran (hranu) i položaj scrana

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

// boduje varijable

duga predstava = 0; dugi rezultat = 30; // postaviti visoku ocjenu na 3 prikupiti kao početnu točku

// --------------------------- ovo je ono što se prekida radi pri porastu napona ------------ -------------

void interruptpressed () {odgoda (150); // malo kašnjenje za dodatnu "bounce" zaštitu updatedirection (); } // ------------------ ažuriranje vrijednosti smjera pritiskom na tipku ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // provjeravamo koji je ulaz bio visok i postavimo relevantnu bool true butdown = digitalRead (DWNPIN); butleft = digitalno čitanje (LFTPIN); butright = digitalno čitanje (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 = lažno; 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 == istina)

{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čiti rezultate i obrise

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

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

display.setTextSize (0); display.setTextColor (BIJELO); // izvlačenje rezultata display.setCursor (2, 1); display.print ("Bodovi:"); 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); // prikaz vrlo gornjeg ruba.drawLine (63, 0, 63, 9, BIJELO); // display separator score.drawLine (0, 9, 127, 9, BIJELO); // ispod obruba teksta display.drawLine (0, 63, 127, 63, BIJELO); // prikaz donje ivice.drawLine (0, 0, 0, 63, BIJELO); // prikaz lijevog ruba.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 ();

// provjeriti rutine zmija

if (outOfArea () || selfCollision ())

{ igra je gotova(); }

// 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č (pritisnut gumb) // bio je zmijaDirection

{slučaj DIRUP: snakeY- = 1; pauza; slučaj DIRDOWN: snakeY+= 1; pauza; slučaj DIRLEFT: zmijaX- = 1; pauza; slučaj DIRRIGHT: snakeX+= 1; pauza; } snakePosX [0] = zmijaX; 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 TOČKA GORE ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; ton (SND, 2000, 10); updateDisplay (); mjestoScran (); return 1; } else {return 0; }} // --------------------- izvan područja ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- igra je gotova----------------------- --- 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 ("PREKO"); if (playcore> = highscore) // provjerite je li rezultat veći od visokog boda {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 petlja"); display.display (); rectX1- = 2; // pomak za 2 piksela rectY1- = 2; rectX2+= 4; // pomak za 2 piksela od zadnje točke rectY2+= 4; ton (SND, i*200, 3); } display.display (); // Brisanje zaslona nakon slave nad rectX1 = 0; // postavlja početni položaj linije rectY1 = 0; rectX2 = 0; rectY2 = 63; za (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, CRNI); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); sviranje = 0; // resetiranje pojedinosti o zmiji i igraču snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // pričekajte da igrač započne igru} // ------------------------- pričekajte petlju za tisak ---------- --------------- void waitForPress () {bool čekanje = 0; // petlja završava kada je to istina display.clearDisplay (); while (čekanje == 0) {drawALineForMe (BIJELO); // nacrtati nasumičnu bijelu liniju drawALineForMe (BLACK); // povući nasumičnu crnu liniju tako da zaslon 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 prikaz fonta.println ("ZMIJA"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, BIJELO); // graničnik Zmijski prikaz.drawRect (19, 20, 90, 32, BIJELO); // rubni okvir - 3 display.setCursor (28, 42); display.setTextSize (0); // font natrag na normalni prikaz.println ("pritisnite bilo koju tipku"); display.display (); čekanje = digitalno čitanje (INTPIN); // provjeravamo hoće li se pritisnuta tipka na čekanju promijeniti u 1 koja završava dok je gumb pritisnut = 0; // gumb za resetiranje pritisnite}} // -------------------- NACRTAJ boju nasumičnog unosa uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t linija1X, linija1Y, linija2X, linija2Y = 0; // postavljamo slučajne koordinate za liniju, zatim je crtamo // varijabla ništa manje ni više line1X = slučajno (worldMinX+1, worldMaxX-1); linija1Y = slučajna (worldMinY+1, worldMaxY-1); line2X = slučajni (worldMinX+1, worldMaxX-1); linija2Y = slučajna (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 prikaz serijskih izlaza.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // počnite s čistim prikazom zaslona.setTextColor (BIJELO); // postavite veličinu rotacije boje teksta itd. display.setRotation (0); display.setTextWrap (lažno); display.dim (0); // postavljamo pinMode svjetline zaslona (INTPIN, INPUT); // postavljanje ispravnih portova 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-pin-funkcija za izvršavanje uvjeta na pin attachInterrupt (digitalPinToInterrupt (INTPIN), prekinuto, RISING); // Serial.println ("Postavka je prošla"); waitForPress (); // prikazuje zaslon za pokretanje zmije placeScran (); // stavite prvi komad hrane} // --------------------- GLAVNA PETLJA ----------------- ---------------------- void loop () {updateGame (); // ova funkcija nosi glavni kod}

3. korak:

Preporučeni: