Satura rādītājs:

Arduino OLED čūsku spēle: 3 soļi
Arduino OLED čūsku spēle: 3 soļi

Video: Arduino OLED čūsku spēle: 3 soļi

Video: Arduino OLED čūsku spēle: 3 soļi
Video: Как использовать SSD1306 128x32 OLED-дисплей I2C с кодом Arduino 2024, Novembris
Anonim
Arduino OLED čūsku spēle
Arduino OLED čūsku spēle

Sveiki un laipni lūgti, mūsu instrukcijās par to, kā izveidot un arduino OLED spēli, šis projekts radās, kad mēs mēģinājām izveidot savu pirmo spēli ar arduino, tāpēc mēs domājām, kur sākt labāk nekā nokia classic Snake (labi vismaz čūskas klons:)).

Kas jums būs nepieciešams

Piegādes

Arduino UNO vai klons

OLED displejs

4 diodes

500-1k rezistors

4 vadības pogas

Pasīvs Piezo skaņas signāls

neobligāti

Lodmetāla maizes dēlis

Lūdzu, ņemiet vērā, ka šīs saites ir tikai piemērs

1. solis: ķēde

Ķēde
Ķēde

Iepriekš redzamajā attēlā jūs varat redzēt mūsu shēmu, mēs izmantojam arduino tapu d3 kā pārtraukuma pieprasījuma tapu, lai arduino priekšroku dotu kontroliera ievades nolasīšanai, kas ir d4 d5 d6 d7. Ķēdes pamati ir tādi, ka tiek nospiesta virziena poga, kas paceļas augstu 5v, tas aktivizē pārtraukšanas pieprasījuma tapu (d3 violeta stieple) un atbilstošu virziena tapu, pārtraukšanas funkcija izsauc atjaunināšanas virziena funkciju un šis kods attiecīgi pārvieto čūsku. Tapu 9 izmanto kā skaņas tapu, jo tā ir PWM (~ impulsa platuma modulācija), kas ir tieši savienota ar 5 voltu pjezo uz + tapas un - atgriežas pie 0v/zemes.

(FYI uz arduino uno un kloniem tikai d2 un d3 var darboties kā pārtraukšanas pieprasījuma tapas).

Virziena tapas:

d4 Uz augšu ORANGE

d5 Uz leju rozā

d6 pa kreisi ZILA

d7 Pa labi BROWN

d9 skaņa PELĒKA

Katrai pogai ir 5 V savienojuma ieeja un izeja, kas vispirms ir pievienota attiecīgajai digitālajai ieejai arduino, šī pati katras pogas izeja tiek pievienota savai diodei, mēs izmantojam diodes, lai pārtrauktu sprieguma atgriešanos atpakaļ uz citas pogas un to aktivizēšana. Visu 4 diodes katoda (-) galā mēs savienojam tos kopā, lai izveidotu izejas krustojumu, kas savienojas ar d3 un pēc tam caur a rezistoru līdz 0v/zemei, lai arduino tapas novilktu zemu, lai neatstātu peldošās tapas, kad tās netiek aktivizēts.

(FYI peldošā tapa var saņemt fantoma spriegumu un izraisīt neparastu uzvedību)

Displeja vadīšanai tiek izmantotas 2 analogās tapas, tās ir arduino aparatūras i2c tapas.

A5 ir pievienots SCL YELLOW

A4 ir pievienots SDA GREEN

+5v un 0v (zeme) izeja no arduino tiek izmantota kā strāvas avots visai ķēdei, ko var darbināt ar USB vai tālruņa lādētāju.

2. darbība: kods

// ------------------------ ANJAWARE SNAKE Games Ar tīkla tautu palīdzību --------------- -------

#iekļaut

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // displeja komplekts (platums, augstums) Adafruit_SSD1306 displejs (128, 64); // definējiet ievades tapas, tās ir arduino tapas, kuras tās nekad nemainās, tāpēc #define #define INTPIN 3 // tikai 2. un 3. tapas var būt pārtrauktas tapas uz UNO #define UPPIN 4 // tās ir savienotas tapas tp attiecīgais slēdzis #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // definēt virzienus #define DIRUP 1 // šīs vērtības ir tas, uz ko "čūska" skatās, lai izlemtu- #define DIRDOWN 2 // virzienā, kurā čūska brauks # definēt DIRLEFT 3 #define DIRRIGHT 4

// iestatīt pogu mainīgos

// volitile cos mums tas ir jāatjaunina ar pārtraukumu, tāpēc var būt jebkura cikla vērtība

// nekad nav lielāks par 4, tāpēc resursu taupīšanai nepieciešams tikai 8 bitu int. gaistošs uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // mēs to izmantojam, lai iestatītu patiesu, lai "noteiktu", kurā virzienā spieda bool butleft = 0; bool butright = 0;

// čūska ints

baits snakePosX [30]; // masīvs, lai izveidotu čūskas ķermeņa baitu snakePosY [30];

int čūskaX = 30; // čūskas galvas stāvoklis

int čūskaY = 30; int snakeSize = 1; // čūsku izmēru skaits ir ierobežots līdz masīva lielumam

// pasaule ints

uint8_t worldMinX = 0; // tie nosaka rotaļu laukuma robežas

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

// savākt skranu (ēdienu) un skrāna stāvokli

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

// vērtē mainīgos

garš atskaņošanas rezultāts = 0; garš rekords = 30; // iestatiet augstu rezultātu uz 3 savākt kā sākumpunktu

// --------------------------- tas ir tas, ko pārtraukums izpilda, palielinoties spriegumam ------------ -------------

void interruptpressed () {kavēšanās (150); // neliela aizkavēšanās papildu "atlēcienu" aizsardzības atjauninātai virzienam (); } // ------------------ atjauniniet virziena vērtību, nospiežot pogu ----------------- void updatedirection () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // pārbaudiet, kura ievade bija augsta, un iestatiet atbilstošo bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // šie, ja statūti aplūko, kura ievade ir paaugstināta, un ievada attiecīgo vērtību mainīgā "buttonpressed" //, šis mainīgais diktē kustības virzienu, ja (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP nospiests"); // Serial.println (nospiesta poga); butup = nepatiess; tonis (SND, 1500, 10); } if (butdown == true) {poga nospiesta = DIRDOWN; // Serial.println ("Nospiest uz leju"); // Serial.println (nospiesta poga); butdown = nepatiess; tonis (SND, 1500, 10); }

ja (butleft == true)

{nospiesta poga = DIRLEFT; // Serial.println ("Nospiests pa kreisi"); // Serial.println (nospiesta poga); butleft = nepatiess; tonis (SND, 1500, 10); } ja (butright == true) {poga nospiesta = TIEŠA; // Serial.println ("Nospiests pa labi"); // Serial.println (nospiesta poga); butright = nepatiess; tonis (SND, 1500, 10); }}

// -------------------------- uzzīmējiet displeja kārtību ------------------ -----------------

void updateDisplay () // zīmēt punktus un kontūras

{// Serial.println ("Atjaunināt displeju");

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

display.setTextSize (0); display.setTextColor (BALTS); // zīmēt rādītājus display.setCursor (2, 1); display.print ("Rezultāts:"); display.print (String (playcore, DEC)); display.setCursor (66, 1); display.print ("Augsts:"); display.print (String (tops, DEC)); // zīmēt rotaļu laukumu // poz 1x, 1y, 2x, 2y, krāsu displejs.drawLine (0, 0, 127, 0, WHITE); // ļoti augšējās robežas displejs.drawLine (63, 0, 63, 9, WHITE); // rezultātu atdalītāja displejs.drawLine (0, 9, 127, 9, WHITE); // zem teksta apmales displeja.drawLine (0, 63, 127, 63, WHITE); // apakšējās robežas displejs.drawLine (0, 0, 0, 63, WHITE); // kreisās malas displejs.drawLine (127, 0, 127, 63, WHITE); // labā robeža

}

// ----------------------------------- atjauniniet spēļu zonu ---------- --------------------

void updateGame () // tas atjaunina spēles apgabala displeju

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// pārbaudīt čūsku rutīnas

ja (outOfArea () || selfCollision ())

{ spēle beigusies(); }

// parādīt čūsku

par (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = čūskaPosY [i-1]; } // pievienojiet čūskai papildu pikseļu, ja (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = čūskaY; }

slēdzis (nospiesta poga) // bija čūskaDirection

{gadījums DIRUP: čūskaY- = 1; pārtraukums; gadījums DIRDOWN: čūskaY+= 1; pārtraukums; gadījums DIRLEFT: snakeX- = 1; pārtraukums; gadījums TIESĪBAS: čūskaX+= 1; pārtraukums; } snakePosX [0] = snakeX; snakePosY [0] = čūskaY; updateDisplay (); display.display (); // --------------------- novietojiet skranu -------------------

tukša vietaScran ()

{scranPosX = nejaušs (worldMinX+1, worldMaxX-1); scranPosY = nejaušs (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playcore = playcore+10; tonis (SND, 2000, 10); updateDisplay (); placeScran (); atgriešanās 1; } cits {atgriezties 0; }} // --------------------- ārpus zonas ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- spēle beigusies----------------------- --- 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); tonis (SND, 2000, 50); display.print ("SPĒLE"); tonis (SND, 1000, 50); display.print ("OVER"); if (playcore> = rekords) // pārbaudiet, vai rezultāts ir augstāks par labāko rezultātu {highscore = playscore; // viens, ja statments, lai atjauninātu augstu rezultātu} par (int i = 0; i <= 16; i ++) // tas ir izdarīt taisnstūrus ap spēli virs {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("ja cilpa"); display.display (); rectX1- = 2; // pārslēgties par 2 pikseļiem rectY1- = 2; rectX2+= 4; // pāriet no 2 punktiem virs pēdējā punkta rectY2+= 4; tonis (SND, i*200, 3); } display.display (); // Ekrāna noslaukšana pēc slavas virs rectX1 = 0; // iestatīt līnijas rectY1 sākuma stāvokli = 0; rectX2 = 0; rectY2 = 63; par (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; // atiestatīt čūsku un spēlētāja informāciju snakeSize = 1; čūskaX = displejs.platums ()/2; čūskaY = displejs.augstums ()/2; waitForPress (); // pagaidiet, kamēr spēlētājs sāks spēli} // ------------------------- gaidiet preses cilpu ---------- --------------- void waitForPress () {bool gaidot = 0; // cilpa beidzas, ja tas ir patiess displejs.clearDisplay (); kamēr (gaida == 0) {drawALineForMe (BALTS); // izdarīt nejaušu baltu līniju drawALineForMe (BLACK); // uzzīmē nejaušu melnu līniju, lai ekrāns pilnībā neaizpildītu balto displeju.fillRect (19, 20, 90, 32, BLACK); // tukšs fons teksta attēlošanai.setTextColor (BALTS); display.setCursor (35, 25); display.setTextSize (2); // lielāks fontu displejs.println ("SNAKE"); // x y w h r col displejs.drawRoundRect (33, 22, 62, 20, 4, WHITE); // robeža Snake display.drawRect (19, 20, 90, 32, WHITE); // robežu kaste - 3 displejs.setCursor (28, 42); display.setTextSize (0); // fonts atpakaļ normālā displejā.println ("nospiediet jebkuru taustiņu"); display.display (); gaidīšana = digitalRead (INTPIN); // pārbaudiet, vai nospiežot taustiņu gaidīšana, mainīsies uz 1 beigām, kamēr poga tiek nospiesta = 0; // atiestatīšanas pogas nospiešana}} // -------------------- ZĪMĒT nejaušas līnijas ievades krāsu uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // noteikt līnijai nejaušas koordinātas, pēc tam to uzzīmēt // mainīgais ne mazāk ne vairāk line1X = random (worldMinX+1, worldMaxX-1); line1Y = nejaušs (worldMinY+1, worldMaxY-1); line2X = nejaušs (worldMinX+1, worldMaxX-1); line2Y = nejaušs (worldMinY+1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------ sadursmes noteikšana -------- -----------------------

par (baits i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; tonis (SND, 2000, 20); tonis (SND, 1000, 20); } atgriezties 0; }

//-------------------------------- UZSTĀDĪT--------------- -------------------------------

void setup () {kavēšanās (100); // vienkārši dodiet sīkumiem iespēju "boot" // Serial.begin (9600); // noņemiet atzīmi no šīs izvēles rūtiņas, ja vēlaties redzēt sērijas izvades displeju.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // sākt ar tīru displeju display.setTextColor (WHITE); // iestatīt teksta krāsu rotācijas lielumu utt. display.setRotation (0); display.setTextWrap (nepatiess); displejs.dim (0); // iestatiet displeja spilgtumu pinMode (INTPIN, INPUT); // iestatiet pareizos portus ieejām pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // šī ir pārtraukuma komanda, kas "aptur" arduino, lai nolasītu ieejas // komanda- funkcija- pin funkcija, lai izpildītu nosacījumu uz pin attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Iestatīšana nodota"); waitForPress (); // parādīt čūskas sākuma ekrānu placeScran (); // ievietojiet pirmo ēdiena gabalu} // --------------------- GALVENĀ LOOP ----------------- ---------------------- void loop () {updateGame (); // šī funkcija nes galveno kodu}

3. darbība:

Ieteicams: