Sisällysluettelo:

Arduino OLED Snake Game: 3 askelta
Arduino OLED Snake Game: 3 askelta

Video: Arduino OLED Snake Game: 3 askelta

Video: Arduino OLED Snake Game: 3 askelta
Video: Arduino Snake Game on an OLED display. 2024, Heinäkuu
Anonim
Arduino OLED Snake Game
Arduino OLED Snake Game

Hei ja tervetuloa, oppaistamme OLED -pelin tekemiseen ja arduinoon, tämä projekti syntyi, kun yritimme tehdä ensimmäistä peliä arduinon kanssa, joten ajattelimme, mistä olisi parempi aloittaa kuin nokia classic Snake (no ainakin käärme klooni:)).

Mitä tarvitset

Tarvikkeet

Arduino UNO tai klooni

OLED -näyttö

4 diodia

500-1k vastus

4 ohjainpainiketta

Passiivinen Piezo -summeri

valinnainen

Juotamaton leipälauta

Huomaa, että nämä linkit ovat vain esimerkkejä

Vaihe 1: Piiri

Piiri
Piiri

Yllä olevassa kuvassa näet piirimme, käytämme arduinossa olevaa tappia d3 keskeytyspyyntönappina, jotta arduino asettaa etusijalle ohjaimen tulojen lukemisen, jotka ovat d4 d5 d6 d7. Piirin perusasiat ovat, että suuntanäppäintä painetaan, joka nousee korkealle 5v, mikä aktivoi keskeytyspyyntönavan (d3 violetti lanka) ja vastaavan suuntaisen nastan, keskeytystoiminto kutsuu päivityssuuntafunktion ja koodi liikuttaa käärmettä vastaavasti. Nasta 9 toimii äänitapina, koska se on PWM (~ pulssileveyden modulaatio), joka on kytketty suoraan + -tapin 5 V pietsoon ja - palaa 0 V/maahan.

(Tiedotus arduino uno -laitteessa ja kloonit vain d2 ja d3 voivat toimia keskeytyspyyntönopeina).

Suuntatapit:

d4 YLÖS ORANSSI

d5 alas PINK

d6 Vasen SININEN

d7 Oikea RUSKEA

d9 ääni HARMAA

Jokaisella painikkeella on 5 V: n liitäntätulo ja ulostulo, joka on ensin kytketty vastaavaan digitaalituloon arduinossa, jokaisen painikkeen sama lähtö kytketään sitten omaan diodiinsa, käytämme diodeja pysäyttämään jännitteen syöttö takaisin muut painikkeet ja niiden aktivointi. Kaikkien 4 diodin katodipäässä (-) liitämme ne yhteen luodaksemme lähtöliitännän, joka muodostaa yhteyden d3: een ja sitten vastuksen kautta 0v/maahan vetämään arduino-nastat matalalle, jotta ei jää kelluvia nastoja, kun niitä ei ole aktivoitu.

(FYI kelluva nasta voi vastaanottaa fantomijännitteen ja aiheuttaa epätavallista käyttäytymistä)

Näytön ohjaamiseen käytetään 2 analogista nastaa, nämä ovat arduino -laitteiston i2c -nastat.

A5 on kytketty SCL KELTAISEEN

A4 on liitetty SDA GREENiin

Arduino +5v ja 0v (maadoitus) -lähtöä käytetään koko piirin virtalähteenä, jota voidaan käyttää USB- tai puhelinlaturilla.

Vaihe 2: Koodi

// ------------------------ ANJAWARE SNAKE -pelit Verkkokansojen avulla --------------- -------

#sisältää

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // näyttöjoukko (leveys, korkeus) Adafruit_SSD1306 -näyttö (128, 64); // määrittele syöttönastat, nämä ovat arduino -nastat, joita ne eivät koskaan muuta, joten #define #define INTPIN 3 // vain nastat 2 ja 3 voivat olla katkaisunappeja UNO: ssa #define UPPIN 4 // nämä ovat nastat kytketty tp asiaankuuluva kytkin #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // määritä reittiohjeet #define DIRUP 1 // nämä arvot ovat mitä "käärme" katsoo päättääkseen- #define DIRDOWN 2 // suunnan, jonka käärme kulkee # määritä DIRLEFT 3 #define DIRRIGHT 4

// aseta painikemuuttujat

// volitile cos tarvitsemme sen päivitettäväksi keskeytyksen kanssa, joten se voi olla mikä tahansa jakson arvo

// ei ole koskaan korkeampi kuin 4, joten resurssien säästämiseksi tarvitaan vain 8 -bittinen int. haihtuva uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // käytämme tätä asetukseksi "tunnistaa", mihin suuntaan painettu bool butleft = 0; bool butright = 0;

// käärme ints

tavu käärmePosX [30]; // matriisi käärmeen kehon muodostamiseksi tavu käärmePosY [30];

int käärmeX = 30; // käärmeen pää

int käärmeY = 30; int snakeSize = 1; // käärmeiden lukumäärä rajoittuu taulukon kokoon

// maailman ints

uint8_t worldMinX = 0; // nämä asettavat leikkialueen rajat

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

// kerää scran (ruoka) ja scranin sijainti

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

// pisteet muuttujia

pitkä toistotulos = 0; pitkä huipputulos = 30; // aseta korkeat pisteet arvoon 3 kerätä lähtökohtana

// --------------------------- tätä keskeytys suorittaa jännitteen noustessa ------------ -------------

void keskeytetty () {viive (150); // pieni viive lisättyyn "pomppimissuojaukseen" päivitettysuunta (); } // ------------------ päivittää suunta-arvon painikkeen painalluksella ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // tarkista mikä tulo meni korkealle ja aseta asiaankuuluva bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // nämä jos lausunnot katsovat, mikä syöttö oli korkea ja syöttää asianmukaisen arvon "painettu" // -muuttujaan, tämä muuttuja sanelee liikesuunnan, jos (butup == true) {buttonpressed = DIRUP; // Serial.println ("YLÖS painettu"); // Serial.println (painiketta painettu); butup = väärä; sävy (SND, 1500, 10); } if (butdown == true) {painiketta painettu = DIRDOWN; // Serial.println ("ALAS painettu"); // Serial.println (painiketta painettu); butdown = epätosi; sävy (SND, 1500, 10); }

jos (butleft == true)

{painettu = DIRLEFT; // Serial.println ("VASEN painettu"); // Serial.println (painiketta painettu); butleft = väärä; sävy (SND, 1500, 10); } if (butright == true) {painettuna = DIRRIGHT; // Serial.println ("OIKEA painettu"); // Serial.println (painiketta painettu); butright = väärä; sävy (SND, 1500, 10); }}

// -------------------------- piirrä näyttörutiineja ------------------ -----------------

void updateDisplay () // piirtää tulokset ja ääriviivat

{// Serial.println ("Päivitä näyttö");

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

display.setTextSize (0); display.setTextColor (VALKOINEN); // piirrä pisteet display.setCursor (2, 1); display.print ("Pisteet:"); display.print (Merkkijono (toistotulos, DEC)); display.setCursor (66, 1); display.print ("Korkea:"); display.print (Jono (huipputulos, DEC)); // piirrä leikkialue // pos 1x, 1y, 2x, 2y, värinäyttö.drawLine (0, 0, 127, 0, WHITE); // äärimmäisen reunan näyttö.drawLine (63, 0, 63, 9, WHITE); // pisteiden erottimen näyttö.drawLine (0, 9, 127, 9, WHITE); // tekstin reunanäytön alla.drawLine (0, 63, 127, 63, WHITE); // alareunan näyttö.drawLine (0, 0, 0, 63, WHITE); // vasemman reunan näyttö.drawLine (127, 0, 127, 63, WHITE); // oikea raja

}

// ----------------------------------- päivitä leikkialue ---------- --------------------

void updateGame () // tämä päivittää pelialueen näytön

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// tarkista käärmeen rutiinit

jos (outOfArea () || itsetörmäys ())

{ peli ohi(); }

// näytä käärme

for (int i = 0; i0; i--) {snakePosX = käärmePosX [i-1]; snakePosY = käärmePosY [i-1]; } // lisää ylimääräinen pikseli käärmeeseen, jos (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = käärmeY; }

kytkin (painiketta painettuna) // oli snakeDirection

{tapaus DIRUP: käärmeY- = 1; tauko; tapaus DIRDOWN: käärmeY+= 1; tauko; tapaus DIRLEFT: snakeX- = 1; tauko; tapaus DIRRIGHT: käärmeX+= 1; tauko; } snakePosX [0] = käärmeX; snakePosY [0] = käärmeY; updateDisplay (); display.display (); // --------------------- aseta scran -------------------

tyhjä paikkaScran ()

{scranPosX = satunnainen (worldMinX+1, worldMaxX-1); scranPosY = satunnainen (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playcore = pelitulos+10; sävy (SND, 2000, 10); updateDisplay (); paikkaScran (); paluu 1; } else {return 0; }} // --------------------- alueen ulkopuolella ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- peli ohi----------------------- --- mitätön gameOver () {uint8_t rectX1, rectY1, rectX2, rectY2; rectX1 = 38; rectY1 = 28; rectX2 = 58; rectY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); sävy (SND, 2000, 50); display.print ("PELI"); sävy (SND, 1000, 50); display.print ("OVER"); if (playcore> = huipputulos) // tarkista, onko pisteet korkeammat kuin {highscore = playscore; // single if statment to update high score} for (int i = 0; i <= 16; i ++) // tämä on piirtää suorakulmioita pelin ympärille {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("jos silmukka"); display.display (); rectX1- = 2; // siirtyminen 2 pikseliä rectY1- = 2; rectX2+= 4; // siirtyminen 2 pikselin yli viimeisestä pisteestä rectY2+= 4; ääni (SND, i*200, 3); } display.display (); // Näytön pyyhkiminen mainoksen jälkeen rectX1 = 0; // aseta suoran aloituspaikka rectY1 = 0; rectX2 = 0; rectY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, BLACK); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); playcore = 0; // nollaa käärme ja pelaajan tiedot snakeSize = 1; käärmeX = näyttö.leveys ()/2; käärmeY = näyttö.korkeus ()/2; waitForPress (); // odota pelaajan aloittavan pelin} // ------------------------- odota painosilmukkaa ---------- --------------- mitätön waitForPress () {bool odottaa = 0; // silmukka päättyy, kun tämä on todellinen näyttö.clearDisplay (); while (odottaa == 0) {drawALineForMe (WHITE); // piirrä satunnainen valkoinen viiva drawALineForMe (BLACK); // piirrä satunnainen musta viiva, jotta näyttö ei täytä kokonaan valkoista näyttöä. fillRect (19, 20, 90, 32, BLACK); // tyhjä tausta tekstinäytölle.setTextColor (VALKOINEN); display.setCursor (35, 25); display.setTextSize (2); // isompi fonttinäyttö.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // raja Snake display.drawRect (19, 20, 90, 32, WHITE); // reunuslaatikko - 3 display.setCursor (28, 42); display.setTextSize (0); // fontti takaisin normaalinäyttöön.println ("paina mitä tahansa näppäintä"); display.display (); odottaa = digitalRead (INTPIN); // tarkista, muuttuuko odottavan näppäimen painallus 1: ksi, kun painiketta painetaan = 0; // nollauspainikkeen painaminen}} // -------------------- DRAW satunnaisen rivin tuloväri uint8_t -------------- ----- mitätön drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // aseta viivalle satunnaiset koordinaatit ja piirrä se // muuttuja vähintään yhtä line1X = satunnainen (worldMinX+1, worldMaxX-1); line1Y = satunnainen (worldMinY+1, worldMaxY-1); line2X = satunnainen (worldMinX+1, worldMaxX-1); line2Y = satunnainen (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------ törmäyksen havaitseminen -------- -----------------------

for (tavu i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; sävy (SND, 2000, 20); sävy (SND, 1000, 20); } palauta 0; }

//-------------------------------- PERUSTAA--------------- -------------------------------

void setup () {viive (100); // anna tavaroille mahdollisuus "käynnistyä" // Serial.begin (9600); // poista valinta tästä, jos haluat nähdä sarjalähtöjen näytön.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // aloita puhtaalla näytöllä display.setTextColor (WHITE); // määritä tekstin värin kiertokoko jne. display.setRotation (0); display.setTextWrap (epätosi); display.dim (0); // aseta näytön kirkkaus pinMode (INTPIN, INPUT); // aseta oikeat portit tuloille pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // tämä on interupt-komento, joka "pysäyttää" arduinon lukemaan tulot // komento- funktio- nasta-toiminto suorittamaan ehdon pin attachInterrupt (digitalPinToInterrupt (INTPIN), keskeytetty, RISING); // Serial.println ("Asennus hyväksytty"); waitForPress (); // näytä käärmeen aloitusnäyttö placeScran (); // laita ensimmäinen ruokalaji} // --------------------- PÄÄSILMU ----------------- ---------------------- void loop () {updateGame (); // tämä toiminto kantaa pääkoodin}

Vaihe 3:

Suositeltava: