Talaan ng mga Nilalaman:

Arduino OLED Snake Game: 3 Hakbang
Arduino OLED Snake Game: 3 Hakbang

Video: Arduino OLED Snake Game: 3 Hakbang

Video: Arduino OLED Snake Game: 3 Hakbang
Video: Arduino Snake Game on an OLED display. 2024, Hulyo
Anonim
Arduino OLED Snake Game
Arduino OLED Snake Game

Kumusta at maligayang pagdating, sa aming mga itinuturo sa kung paano gumawa at arduino OLED Game, ang proyektong ito ay naganap habang sinusubukan naming gawin ang aming unang laro sa isang arduino, soooo, naisip namin kung saan mas mahusay na magsimula kaysa sa nokia klasikong Ahas (na rin sa kahit isang clone ng ahas:)).

Ano ang Kakailanganin Mo

Mga gamit

Arduino UNO o clone

OLED Display

4 na Diode

500-1k risistor

4 na mga pindutan ng controller

Passive Piezo buzzer

opsyonal

Solderless BreadBoard

Mangyaring tandaan na ang mga link na ito ay halimbawa lamang

Hakbang 1: Ang Circuit

Ang Circuit
Ang Circuit

Sa larawan sa itaas maaari mong makita ang aming circuit, ginagamit namin ang pin d3 sa arduino bilang isang makagambala na pin ng kahilingan upang ang arduino ay bibigyan ng priyoridad sa pagbabasa ng mga input ng controller na d4 d5 d6 d7. Ang mga pangunahing kaalaman sa circuit ay ang isang pindutan ng direksyon na pinindot na kung saan napupunta mataas na 5v na ito ay nagpapagana ng sagabal na kahilingan pin (d3 purple wire) at isang kaukulang direksyon ng direksyon, ang gumagambala na pag-andar ay tumatawag sa isang pag-andar ng direksyon ng pag-update at ang code na iyon ay gumagalaw sa ahas nang naaayon. Ginamit ang pin 9 bilang sound pin dahil ito ay isang PWM (~ pulse width modulation) na direktang konektado sa isang 5v piezo sa + pin at ang - ay babalik sa 0v / ground.

(FYI sa arduino uno at mga clone lang d2 at d3 ang maaaring kumilos bilang nakakagambala na mga pin ng kahilingan).

Mga pin ng direksyon:

d4 Pataas ORANGE

d5 Pababa PINK

d6 Kaliwa BLUE

d7 Tamang BROWN

d9 tunog GRAY

Ang bawat pindutan ay may isang 5v na koneksyon input at isang output na konektado muna sa kani-kanilang digital input sa arduino, ang parehong output ng bawat pindutan pagkatapos ay konektado sa sarili nitong diode, ginagamit namin ang mga diode upang ihinto ang boltahe na pagpapakain pabalik sa iba pang mga pindutan at pinapagana ang mga ito. Sa cathode (-) dulo ng lahat ng 4 diode sumasama kami sa kanila upang lumikha ng isang output junction na kumokonekta sa d3 at pagkatapos ay sa pamamagitan ng isang risistor sa 0v / lupa upang hilahin ang mga pin ng arduino mababa upang hindi iwanan ang mga lumulutang na pin kapag hindi naging pinapagana

(FYI isang lumulutang na pin ay maaaring makatanggap ng boltahe ng multo at maging sanhi ng hindi pangkaraniwang pag-uugali)

2 analog pin ang ginagamit upang himukin ang display, ito ang mga pin ng arduino hardware i2c.

Ang A5 ay konektado sa SCL YELLOW

Ang A4 ay konektado sa SDA GREEN

Ang output na + 5v at 0v (lupa) mula sa arduino ay ginagamit bilang mapagkukunan ng lakas para sa buong circuit na maaaring pinalakas ng usb o charger ng telepono.

Hakbang 2: Ang Code

// ----------------- ANJAWARE SNAKE Mga Laro Sa tulong mula sa mga net people ------------- -------

# isama

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // display set (lapad, taas) Adafruit_SSD1306 display (128, 64); // tukuyin ang mga input pin ito ang mga pin sa arduino na hindi nila binabago kaya #define #define INTPIN 3 // ang mga pin lamang 2 at 3 ang maaaring interupt pin sa UNO #define UPPIN 4 // ang mga ito ay konektado sa mga pin tp kaugnay na switch #define DWNPIN 5 # tukuyin ang LFTPIN 6 # tukuyin ang RHTPIN 7 # tukuyin ang SND 9 // tukuyin ang mga direksyon tukuyin ang DIRLEFT 3 # tukuyin ang DIRRIGHT 4

// set variable ng mga pindutan

// volitile cos kailangan namin ito upang mag-update gamit ang interupt upang maaaring maging anumang halaga ng cycle

// ay hindi hihigit sa 4 kaya kailangan lang ng 8bit int upang makatipid ng mga mapagkukunang pabagu-bago ng uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // ginagamit namin ito upang magtakda ng totoo sa "tuklasin" kung aling direksyon ang pinindot ang bool butleft = 0; bool butright = 0;

// mga ints ng ahas

byte snakePosX [30]; // array upang gumawa ng katawan ng ahas byte ahasPosY [30];

int ahasX = 30; // posisyon ng ulo ng ahas

int ahasY = 30; int ahasSize = 1; // Bilang ng laki ng ahas na limitado sa laki ng array

// mundo ints

uint8_t worldMinX = 0; // itinakda nito ang mga limitasyon ng lugar ng pag-play

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

// mangolekta ng scran (pagkain) at posisyon ng scran

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

// variable ng mga marka

mahabang playcore = 0; mahabang highscore = 30; // magtakda ng mataas na marka sa 3 mangolekta bilang isang panimulang punto

// --------------------------- ito ang ginagawa ng interupt sa pagtaas ng boltahe ------------ -------------

walang bisa na nagambala () {pagkaantala (150); // bahagyang pagkaantala para sa naidagdag na pag-update ng proteksyon ng "bounce" (); } // ----------------- i-update ang halaga ng direksyon mula sa pindutan ng pindutan ----------------- walang bisa ang pag-update () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // check kung aling input ang naging mataas at itakda ang nauugnay na bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // mga ito kung titingnan ng mga statemeent kung aling input ang naging mataas at ipinasok ang may-katuturang halaga sa "buttonpressed" // variable, ang variable na ito ay nagdidikta ng direksyon ng paggalaw kung (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP press"); // Serial.println (buttonpressed); butup = false; tono (SND, 1500, 10); } kung (butdown == totoo) {buttonpressed = DIRDOWN; // Serial.println ("PUMUNIT na pinindot"); // Serial.println (buttonpressed); butdown = false; tono (SND, 1500, 10); }

kung (butleft == totoo)

{buttonpressed = DIRLEFT; // Serial.println ("LEFT press"); // Serial.println (buttonpressed); butleft = false; tono (SND, 1500, 10); } kung (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("RIGHT press"); // Serial.println (buttonpressed); butright = false; tono (SND, 1500, 10); }}

// ---- iguhit ang mga gawain sa pagpapakita ------------------ -----------------

walang bisa ang pag-updateDisplay () // pagguhit ng mga marka at mga balangkas

{// Serial.println ("I-update ang Display");

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

display.setTextSize (0); display.setTextColor (PUTI); // draw score display.setCursor (2, 1); display.print ("Iskor:"); display.print (String (playcore, DEC)); display.setCursor (66, 1); display.print ("Mataas:"); display.print (String (highscore, DEC)); // draw play area // pos 1x, 1y, 2x, 2y, display ng kulay.drawLine (0, 0, 127, 0, WHITE); // pinakatuktok na display ng border.drawLine (63, 0, 63, 9, WHITE); // score seperator display.drawLine (0, 9, 127, 9, WHITE); // sa ibaba ng display border ng teksto.drawLine (0, 63, 127, 63, WHITE); // ilalim ng border display.drawLine (0, 0, 0, 63, WHITE); // left border display.drawLine (127, 0, 127, 63, WHITE); // kanang hangganan

}

// ----------------------------------- i-update ang lugar ng pag-play ---------- --------------------

walang bisa ang updateGame () // ina-update nito ang pagpapakita ng lugar ng laro

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// suriin ang mga gawain sa ahas

kung (outOfArea () || selfCollision ())

{ tapos na ang laro(); }

// display ahas

para sa (int i = 0; i0; i--) {ahasPosX = ahasPosX [i-1]; ahasPosY = ahasPosY [i-1]; } // magdagdag ng dagdag na pixel sa ahas kung (scranAte) {ahasSize + = 1; ahasPosX [ahasSize-1] = ahasX; ahasPosY [ahasSize-1] = ahasY; }

switch (buttonpressed) // ay ahasDirection

{case DIRUP: ahasY- = 1; pahinga; kaso DIRDOWN: ahasY + = 1; pahinga; kaso DIRLEFT: ahasX- = 1; pahinga; kaso DIRRIGHT: ahasX + = 1; pahinga; } ahasPosX [0] = ahasX; ahasPosY [0] = ahasY; updateDisplay (); display.display (); // --------------------- ilagay ang scran -------------------

walang bisa na lugarScran ()

{scranPosX = random (worldMinX + 1, worldMaxX-1); scranPosY = random (worldMinY + 1, worldMaxY-1); } // ----------------- SCRAN ATE POINT UP ---------------- bool scranFood () {kung (ahasX == scranPosX && ahasY == scranPosY) {playcore = playscore + 10; tono (SND, 2000, 10); updateDisplay (); lugarScran (); ibalik ang 1; } iba pa {return 0; }} // ----------------- sa labas ng lugar -------------------- bool outOfArea () {return snakeX = worldMaxX || ahasY = worldMaxY; } //---------------------- tapos na ang laro----------------------- --- void gameOver () {uint8_t rectX1, straightY1, rectX2, rectY2; straightX1 = 38; rectY1 = 28; straightX2 = 58; straightY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); tono (SND, 2000, 50); display.print ("GAME"); tono (SND, 1000, 50); display.print ("OVER"); kung (playcore> = highscore) // suriin upang makita kung mas mataas ang iskor kaysa sa mataas na marka {highscore = playscore; // solong kung statment upang mag-update ng mataas na marka} para sa (int i = 0; i <= 16; i ++) // ito ay upang gumuhit ng mga parihaba sa paligid ng laro sa paglipas ng {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("kung loop"); display.display (); straightX1- = 2; // shift over by 2 pixel rectY1- = 2; straightX2 + = 4; // shift over 2 pixel mula sa huling punto na rectY2 + = 4; tono (SND, i * 200, 3); } display.display (); // Screen Wipe after fame over rectX1 = 0; // itakda ang posisyon ng pagsisimula ng linya na rectY1 = 0; straightX2 = 0; straightY2 = 63; para sa (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, straightY2, BLACK); straightX1 ++; straightX2 ++; display.display (); } display.clearDisplay (); playscore = 0; // reset ang mga detalye ng ahas at manlalaro ng SnakeSize = 1; ahasX = display.width () / 2; ahasY = display.ight () / 2; waitForPress (); // maghintay para sa manlalaro upang simulan ang laro} // ----------------- maghintay para sa presss loop ---------- --------------- void waitForPress () {bool waiting = 0; // loop ends whjen this is true display.clearDisplay (); habang (naghihintay == 0) {drawALineForMe (WHITE); // draw a random white line drawALineForMe (BLACK); // gumuhit ng isang random na itim na linya upang ang screen ay hindi ganap na punan ang puting display.fillRect (19, 20, 90, 32, BLACK); // blangko background para sa pagpapakita ng teksto.setTextColor (WHITE); display.setCursor (35, 25); display.setTextSize (2); // mas malaking display ng font.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // border Snake display.drawRect (19, 20, 90, 32, WHITE); // border box - 3 display.setCursor (28, 42); display.setTextSize (0); // font bumalik sa normal na display.println ("pindutin ang anumang key"); display.display (); naghihintay = digitalRead (INTPIN); // check to see kung ang key na pinindot ang paghihintay ay magbabago sa 1 pagtatapos habang na-button = 0; // reset button press}} // ----------------- GAWIN ang isang random na linya ng pag-input ng linya uint8_t ------------ ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // set random co-ordinates para sa isang linya pagkatapos ay iguhit ito // variable hindi mas mababa wala nang line1X = random (worldMinX + 1, worldMaxX-1); line1Y = random (worldMinY + 1, worldMaxY-1); line2X = random (worldMinX + 1, worldMaxX-1); line2Y = random (worldMinY + 1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- pag-iingat ng banggaan -------- -----------------

para sa (byte i = 4; i <ahasSize; i ++) {kung (ahasX == snakePosX && ahasY == ahasPosy ) {bumalik 1; tono (SND, 2000, 20); tono (SND, 1000, 20); } ibalik ang 0; }

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

walang bisa ang pag-setup () {pagkaantala (100); // bigyan lamang ng isang pagkakataon ang mga bagay-bagay upang "mag-boot" // Serial.begin (9600); // i-uncheck ito kung nais mong makita ang display ng serial output.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // magsimula sa isang malinis na display display.setTextColor (WHITE); // i-set up ang laki ng pag-ikot ng kulay ng teksto atbp display.setRotation (0); display.setTextWrap (false); display.dim (0); // itakda ang display brighness pinMode (INTPIN, INPUT); // itakda ang tamang mga port sa mga input na pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // this is the interupt command this "ihihinto" ang arduino upang basahin ang mga input // command- function- pin-function upang maipatupad-kondisyon sa pin attachInterrupt (digitalPinToInterrupt (INTPIN), nagambala, NAKAISA); // Serial.println ("Passup Passed"); waitForPress (); // ipakita ang pagsisimula ng ahas sa lugar ng screenScran (); // ilagay ang unang kaunting pagkain} // ----------------- MAIN LOOP ----------------- ----------------- void loop () {updateGame (); // ang pagpapaandar na ito ay kung ano ang nagdadala ng pangunahing code}

Hakbang 3:

Inirerekumendang: