Obsah:

Arduino OLED Snake Game: 3 kroky
Arduino OLED Snake Game: 3 kroky

Video: Arduino OLED Snake Game: 3 kroky

Video: Arduino OLED Snake Game: 3 kroky
Video: Arduino návody | LCD Shield 16x2 a tlačítka 2024, Červenec
Anonim
Arduino OLED Snake Game
Arduino OLED Snake Game

Ahoj, vítejte, v našich instrukcích o tom, jak vyrábět a arduino OLED hru, tento projekt vznikl, když jsme se pokoušeli udělat naši vůbec první hru s arduinem, aha, řekli jsme si, kde je lepší začít než klasická Nokia Snake (dobře na alespoň hadí klon:)).

Co budete potřebovat

Zásoby

Arduino UNO nebo klon

OLED displej

4 diody

Odpor 500-1k

4 tlačítka ovladače

Pasivní piezo bzučák

volitelný

Bezpájecí BreadBoard

Tyto odkazy jsou například pouze

Krok 1: Okruh

Okruh
Okruh

Na výše uvedeném obrázku vidíte náš obvod, používáme pin d3 na arduinu jako pin požadavku na přerušení, takže arduino dá přednost čtení vstupů ovladače, které jsou d4 d5 d6 d7. Základem obvodu je, že je stisknuto směrové tlačítko, které jde vysoko 5v, čímž se aktivuje pin požadavku na přerušení (fialový vodič d3) a odpovídající směrový kolík, funkce přerušení volá funkci aktualizace směru a kód podle toho pohybuje hadem. Pin 9 se používá jako zvukový pin, protože je to PWM (~ modulace šířky impulzů), která je připojena přímo k 5v piezo na kolíku + a - přejde zpět na 0v/zem.

(FYI na arduino uno a klonech pouze d2 a d3 mohou fungovat jako piny požadavku na přerušení).

Směrové kolíky:

d4 Nahoru ORANŽOVÁ

d5 Dolů RŮŽOVÁ

d6 Vlevo MODRÁ

d7 Vpravo HNĚDÁ

d9 zvuk ŠEDÝ

Každé tlačítko má vstup pro připojení 5 V a výstup, který je nejprve připojen k jejich příslušnému digitálnímu vstupu na Arduinu, stejný výstup každého tlačítka je pak připojen k vlastní diodě, pomocí diod zastavíme přívod napětí zpět do další tlačítka a jejich aktivace. Na katodovém (-) konci všech 4 diod je spojíme dohromady, abychom vytvořili výstupní spojení, které se připojí k d3 a poté přes odpor na 0 V/Zemi, aby se piny arduino stáhly nízko, aby nezůstávaly plovoucí piny, když nejsou aktivováno.

(Pro informaci, plovoucí kolík může přijímat fantomové napětí a způsobovat neobvyklé chování)

K ovládání displeje jsou použity 2 analogové piny, jedná se o piny hardwaru i2c arduino.

A5 je připojen k SCL ŽLUTĚ

A4 je připojen k SDA GREEN

Výstup +5v a 0v (uzemnění) z arduina se používá jako zdroj energie pro celý obvod, který lze napájet pomocí USB nebo telefonní nabíječky.

Krok 2: Kód

// ------------------------ Hry ANJAWARE SNAKE S pomocí lidí ze sítě --------------- -------

#zahrnout

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // sada zobrazení (šířka, výška) Adafruit_SSD1306 displej (128, 64); // definujte vstupní piny to jsou piny na arduinu, které se nikdy nemění, takže #define #define INTPIN 3 // pouze piny 2 a 3 mohou být přerušovací piny na UNO #define UPPIN 4 // to jsou piny připojené tp relevantní přepínač #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // definovat směry #define DIRUP 1 // tyto hodnoty je to, na co se „had“dívá, aby rozhodl- #definovat DIRDOWN 2 // směr, kterým se bude had pohybovat # definujte DIRLEFT 3 #define DIRRIGHT 4

// nastavení proměnných tlačítek

// volitilní cos potřebujeme, aby se aktualizoval s přerušením, takže může být jakýkoli bit hodnoty cyklu

// nikdy není vyšší než 4, takže k uložení zdrojů stačí nestabilní 8bit int uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // toto použijeme k nastavení true na "detekci", kterým směrem stiskl bool butleft = 0; bool butright = 0;

// hadí inti

byte snakePosX [30]; // pole pro vytvoření těla hadího bytu snakePosY [30];

int snakeX = 30; // poloha hlavy hada

int hadYY = 30; int snakeSize = 1; // počet velikostí hada omezený na velikost pole

// světoví intři

uint8_t worldMinX = 0; // tyto nastavují limity hrací plochy

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

// sbírat scran (jídlo) a polohu scranu

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

// skóruje proměnné

dlouhý playcore = 0; dlouhé nejvyšší skóre = 30; // jako výchozí bod nastavte vysoké skóre na 3

// --------------------------- to je to, co přerušení provádí při nárůstu napětí ------------ -------------

void interruptpressed () {delay (150); // mírné zpoždění pro přidanou ochranu "odrazit" updatedirection (); } // ------------------ aktualizujte hodnotu směru stisknutím tlačítka ----------------- neplatné aktualizované směrování () { // Serial.println ("Updatedirection"); butup = digitalRead (UPPIN); // zkontrolujte, který vstup byl vysoký, a nastavte relevantní bool true butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // tyto, pokud se statemeents podívají na to, který vstup se zvýšil, a zadá příslušnou hodnotu do proměnné „stisknutí tlačítka“//, tato proměnná určuje směr pohybu, pokud (butup == true) {buttonpressed = DIRUP; // Serial.println ("stisknuto NAHORU"); // Serial.println (stisknutí tlačítka); butup = false; tón (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOLŮ stisknuto"); // Serial.println (stisknutí tlačítka); butdown = false; tón (SND, 1500, 10); }

if (butleft == true)

{buttonpressed = DIRLEFT; // Serial.println ("VLEVO stisknuto"); // Serial.println (stisknutí tlačítka); butleft = false; tón (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("PRAVĚ stisknuto"); // Serial.println (stisknutí tlačítka); butright = false; tón (SND, 1500, 10); }}

// -------------------------- nakreslete rutiny zobrazení ------------------ -----------------

void updateDisplay () // kreslení skóre a obrysů

{// Serial.println ("Aktualizovat zobrazení");

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

display.setTextSize (0); display.setTextColor (BÍLÁ); // kreslení skóre display.setCursor (2, 1); display.print ("Skóre:"); display.print (String (playcore, DEC)); display.setCursor (66, 1); display.print ("Vysoká:"); display.print (String (highscore, DEC)); // nakreslit hrací plochu // poz 1x, 1y, 2x, 2y, barevný displej.drawLine (0, 0, 127, 0, WHITE); // zobrazení velmi horního okraje.drawLine (63, 0, 63, 9, WHITE); // oddělovač skóre display.drawLine (0, 9, 127, 9, WHITE); // pod okrajem textu display.drawLine (0, 63, 127, 63, WHITE); // spodní okraj displeje.drawLine (0, 0, 0, 63, WHITE); // levý okraj display.drawLine (127, 0, 127, 63, WHITE); // pravý okraj

}

// ----------------------------------- aktualizovat hrací plochu ---------- --------------------

void updateGame () // toto aktualizuje zobrazení herní oblasti

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// kontrola hadích rutin

if (outOfArea () || selfCollision ())

{ konec hry(); }

// zobrazit hada

pro (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // přidejte hadovi další pixel, pokud (scranAte) {snakeSize+= 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

přepínač (stisknutí tlačítka) // byl snakeDirection

{case DIRUP: snakeY- = 1; přestávka; případ DIRDOWN: snakeY+= 1; přestávka; pouzdro DIRLEFT: snakeX- = 1; přestávka; pouzdro DIRRIGHT: snakeX+= 1; přestávka; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; updateDisplay (); display.display (); // --------------------- umístit scran -------------------

prázdné místo Scran ()

{scranPosX = random (worldMinX+1, worldMaxX-1); scranPosY = random (worldMinY+1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore+10; tón (SND, 2000, 10); updateDisplay (); placeScran (); návrat 1; } else {return 0; }} // --------------------- mimo oblast ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- konec hry----------------------- --- 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); tón (SND, 2000, 50); display.print („HRA“); tón (SND, 1000, 50); display.print („NAD“); if (playscore> = highscore) // zkontrolujte, zda je skóre vyšší než vysoké skóre {highscore = playscore; // single if statment pro aktualizaci vysokého skóre} for (int i = 0; i <= 16; i ++) // toto je kreslení přímek kolem hry přes {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("if loop"); display.display (); rectX1- = 2; // posun o 2 pixely rectY1- = 2; rectX2+= 4; // posun přes 2 pixely z posledního bodu rectY2+= 4; tón (SND, i*200, 3); } display.display (); // Vymazání obrazovky po slávě přes rectX1 = 0; // nastavení počáteční polohy řádku rectY1 = 0; rectX2 = 0; rectY2 = 63; pro (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; // reset hada a detailu hráče snakeSize = 1; snakeX = display.width ()/2; snakeY = display.height ()/2; waitForPress (); // počkejte, až hráč zahájí hru} // ------------------------- počkejte na smyčku stisknutí ---------- --------------- neplatné čekáníForPress () {bool čekání = 0; // smyčka končí, když je to pravda display.clearDisplay (); while (čeká == 0) {drawALineForMe (WHITE); // nakreslete náhodnou bílou čáru drawALineForMe (ČERNÁ); // nakreslete náhodnou černou čáru, aby obrazovka zcela nevyplnila bílý displej.fillRect (19, 20, 90, 32, ČERNÁ); // prázdné pozadí pro textový display.setTextColor (WHITE); display.setCursor (35, 25); display.setTextSize (2); // větší písmo display.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, WHITE); // ohraničení Snake display.drawRect (19, 20, 90, 32, WHITE); // rámeček ohraničení - 3 display.setCursor (28, 42); display.setTextSize (0); // písmo zpět na normální zobrazení.println ("stiskněte libovolnou klávesu"); display.display (); čekání = digitalRead (INTPIN); // zkontrolujte, zda se čekání při stisknutí klávesy změní na 1 končící při stisknutí tlačítka = 0; // tlačítko reset reset}} // -------------------- NAKRESLI barvu vstupu náhodného řádku uint8_t -------------- ----- neplatné drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // nastavte náhodné souřadnice pro čáru a poté ji nakreslete // proměnná neméně ne více 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); } // ------------------------------------- detekce kolizí -------- -----------------------

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

//-------------------------------- ZALOŽIT--------------- -------------------------------

neplatné nastavení () {zpoždění (100); // jen dejte šanci věci „nastartovat“// Serial.begin (9600); // odškrtněte toto, pokud chcete vidět zobrazení sériových výstupů.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // začněte čistým zobrazením display.setTextColor (WHITE); // nastavení velikosti otáčení barev textu atd. display.setRotation (0); display.setTextWrap (false); display.dim (0); // nastavení pin brodeness pinMode (INTPIN, INPUT); // nastavit správné porty na vstupy pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // toto je příkaz pro přerušení, který „zastaví“arduino, aby přečetlo vstupy // příkaz- funkce- funkce pinu k provedení podmínky na pinu attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Nastavení prošlo"); waitForPress (); // zobrazení úvodní obrazovky hada placeScran (); // vložte první kousek jídla} // --------------------- HLAVNÍ SMYČKA ----------------- ---------------------- void loop () {updateGame (); // tato funkce nese hlavní kód}

Krok 3:

Doporučuje: