Kazalo:

Arduino OLED Snake Game: 3 koraki
Arduino OLED Snake Game: 3 koraki

Video: Arduino OLED Snake Game: 3 koraki

Video: Arduino OLED Snake Game: 3 koraki
Video: Arduino Snake Game on an OLED display. 2024, November
Anonim
Arduino OLED kača igra
Arduino OLED kača igra

Pozdravljeni in dobrodošli, v naših navodilih za izdelavo in arduino OLED igro je ta projekt nastal, ko smo poskušali narediti prvo igro z arduinom, takoooo, mislili smo, kje je bolje začeti kot nokia classic Snake (no na vsaj kačji klon:)).

Kaj boste potrebovali

Zaloge

Arduino UNO ali klon

OLED zaslon

4 diode

500-1k upor

4 krmilne tipke

Pasivni zvočni signal Piezo

neobvezno

BreardBoard brez spajkanja

Upoštevajte, da so te povezave samo na primer

1. korak: vezje

Vezje
Vezje

Na zgornji sliki si lahko ogledate naše vezje, pin d3 na arduinu uporabljamo kot pin za zahtevo po prekinitvi, tako da bo arduino imel prednost pri branju vhodov krmilnika, ki so d4 d5 d6 d7. Osnove vezja so, da pritisnete smerni gumb, ki se dvigne visoko 5v, kar aktivira zatič za zahtevo prekinitve (vijolična žica d3) in ustrezen smerni zatič, funkcija prekinitve pokliče funkcijo za smer posodobitve in ta koda ustrezno premakne kačo. Pin 9 se uporablja kot zvočni zatič, saj je PWM (~ impulzno širinska modulacija), ki je neposredno priključen na 5v piezo na + pinu in - se vrne na 0v/ozemljitev.

(FYI na arduino uno in kloni samo d2 in d3 lahko delujeta kot zatiči za prekinitev).

Smerni zatiči:

d4 gor ORANŽNA

d5 Dol PINK

d6 Levo MODRO

d7 Desno RJAVA

d9 zvoni SIVO

Vsak gumb ima vhod za vhod 5V in izhod, ki je najprej povezan z ustreznim digitalnim vhodom na arduinu, ta isti izhod vsakega gumba je nato povezan z lastno diodo, z diodami ustavimo napetost, ki se vrača nazaj v druge gumbe in jih aktivirate. Na katodnem (-) koncu vseh 4 diod jih povežemo skupaj, da ustvarimo izhodni spoj, ki se poveže z d3 in nato skozi upor do 0v/ozemljitev, da arduino zatiče potegnemo nizko, da ne pustimo plavajočih zatičev, ko niso aktivirano.

(FYI plavajoči zatič lahko sprejme fantomsko napetost in povzroči nenavadno vedenje)

Za pogon zaslona se uporabljata 2 analogna zatiča, to sta zatiča strojne opreme i2c arduino.

A5 je priključen na SCL YELLOW

A4 je priključen na SDA GREEN

Izhod +5v in 0v (ozemljitev) iz arduina se uporablja kot vir energije za celotno vezje, ki ga lahko napaja USB ali polnilec za telefon.

2. korak: Koda

// ------------------------ ANJAWARE SNAKE Igre S pomočjo ljudi iz omrežja --------------- -------

#vključi

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // komplet zaslona (širina, višina) Adafruit_SSD1306 display (128, 64); // določimo vhodne zatiče, to so zatiči na arduinu, ki se nikoli ne spremenijo, zato #define #define INTPIN 3 // samo zatiča 2 in 3 lahko prekinite zatiči na UNO #define UPPIN 4 // to so zatiči povezani tp ustrezno stikalo #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // opredelite smeri #define DIRUP 1 // te vrednosti je tisto, kar "kača" gleda, da se odloči- #define DIRDOWN 2 // smer kača bo potovala # define DIRLEFT 3 #define DIRRIGHT 4

// nastavimo spremenljivke gumbov

// volitile cos we need to update with the interupt so can any bit of cycle value

// nikoli ni višji od 4, zato potrebujete le 8 -bitni int, da shranite vire. volatile uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // s tem nastavimo true za "zaznavanje" v katero smer je pritisnjen bool butleft = 0; bool butright = 0;

// kačje vložke

bajt snakePosX [30]; // matrika za izdelavo telesa kačjega bajta snakePosY [30];

int kačaX = 30; // položaj kačje glave

int kačaY = 30; int snakeSize = 1; // število kač je omejeno na velikost polja

// svetovne ints

uint8_t worldMinX = 0; // ti določajo meje igralnega območja

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

// zberemo scran (hrano) in položaj scrana

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

// ocenjuje spremenljivke

dolgo predvajanje = 0; dolg rezultat = 30; // nastavite visoko oceno na 3 zbira kot izhodišče

// --------------------------- to se izvede pri prekinitvi ob dvigu napetosti ------------ -------------

void interruptpressed () {zamuda (150); // rahla zamuda za dodano zaščito "bounce" updatedirection (); } // ------------------ posodobi vrednost smeri s pritiskom na gumb ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalno branje (UPPIN); // preverimo, kateri vhod je bil visok in nastavimo ustrezno bool true butdown = digitalRead (DWNPIN); butleft = digitalno branje (LFTPIN); butright = digitalno branje (RHTPIN); // ti, če merilniki stanja gledajo, kateri vhod je bil visok, in vnese spremenljivo vrednost v spremenljivko "buttonpressed" // ta spremenljivka narekuje smer gibanja, če (butup == true) {buttonpressed = DIRUP; // Serial.println ("GOR pritisnjen"); // Serial.println (pritisnjen na gumb); butup = false; ton (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOL pritisnjeno"); // Serial.println (pritisnjen na gumb); butdown = false; ton (SND, 1500, 10); }

če (butleft == res)

{buttonpressed = DIRLEFT; // Serial.println ("LEVO pritisnjeno"); // Serial.println (pritisnjen na gumb); butleft = false; ton (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("DESNO pritisnjeno"); // Serial.println (pritisnjen na gumb); butright = false; ton (SND, 1500, 10); }}

// -------------------------- narišite rutine prikaza ------------------ -----------------

void updateDisplay () // žrebanje rezultatov in orisov

{// Serial.println ("Posodobi zaslon");

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

display.setTextSize (0); display.setTextColor (BELO); // žrebanje rezultatov display.setCursor (2, 1); display.print ("Score:"); display.print (niz (predvajanje, DEC)); display.setCursor (66, 1); display.print ("Visoko:"); display.print (Niz (vrhunski rezultat, DEC)); // risanje igralnega območja // poz 1x, 1y, 2x, 2y, barvni prikaz.drawLine (0, 0, 127, 0, BELO); // zelo zgornji rob rob.drawLine (63, 0, 63, 9, BELA); // ocena ločevalnika display.drawLine (0, 9, 127, 9, BELA); // pod mejo besedila display.drawLine (0, 63, 127, 63, WHITE); // prikaz spodnje meje.drawLine (0, 0, 0, 63, BELA); // prikaz leve obrobe.drawLine (127, 0, 127, 63, BELA); // desna meja

}

// ----------------------------------- posodobi igralno področje ---------- --------------------

void updateGame () // to posodobi prikaz področja igre

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, BELO);

scranAte = scranFood ();

// preverimo rutine kač

if (outOfArea () || selfCollision ())

{ konec igre(); }

// prikaz kače

for (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // kači dodamo dodatno slikovno piko if (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

stikalo (pritisnjeno na gumb) // je bil snakeDirection

{primer DIRUP: snakeY- = 1; zlom; primer DIRDOWN: snakeY+= 1; zlom; ohišje DIRLEFT: snakeX- = 1; zlom; ohišje DIRRIGHT: snakeX+= 1; zlom; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- postavite scran -------------------

void placeScran ()

{scranPosX = naključno (worldMinX+1, worldMaxX-1); scranPosY = naključno (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; ton (SND, 2000, 10); updateDisplay (); placeScran (); vrnitev 1; } else {return 0; }} // --------------------- izven območja ---------------------- bool outOfArea () {vrni snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- konec igre----------------------- --- 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) // preverite, če je rezultat višji od najvišjega {scorescore = playscore; // samski, če statment za posodobitev visoke ocene} for (int i = 0; i <= 16; i ++) // to je za risanje rektalnosti okoli igre nad {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("if zanka"); display.display (); rectX1- = 2; // premik za 2 slikovni piki rectY1- = 2; rectX2+= 4; // premik za 2 slikovni piki od zadnje točke rectY2+= 4; ton (SND, i*200, 3); } display.display (); // Brisanje zaslona po slavi nad rectX1 = 0; // nastavimo začetni položaj vrstice rectY1 = 0; rectX2 = 0; rectY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, ČRNA); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); predvajanje = 0; // ponastavimo podatke o kači in igralcu snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // počakajte, da igralec začne igro} // ------------------------- počakajte na zanko za tisk ---------- --------------- void waitForPress () {bool čaka = 0; // zanka se konča, ko je to res display.clearDisplay (); while (čaka == 0) {drawALineForMe (BELO); // narišemo naključno belo črto drawALineForMe (BLACK); // potegnemo naključno črno črto, tako da zaslon ne zapolni popolnoma belega zaslona.fillRect (19, 20, 90, 32, BLACK); // prazno ozadje za prikaz besedila.setTextColor (BELO); display.setCursor (35, 25); display.setTextSize (2); // večja pisava display.println ("ZMIJA"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, BELO); // obroba Snake display.drawRect (19, 20, 90, 32, BELA); // obrobno polje - 3 display.setCursor (28, 42); display.setTextSize (0); // pisava nazaj na običajni display.println ("pritisnite katero koli tipko"); display.display (); čaka = digitalno branje (INTPIN); // preverimo, če se pritisnjena tipka čaka in se spremeni na 1, medtem ko je gumb pritisnjen = 0; // gumb za ponastavitev pritisnite}} // -------------------- NARISI barvo vnosa naključne črte uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // nastavimo naključne koordinate za črto in jo nato narišemo // spremenljivko nič manj nič več line1X = naključno (worldMinX+1, worldMaxX-1); vrstica1Y = naključno (worldMinY+1, worldMaxY-1); line2X = naključno (worldMinX+1, worldMaxX-1); line2Y = naključno (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- zaznavanje trka -------- -----------------------

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

//-------------------------------- NASTAVITI--------------- -------------------------------

void setup () {zakasnitev (100); // samo damo materialu možnost "zagona" // Serial.begin (9600); // počistite to polje, če želite videti serijske izhode display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // začnite s čistim prikazom display.setTextColor (WHITE); // nastavite velikost vrtenja barve besedila itd display.setRotation (0); display.setTextWrap (false); display.dim (0); // nastavimo pinMode osvetlitve zaslona (INTPIN, INPUT); // nastavimo pravilna vrata na vhode pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // to je prekinitveni ukaz, ki "ustavi" arduino za branje vhodov // command-function-pin-function to execute-condition on pin attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Namestitev je opravljena"); waitForPress (); // prikaže zaslon za zagon kače placeScran (); // postavite prvi kos hrane} // --------------------- GLAVNA ZANKA ----------------- ---------------------- void loop () {updateGame (); // ta funkcija nosi glavno kodo}

3. korak:

Priporočena: