INHOUDSOPGAWE:

Arduino OLED -slangspel: 3 stappe
Arduino OLED -slangspel: 3 stappe

Video: Arduino OLED -slangspel: 3 stappe

Video: Arduino OLED -slangspel: 3 stappe
Video: Генератор ритмических паттернов Arduino 8x8 Gate Sequencer с двумя поворотными энкодерами и OLED- 2024, Desember
Anonim
Arduino OLED slangspel
Arduino OLED slangspel

Hallo en welkom, ons instruksies oor hoe om 'n OLED -speletjie en arduino te maak, hierdie projek het ontstaan terwyl ons probeer het om ons eerste wedstryd ooit met 'n arduino te maak, soooo, ons het gedink waar is dit beter om te begin as die Nokia Classic Snake (wel by ten minste 'n slangkloon:)).

Wat u benodig

Voorrade

Arduino UNO of kloon

OLED -skerm

4 diodes

500-1k weerstand

4 beheer knoppies

Passiewe Piezo -zoemer

opsioneel

Soldeerlose broodbord

Let asseblief daarop dat hierdie skakels slegs byvoorbeeld is

Stap 1: Die stroombaan

Die stroombaan
Die stroombaan

In die foto hierbo kan u ons stroombaan sien; ons gebruik pen d3 op die arduino as 'n onderbrekingspen, sodat die arduino voorrang sal gee aan die lees van die kontrole -insette wat d4 d5 d6 d7 is. Die basiese beginsels van die stroombaan is dat 'n rigtingknoppie ingedruk word wat hoog 5v gaan, dit aktiveer die onderbrekingspen (d3 pers draad) en 'n ooreenstemmende rigtingpen, die onderbrekingsfunksie noem 'n opdateringsrigtingfunksie en die kode beweeg die slang dienooreenkomstig. Speld 9 word as die klankpen gebruik, aangesien dit 'n PWM (~ polswydte modulasie) is wat direk gekoppel is aan 'n 5v piëzo op die + pen en die - gaan terug na 0v/grond.

(Tereg op die arduino uno en klone slegs d2 en d3 kan as onderbrekingsversoekpenne optree).

Rigtingspenne:

d4 ORANJE op

d5 ROOS af

d6 BLOU links

d7 Regs BRUIN

d9 klink Grys

Elke knoppie het 'n in -5v aansluitingsingang en 'n uitgang wat eers gekoppel is aan hul onderskeie digitale ingang op die arduino. ander knoppies en aktiveer dit. Aan die einde van die katode (-) van al 4 diodes verbind ons hulle om 'n uitgangskruising te skep wat aansluit by d3 en dan deur die a weerstand na 0v/aarde om die arduino-penne laag te trek om nie drywende penne te laat as hulle nie geaktiveer.

(Terloops, 'n dryfpen kan fantoomspanning ontvang en ongewone gedrag veroorsaak)

2 analoog penne word gebruik om die skerm te bestuur, dit is die arduino hardeware i2c -penne.

A5 is gekoppel aan SCL GEEL

A4 is gekoppel aan SDA GREEN

Die +5v en 0v (aarde) uitset van die arduino word gebruik as die bron van die krag vir die hele stroombaan wat deur 'n usb- of telefoonlaaier aangedryf kan word.

Stap 2: Die kode

// ------------------------ ANJAWARE SNAKE-speletjies Met hulp van die netto mense --------------- -------

#insluit

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // display set (width, height) Adafruit_SSD1306 display (128, 64); // definieer invoerpenne dit is die penne op die arduino, hulle verander nooit, so #definieer #definieer INTPIN 3 // slegs penne 2 en 3 kan penne op UNO wees #definieer UPPIN 4 // dit is penne wat gekoppel is tp relevante skakelaar #definieer DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // definieer aanwysings #definieer DIRUP 1 // hierdie waardes is waarna die "slang" kyk om te besluit- #define DIRDOWN 2 // die rigting waarin die slang sal beweeg # definieer DIRLEFT 3 #define DIRRIGHT 4

// stel knoppie veranderlikes

// onwankelbaar omdat ons dit nodig het om by te werk met die onderbreking, sodat dit 'n bietjie sikluswaarde kan wees

// is nooit hoër as 4 nie, dus benodig slegs 8bit int om hulpbronne te bespaar vlugtig uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // ons gebruik dit om waar te stel om "op te spoor" in watter rigting bool butleft = 0 gedruk word; bool butright = 0;

// slang ints

byte slangPosX [30]; // skikking om die liggaam van slangbyte te maak slangPosY [30];

int slangX = 30; // slangkop posisie

int slangY = 30; int snakeSize = 1; // aantal slanggroottes beperk tot die grootte van die skikking

// world ints

uint8_t worldMinX = 0; // dit stel die grense van die speelarea

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

// versamel scran (voedsel) en posisie van scran

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

// tellings veranderlikes

lang speelpunt = 0; lang telling = 30; // stel die hoë telling op 3 versamel as 'n beginpunt

// --------------------------- dit is wat die interupt uitvoer by spanningstyging ------------ -------------

leegte onderbreek onderdruk () {vertraging (150); // effense vertraging vir bykomende "weiering" -beskerming bygewerk (); } // ------------------ werk die rigtingwaarde op deur op die knoppie te druk ----------------- nietig opgedateerde rigting () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // kyk watter insette hoog is en stel relevante bool true butdown in = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // hierdie as statemeente kyk na watter inset hoog is en die relevante waarde in "knoppie" // veranderlike invoer, hierdie veranderlike bepaal die bewegingsrigting as (butup == waar) {buttonpressed = DIRUP; // Serial.println ("UP ingedruk"); // Serial.println (met knoppies ingedruk); butup = vals; toon (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOWN gedruk"); // Serial.println (met knoppies ingedruk); afslag = vals; toon (SND, 1500, 10); }

as (butleft == waar)

{buttonpressed = DIRLEFT; // Serial.println ("LINKS ingedruk"); // Serial.println (met knoppies ingedruk); butleft = vals; toon (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("REGS ingedruk"); // Serial.println (met knoppies ingedruk); butright = vals; toon (SND, 1500, 10); }}

// -------------------------- teken die vertoonroetines ------------------ -----------------

leegte updateDisplay () // teken tellings en buitelyne

{// Serial.println ("Update -skerm");

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

display.setTextSize (0); display.setTextColor (WIT); // teken tellings display.setCursor (2, 1); display.print ("telling:"); display.print (snaar (speelpunt, DEC)); display.setCursor (66, 1); display.print ("Hoog:"); display.print (String (highscore, DEC)); // teken speelarea // pos 1x, 1y, 2x, 2y, kleurskerm.drawLine (0, 0, 127, 0, WHITE); // heel boonste rand vertoon.drawLine (63, 0, 63, 9, WIT); // score separator display.drawLine (0, 9, 127, 9, WHITE); // onder teksgrens vertoon.drawLine (0, 63, 127, 63, WIT); // onderste rand display.drawLine (0, 0, 0, 63, WIT); // linkergrens vertoon.drawLine (127, 0, 127, 63, WIT); // regterkant

}

// ----------------------------------- speel speelarea op ---------- --------------------

void updateGame () // hiermee word die spelgebied vertoon

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// kyk na slangroetines

as (outOfArea () || selfCollision ())

{ spel verby(); }

// vertoon slang

vir (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // voeg 'n ekstra pixel by die slang as (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = slangX; snakePosY [snakeSize-1] = slangY; }

skakelaar (met die knoppie ingedruk) // was snakeDirection

{geval DIRUP: snakeY- = 1; breek; geval DIRDOWN: slangY+= 1; breek; geval DIRLEFT: slangX- = 1; breek; saak DIRRIGHT: slangX+= 1; breek; } snakePosX [0] = slangX; snakePosY [0] = slangY; updateDisplay (); vertoon.display (); // --------------------- plaas die scran -------------------

leë plekScran ()

{scranPosX = random (worldMinX+1, worldMaxX-1); scranPosY = random (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranKos () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; toon (SND, 2000, 10); updateDisplay (); placeScran (); opgawe 1; } anders {terugkeer 0; }} // --------------------- buite die gebied ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- spel verby----------------------- --- 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); toon (SND, 2000, 50); display.print ("GAME"); toon (SND, 1000, 50); display.print ("OVER"); if (playscore> = highscore) // kyk of die telling hoër is as die hoë score {highscore = playscore; // enkel as verklaring om hoë telling op te dateer} vir (int i = 0; i <= 16; i ++) // dit is om rektale langs die spel te teken oor {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("as lus"); vertoon.display (); rectX1- = 2; // skuif oor met 2 pixels rectY1- = 2; rectX2+= 4; // skuif oor 2 pixels van die laaste punt rectY2+= 4; toon (SND, i*200, 3); } vertoon.display (); // Skermvee na roem oor rectX1 = 0; // stel beginposisie van reël rectY1 = 0; rectX2 = 0; rectY2 = 63; vir (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, SWART); rectX1 ++; rectX2 ++; vertoon.display (); } display.clearDisplay (); speel telling = 0; // stel slang- en spelerbesonderhede terug snakeSize = 1; slangX = display.width ()/2; slangY = display.height ()/2; waitForPress (); // wag vir die speler om die spel te begin} // ------------------------- wag vir die perslus ---------- --------------- void waitForPress () {bool waiting = 0; // loop eindig terwyl dit 'n ware display.clearDisplay () is; terwyl (wag == 0) {drawALineForMe (WIT); // teken 'n ewekansige wit lyn drawALineForMe (SWART); // trek 'n ewekansige swart lyn sodat die skerm nie heeltemal die wit skerm vul nie.fillRect (19, 20, 90, 32, SWART); // leë agtergrond vir teksvertoning.setTextColor (WIT); display.setCursor (35, 25); display.setTextSize (2); // groter lettertipe display.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // grens Snake display.drawRect (19, 20, 90, 32, WIT); // grenskas - 3 display.setCursor (28, 42); display.setTextSize (0); // lettertipe terug na normale display.println ("druk op enige sleutel"); vertoon.display (); wag = digitalRead (INTPIN); // kyk of die wagwoord ingedruk word na 1 eindig terwyl die knoppie ingedruk word = 0; // herstel knoppie druk}} // -------------------- TEKEN 'n ewekansige lyninvoerkleur uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // stel ewekansige koördinate vir 'n lyn en teken dit dan // veranderlike nie minder nie meer 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 (reël1X, reël1Y, reël2X, reël2Y, clr); } // ------------------------------------- botsingsopsporing -------- -----------------------

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

//-------------------------------- STEL OP--------------- -------------------------------

ongeldige opstelling () {vertraging (100); // gee dinge net 'n kans om te "opstart" // Serial.begin (9600); // ontmerk dit as u die seriële uitsette wil sien. begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // begin met 'n skoon skerm display.setTextColor (WHITE); // stel die grootte van die rotasie van die kleure in, ens display.setRotation (0); display.setTextWrap (vals); vertoon.dim (0); // stel die display brighness pinMode (INTPIN, INPUT) in; // stel die korrekte poorte in op pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // dit is die onderbreekopdrag, hierdie "stop" die arduino om die insette te lees // command- function- pin-function to execute-condition on pin attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Opstelling geslaag"); waitForPress (); // die plek van die slang se opstartskerm vertoon placeScran (); // plaas eerste stukkie kos} // --------------------- HOOFSTROOM ----------------- ---------------------- void lus () {updateGame (); // hierdie funksie is die belangrikste kode}

Stap 3:

Aanbeveel: