Përmbajtje:

Arduino OLED Snake Lojë: 3 hapa
Arduino OLED Snake Lojë: 3 hapa

Video: Arduino OLED Snake Lojë: 3 hapa

Video: Arduino OLED Snake Lojë: 3 hapa
Video: NOOBS PLAY CLASH ROYALE FROM START LIVE 2024, Nëntor
Anonim
Lojë Arduino OLED Snake
Lojë Arduino OLED Snake

Përshëndetje dhe mirëseardhje, për udhëzuesit tanë se si të bëjmë dhe arduino OLED Game, ky projekt erdhi ndërsa ne po përpiqeshim të bënim lojën tonë të parë ndonjëherë me një arduino, kështu që, ne menduam se ku është më mirë të fillojmë sesa gjarpri klasik nokia (mirë në të paktën një klon gjarpri:)).

Ajo që do t'ju duhet

Furnizimet

Arduino UNO ose klon

Ekran OLED

4 Diodat

Rezistencë 500-1k

4 butona kontrollues

Zhurmë pasive Piezo

sipas dëshirës

Bordi i Bukës pa Solderless

Ju lutemi vini re se këto lidhje janë vetëm për shembull

Hapi 1: Qarku

Qarku
Qarku

Në foton e mësipërme mund të shihni qarkun tonë, ne përdorim pinin d3 në arduino si një pin kërkese për ndërprerje në mënyrë që arduino t'i japë përparësi leximit të hyrjeve të kontrolluesit të cilat janë d4 d5 d6 d7. Bazat e qarkut janë që shtypet një buton drejtimi i cili shkon lartë 5v kjo aktivizon pinin e kërkesës për ndërprerje (tel vjollce d3) dhe një pin përkatës drejtimi, funksioni i ndërprerjes thërret një funksion drejtimi përditësues dhe ai kod lëviz gjarprin në përputhje me rrethanat. Pin 9 përdoret si kunj i zërit pasi është një PWM (modulim i gjerësisë së pulsit) i cili lidhet drejtpërdrejt me një piezo 5v në pin + dhe - kthehet në 0v/tokë.

(FYI në arduino uno dhe klonon vetëm d2 dhe d3 mund të veprojnë si kunja të kërkesës për ndërprerje).

Kunjat e drejtimit:

d4 Lart Portokalli

d5 PINK Poshtë

d6 Majtas Blu

d7 E DREJTA E KRYER

d9 tingëllon GRI

Çdo buton ka një hyrje lidhjeje 5v dhe një dalje që lidhet së pari me hyrjen e tyre përkatëse dixhitale në arduino, i njëjti dalje i secilit buton lidhet më pas me diodën e vet, ne përdorim diodat për të ndaluar furnizimin e tensionit butona të tjerë dhe aktivizimi i tyre. Në fund të katodës (-) të të 4 diodave ne i bashkojmë ato për të krijuar një kryqëzim dalës i cili lidhet me d3 dhe më pas përmes një rezistori në 0v/tokë për të tërhequr kunjat arduino të ulët në mënyrë që të mos lënë kunja lundruese kur nuk janë aktivizuar.

(FYI një kunj lundrues mund të marrë tension fantazmë dhe të shkaktojë sjellje të pazakontë)

2 kunja analoge përdoren për të drejtuar ekranin, këto janë kunjat e harduerit arduino i2c.

A5 është i lidhur me SCL YELLOW

A4 është i lidhur me SDA GREEN

Dalja +5v dhe 0v (tokë) nga arduino përdoret si burim i energjisë për të gjithë qarkun i cili mund të mundësohet nga usb ose karikuesi i telefonit.

Hapi 2: Kodi

// ------------------------ Lojërat ANJAWARE SNAKE Me ndihmë nga popujt neto --------------- -------

#përfshi

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // set display (width, height) Adafruit_SSD1306 display (128, 64); // përcaktoni kunjat e hyrjes këto janë kunjat në arduino ato nuk ndryshojnë kurrë kështu #define #define INTPIN 3 // vetëm kunjat 2 dhe 3 mund të jenë kunja të ndërprerë në UNO #define UPPIN 4 // këto janë kunja të lidhura tp ndërprerës përkatës #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // përcakto drejtimet #përcakto DIRUP 1 // këto vlera është ajo që shikon "gjarpri" për të vendosur- #define DIRDOWN 2 // drejtimi që gjarpri do të udhëtojë # përcakto DIRLEFT 3 #përcakto DIRRIGHT 4

// vendosni ndryshoret e butonit

// volitile cos ne kemi nevojë që ajo të përditësohet me interupt kështu që mund të ketë ndonjë grimcë të vlerës së ciklit

// nuk është kurrë më e lartë se 4 kështu që ju nevojiten vetëm 8bit int për të kursyer burime të paqëndrueshme uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // ne e përdorim këtë për të vendosur true për të "zbuluar" drejtimin e shtypur bool butleft = 0; bool butright = 0;

// gjarpër ints

byte snakePosX [30]; // grup për të bërë trupin e gjarprit byte snakePosY [30];

int gjarpërX = 30; // pozicioni i kokës së gjarprit

int gjarpërY = 30; int snakeSize = 1; // numërimi i madhësisë së gjarprit i kufizuar në madhësinë e grupit

// ints botërore

uint8_t botëMinX = 0; // këto vendosin kufijtë e zonës së lojës

uint8_t botëMaxX = 128; uint8_t botëMinY = 10; uint8_t botëMaxY = 63;

// mblidhni scran (ushqim) dhe pozicionin e scran

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

// shënon variabla

rezultate të gjata të lojërave = 0; rezultat i gjatë i lartë = 30; // vendos rezultatin e lartë në 3 mbledh si pikë fillestare

// --------------------------- kjo është ajo që ndërprerësi ekzekuton në rritjen e tensionit ------------ -------------

void interruptpressed () {vonesë (150); // vonesë e vogël për drejtimin e përditësuar të mbrojtjes "fryrje" të shtuar (); } // ------------------ përditësoni vlerën e drejtimit nga shtypja e butonit ----------------- drejtimi i zbrazët i përditësuar () { // Serial.println ("përditësimi i drejtimit"); butup = digitalRead (UPPIN); // kontrolloni se cila hyrje shkoi lartë dhe vendosni bool përkatës true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // këto nëse deklaruesit shikojnë se cila hyrje shkoi lartë dhe fut vlerën përkatëse në ndryshoren "buttonpressed" //, kjo ndryshore dikton drejtimin e lëvizjes nëse (butup == vërtetë) {buttonpressed = DIRUP; // Serial.println ("UP shtypur"); // Serial.println (shtypur me butona); butup = false; toni (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("Poshtë shtypur"); // Serial.println (shtypur me butona); butdown = false; toni (SND, 1500, 10); }

nëse (butleft == vërtetë)

{buttonpressed = DIRLEFT; // Serial.println ("LEFT shtypur"); // Serial.println (shtypur me butona); butleft = false; toni (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("Shtypur DREJTA"); // Serial.println (shtypur me butona); i drejtë = i rremë; toni (SND, 1500, 10); }}

// -------------------------- vizatoni rutinat e shfaqjes ------------------ -----------------

void updateDisplay () // tërheq rezultatet dhe skicat

{// Serial.println ("Përditëso ekranin");

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

display.setTextSize (0); display.setTextColor (E BARDH); // tërheq rezultatet display.setCursor (2, 1); display.print ("Pikët:"); display.print (String (playcore, DEC)); display.setCursor (66, 1); display.print ("E lartë:"); display.print (String (rezultat i lartë, DEC)); // vizatoni zonën e lojës // pos 1x, 1y, 2x, 2y, ekran me ngjyra.drawLine (0, 0, 127, 0, WHITE); // shfaqja e kufirit shumë të lartë.drawLine (63, 0, 63, 9, WHITE); // rezultat ndarës display.drawLine (0, 9, 127, 9, WHITE); // shfaqja e kufirit të tekstit poshtë.drawLine (0, 63, 127, 63, WHITE); // ekrani i kufirit të poshtëm.drawLine (0, 0, 0, 63, WHITE); // ekrani i kufirit të majtë.drawLine (127, 0, 127, 63, WHITE); // kufiri i djathtë

}

// ----------------------------------- azhurnoni zonën e lojës ---------- --------------------

void updateGame () // kjo përditëson shfaqjen e zonës së lojës

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// kontrolloni rutinat e gjarprit

nëse (jashtëArea () || vetë -përplasja ())

{ Loja mbaroi(); }

// shfaq gjarpërin

për (int i = 0; i0; i--) {gjarpërPosX = gjarpërPosX [i-1]; gjarpërPosY = gjarpërPosY [i-1]; } // shtoni një piksel shtesë në gjarpër nëse (scranAte) {snakeSize+= 1; gjarpërPosX [gjarpriSize-1] = gjarpërX; gjarpërPosY [gjarpriSize-1] = gjarpërY; }

kaloni (i shtypur me butona) // ishte gjarpër Drejtimi

{rast DIRUP: gjarpërY- = 1; pushim; rasti DIRDOWN: gjarpërY+= 1; pushim; rasti DIRLEFT: gjarpërX- = 1; pushim; rasti DIRRIGHT: gjarpërX+= 1; pushim; } gjarpërPosX [0] = gjarpërX; gjarpërPosY [0] = gjarpërY; updateDisplay (); display.display (); // --------------------- vendosni skranimin -------------------

void placeScran ()

{scranPosX = rastësor (worldMinX+1, worldMaxX-1); scranPosY = e rastësishme (worldMinY+1, worldMaxY-1); } // ------------------------ SHKRUAJ PTER PIK ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playcore = scorecore+10; toni (SND, 2000, 10); updateDisplay (); placeScran (); kthehu 1; } else {kthimi 0; }} // --------------------- jashtë zonës ---------------------- bool outOfArea () {kthehu gjarpërX = worldMaxX || gjarpërY = botëMaxY; } //---------------------- Loja mbaroi----------------------- --- lojë e pavlefshmeOver () {uint8_t rectX1, rectY1, rectX2, rectY2; rectX1 = 38; rectY1 = 28; rectX2 = 58; rectY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); toni (SND, 2000, 50); display.print ("GAME"); toni (SND, 1000, 50); display.print ("OVER"); nëse (scorecore> = rezultati më i lartë) // kontrolloni për të parë nëse rezultati është më i lartë se rezultati i lartë {highscore = rezultati i lojës; // single if statment për të përditësuar rezultatin e lartë} për (int i = 0; i <= 16; i ++) // kjo është për të nxjerrë drejtkëndëshe rreth lojës mbi {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("nëse lak"); display.display (); rectX1- = 2; // zhvendosje me 2 piksele rectY1- = 2; rectX2+= 4; // zhvendos mbi 2 piksele nga pika e fundit rectY2+= 4; toni (SND, i*200, 3); } display.display (); // Fshirja e ekranit pas famës mbi rectX1 = 0; // vendos pozicionin e fillimit të vijës rectY1 = 0; rectX2 = 0; rectY2 = 63; për (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, BLACK); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); scorecore = 0; // rivendos gjarprin dhe detajet e lojtarit snakeSize = 1; gjarpërX = shfaqje. gjerësi ()/2; gjarpërY = shfaqje. lartësia ()/2; waitForPress (); // prisni që lojtari të fillojë lojën} // ------------------------- prisni lakun e shtypjeve ---------- --------------- void waitForPress () {bool սպասում = 0; // loop përfundon kur kjo është shfaqje e vërtetë. ClearDisplay (); ndërsa (në pritje == 0) {drawALineForMe (E BARDH); // vizatoni një vijë të bardhë të rastësishme drawALineForMe (BLACK); // vizatoni një vijë të zezë të rastësishme në mënyrë që ekrani të mos mbushë plotësisht ekranin e bardhë.fillRect (19, 20, 90, 32, BLACK); // sfond bosh për shfaqjen e tekstit.setTextColor (E BARDH); display.setCursor (35, 25); display.setTextSize (2); // ekran më i madh i shkronjave.println ("GJARPR"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // kufiri Ekrani i gjarprit.drawRect (19, 20, 90, 32, WHITE); // kutia e kufirit - 3 ekran. setCursor (28, 42); display.setTextSize (0); // fonti kthehet në ekranin normal.println ("shtypni çdo tast"); display.display (); pritja = digitalRead (INTPIN); // kontrolloni për të parë nëse pritja e shtypur e tastit do të ndryshojë në 1 duke përfunduar ndërsa shtypur butonin = 0; // butoni i rivendosjes shtypni}} // -------------------- Vizatoni një ngjyrë të rastësishme të futjes së rreshtit uint8_t -------------- ----- pavlefshme drawALineForMe (uint8_t clr) {uint8_t rreshti1X, rreshti1Y, rreshti2X, rreshti2Y = 0; // vendos koordinatat e rastësishme për një vijë pastaj vizatoje atë // variabël jo më pak jo më shumë rresht1X = rastësor (worldMinX+1, worldMaxX-1); line1Y = e rastësishme (worldMinY+1, worldMaxY-1); line2X = e rastësishme (worldMinX+1, worldMaxX-1); line2Y = e rastësishme (worldMinY+1, worldMaxY-1); display.drawLine (rreshti1X, rreshti1Y, rreshti2X, rreshti2Y, clr); } // ------------------------------------- zbulimi i përplasjes -------- -----------------------

për (byte i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {kthimi 1; toni (SND, 2000, 20); toni (SND, 1000, 20); } kthimi 0; }

// -------------------------------- SETUP --------------- -----------------------------------

void setup () {vonesë (100); // thjesht jepni një shans sendeve për të "nisur" // Serial.begin (9600); // hiqeni këtë nëse doni të shihni shfaqjet seriale të shfaqjes.filloni (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // filloni me një ekran të pastër të shfaqjes.setTextColor (E BARDH); // konfiguroni madhësinë e rrotullimit të ngjyrës së tekstit etj display.setRotation (0); display.setTextWrap (false); ekran.dim (0); // vendosni pinMode të brighness të ekranit (INTPIN, INPUT); // vendosni portat e sakta në hyrjet pinMode (UPPIN, INPUT); pinMode (DWNPIN, HYRJE); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, HYRJE); // kjo është komanda ndërprerëse kjo "ndalon" arduinon për të lexuar hyrjet // komandë- funksion- funksion-pin për të ekzekutuar-kusht në pin attachInterrupt (digitalPinToInterrupt (INTPIN), ndërprerë, RISHT); // Serial.println ("Konfigurimi kaloi"); waitForPress (); // shfaq ekranin e fillimit të gjarprit placeScran (); // vendosni pjesën e parë të ushqimit} // --------------------- PARA KRYESORE ----------------- ---------------------- void loop () {updateGame (); // ky funksion është ai që mbart kodin kryesor}

Hapi 3:

Recommended: