Isi kandungan:

Permainan Ular OLED Arduino: 3 Langkah
Permainan Ular OLED Arduino: 3 Langkah

Video: Permainan Ular OLED Arduino: 3 Langkah

Video: Permainan Ular OLED Arduino: 3 Langkah
Video: Game Ular di OLED + Joystick 2024, Julai
Anonim
Permainan Ular OLED Arduino
Permainan Ular OLED Arduino

Hai dan selamat datang, kepada instruksional kami tentang cara membuat dan arduino OLED Game, projek ini bermula semasa kami berusaha untuk membuat permainan pertama kami dengan arduino, soooo, kami fikir di mana lebih baik untuk bermula daripada nokia klasik Snake (baik di sekurang-kurangnya klon ular:)).

Apa yang Anda Perlu

Bekalan

Arduino UNO atau klon

Paparan OLED

4 Diod

Perintang 500-1k

4 butang pengawal

Buzzer Piezo pasif

pilihan

Papan Roti Solderless

Harap maklum bahawa pautan ini hanya untuk contoh

Langkah 1: Litar

Litar
Litar

Pada gambar di atas anda dapat melihat litar kami, kami menggunakan pin d3 pada arduino sebagai pin permintaan gangguan sehingga arduino akan memberi keutamaan untuk membaca input pengawal yang d4 d5 d6 d7. Asas litar adalah bahawa butang arah ditekan yang naik tinggi 5v ini mengaktifkan pin permintaan gangguan (d3 dawai ungu) dan pin arah yang sepadan, fungsi interupsi memanggil fungsi arah kemas kini dan kod itu menggerakkan ular dengan sewajarnya. Pin 9 digunakan sebagai pin suara kerana merupakan PWM (~ modulasi lebar nadi) yang disambungkan terus ke piezo 5v pada pin + dan - kembali ke 0v / ground.

(FYI pada arduino uno dan klon hanya d2 dan d3 yang boleh bertindak sebagai pin permintaan gangguan).

Pin arah:

d4 Naik ORANGE

d5 PINK Bawah

d6 KIRI BIRU

d7 KEMBALI Kanan

d9 bunyi GRAY

Setiap butang mempunyai input sambungan 5v dan output yang disambungkan terlebih dahulu ke input digital masing-masing pada arduino, output yang sama setiap butang kemudian disambungkan ke diodnya sendiri, kami menggunakan dioda untuk menghentikan pemberian voltan kembali ke butang lain dan mengaktifkannya. Di hujung katod (-) keempat-empat dioda, kami menyatukannya untuk membuat persimpangan output yang menghubungkan ke d3 dan kemudian melalui perintang ke 0v / bumi untuk menarik pin arduino rendah agar tidak meninggalkan pin terapung ketika tidak berada diaktifkan.

(FYI pin terapung dapat menerima voltan hantu dan menyebabkan tingkah laku yang tidak biasa)

2 pin analog digunakan untuk menggerakkan paparan, ini adalah pin i2c perkakasan arduino.

A5 disambungkan ke SCL KUNING

A4 disambungkan ke SDA GREEN

Output +5v dan 0v (bumi) dari arduino digunakan sebagai sumber kuasa untuk keseluruhan litar yang dapat dikuasakan oleh pengecas usb atau telefon.

Langkah 2: Kodnya

// ------------------------ ANJAWARE SNAKE Games Dengan pertolongan dari net net --------------- -------

#sertakan

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // set paparan (lebar, tinggi) Paparan Adafruit_SSD1306 (128, 64); // tentukan pin input ini adalah pin di arduino yang tidak pernah mereka ubah sehingga #define #define INTPIN 3 // hanya pin 2 dan 3 boleh menjadi pin interupt pada UNO #define UPPIN 4 // ini adalah pin yang disambungkan tp suis yang berkaitan #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // tentukan arah #define DIRUP 1 // nilai-nilai inilah yang dilihat oleh "ular" untuk memutuskan- #tentukan DIRDOWN 2 // arah yang akan dilalui ular # takrifkan DIRLEFT 3 #definisi LANGSUNG 4

// tetapkan pemboleh ubah butang

// volitile cos kita memerlukannya untuk dikemas kini dengan interupt sehingga boleh menjadi sedikit nilai kitaran

// tidak pernah lebih tinggi daripada 4 jadi hanya memerlukan int 8bit untuk menjimatkan sumber yang tidak stabil uint8_t buttonpressed = 0; bool butup = 0; bool butdown = 0; // kami menggunakan ini untuk menjadi benar untuk "mengesan" arah mana yang ditekan bool butleft = 0; bool butright = 0;

// inti ular

byte snakePosX [30]; // susunan untuk menjadikan badan ular bait ularPosY [30];

int ularX = 30; // kedudukan kepala ular

int ularY = 30; int snakeSize = 1; // jumlah ukuran ular terhad kepada ukuran susunan

// ints dunia

uint8_t worldMinX = 0; // ini menetapkan had kawasan permainan

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

// kumpulkan scran (makanan) dan kedudukan scran

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

// pemboleh ubah skor

skor permainan panjang = 0; skor tinggi panjang = 30; // menetapkan skor tinggi kepada 3 mengumpulkan sebagai titik permulaan

// --------------------------- inilah yang dilakukan interupt semasa kenaikan voltan ------------ -------------

kekosongan terganggu () {kelewatan (150); // sedikit kelewatan untuk penambahan arahan pelindung "lantunan" (); } // ------------------ kemas kini nilai arah dari tekan butang ----------------- batalkan arahan yang dikemas kini () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // periksa input mana yang tinggi dan tetapkan bool yang benar butdown = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = digitalRead (RHTPIN); // ini jika statemen melihat input mana yang tinggi dan memasukkan nilai yang relevan dalam pemboleh ubah "buttonpressed" //, pemboleh ubah ini menentukan arah pergerakan jika (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP ditekan"); // Serial.println (ditekan butang); butup = palsu; nada (SND, 1500, 10); } jika (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOWN ditekan"); // Serial.println (ditekan butang); butdown = salah; nada (SND, 1500, 10); }

jika (butleft == benar)

{buttonpressed = DIRLEFT; // Serial.println ("KIRI ditekan"); // Serial.println (ditekan butang); butleft = palsu; nada (SND, 1500, 10); } jika (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("KANAN ditekan"); // Serial.println (ditekan butang); butright = palsu; nada (SND, 1500, 10); }}

// -------------------------- lukiskan rutin paparan ------------------ -----------------

batal kemas kini Paparan () // lukis skor dan garis besar

{// Serial.println ("Kemas kini Paparan");

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

display.setTextSize (0); display.setTextColor (PUTIH); // undian skor display.setCursor (2, 1); display.print ("Skor:"); display.print (Rentetan (skor permainan, DEC)); display.setCursor (66, 1); display.print ("Tinggi:"); display.print (Rentetan (skor tinggi, DEC)); // lukis kawasan permainan // pos 1x, 1y, 2x, 2y, paparan warna.drawLine (0, 0, 127, 0, WHITE); // paparan sempadan paling atas.drawLine (63, 0, 63, 9, WHITE); // skor seperator display.drawLine (0, 9, 127, 9, PUTIH); // di bawah paparan sempadan teks.drawLine (0, 63, 127, 63, WHITE); // paparan sempadan bawah.drawLine (0, 0, 0, 63, WHITE); // paparan sempadan kiri.drawLine (127, 0, 127, 63, WHITE); // sempadan kanan

}

// ----------------------------------- kemas kini kawasan permainan ---------- --------------------

batal updateGame () // ini mengemas kini paparan kawasan permainan

{display.clearDisplay ();

display.drawPixel (scranPosX, scranPosY, WHITE);

scranAte = scranFood ();

// periksa rutin ular

jika (outOfArea () || selfCollision ())

{ permainan tamat(); }

// paparkan ular

untuk (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // tambahkan piksel tambahan pada ular jika (scranAte) {snakeSize + = 1; snakePosX [snakeSize-1] = snakeX; snakePosY [snakeSize-1] = snakeY; }

suis (tekan butang) // adalah arahan ular

{kes DIRUP: snakeY- = 1; rehat; kes DIRDOWN: snakeY + = 1; rehat; kes DIRLEFT: ularX- = 1; rehat; kes DIRRIGHT: snakeX + = 1; rehat; } snakePosX [0] = snakeX; snakePosY [0] = snakeY; kemas kini Paparan (); paparan.display (); // --------------------- letakkan imbasan -------------------

tempat kosong Skrin ()

{scranPosX = rawak (worldMinX + 1, worldMaxX-1); scranPosY = rawak (worldMinY + 1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {drama skor = tempat permainan + 10; nada (SND, 2000, 10); kemas kini Paparan (); placeScran (); pulangan 1; } lain {pulangkan 0; }} // --------------------- di luar kawasan ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- permainan tamat----------------------- --- permainan batalLebih () {uint8_t rectX1, rectY1, rectX2, rectY2; rectX1 = 38; rektY1 = 28; rectX2 = 58; rectY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); nada (SND, 2000, 50); display.print ("PERMAINAN"); nada (SND, 1000, 50); display.print ("OVER"); if (livescore> = highscore) // periksa untuk melihat apakah skor lebih tinggi daripada skor tinggi {highscore = playcore; // single if statment untuk mengemas kini skor tinggi} untuk (int i = 0; i <= 16; i ++) // ini adalah untuk menarik segi empat tepat di sekitar permainan melalui {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("if loop"); paparan.display (); rectX1- = 2; // beralih lebih daripada 2 piksel segiempatY1- = 2; rectX2 + = 4; // beralih lebih daripada 2 piksel dari titik terakhir rectY2 + = 4; nada (SND, i * 200, 3); } paparan.display (); // Sapu Skrin selepas kemasyhuran atas rectX1 = 0; // tetapkan kedudukan permulaan garis rectY1 = 0; rectX2 = 0; segiempatY2 = 63; untuk (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, BLACK); rectX1 ++; rectX2 ++; paparan.display (); } display.clearDisplay (); skor permainan = 0; // tetapkan semula ular dan perincian pemain snakeSize = 1; snakeX = display.width () / 2; snakeY = display.height () / 2; tungguForPress (); // tunggu pemain memulakan permainan} // ------------------------- tunggu gelung tekan ---------- --------------- batal waitForPress () {bool waiting = 0; // gelung berakhir apabila ini adalah paparan benar.clearDisplay (); sementara (menunggu == 0) {drawALineForMe (PUTIH); // lukis draw garis putih rawakALineForMe (HITAM); // lukis garis hitam rawak supaya skrin tidak memenuhi paparan putih sepenuhnya. isiRect (19, 20, 90, 32, BLACK); // latar belakang kosong untuk paparan teks.setTextColor (PUTIH); display.setCursor (35, 25); display.setTextSize (2); // paparan fon yang lebih besar.println ("SNAKE"); // x y w h r col display.drawRoundRect (33, 22, 62, 20, 4, PUTIH); // perbatasan Snake display.drawRect (19, 20, 90, 32, WHITE); // kotak sempadan - 3 display.setCursor (28, 42); display.setTextSize (0); // fon kembali ke paparan normal.println ("tekan sebarang kekunci"); paparan.display (); menunggu = digitalRead (INTPIN); // periksa untuk melihat apakah penekanan tombol yang ditekan akan berubah menjadi 1 akhir sementara butang ditekan = 0; // butang reset tekan}} // -------------------- LUKA warna input garis rawak uint8_t -------------- ----- batal drawALineForMe (uint8_t clr) {uint8_t line1X, line1Y, line2X, line2Y = 0; // tetapkan koordinat rawak untuk garis kemudian lukiskannya // pemboleh ubah tidak kurang lagi garis1X = rawak (worldMinX + 1, worldMaxX-1); line1Y = rawak (worldMinY + 1, worldMaxY-1); line2X = rawak (worldMinX + 1, worldMaxX-1); line2Y = rawak (worldMinY + 1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- penembusan perlanggaran -------- -----------------------

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

// -------------------------------- PENYEDIAAN --------------- -------------------------------

kekosongan persediaan () {kelewatan (100); // beri peluang untuk "boot" // Serial.begin (9600); // hapus centang ini jika anda mahu melihat output bersiri display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // mulakan dengan paparan paparan bersih.setTextColor (PUTIH); // sediakan ukuran putaran warna teks dan lain-lain paparan.setRotation (0); display.setTextWrap (palsu); display.dim (0); // tetapkan pinMode brighness paparan (INTPIN, INPUT); // tetapkan port yang betul ke input pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // ini adalah perintah interupt ini "menghentikan" arduino untuk membaca input // command- function- pin-function to execute-condition on pin attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Persediaan Lulus"); tungguForPress (); // paparkan tempat layar permulaan ularSkran (); // letakkan sedikit makanan pertama} // --------------------- LOOP UTAMA ----------------- ---------------------- gelung kosong () {updateGame (); // fungsi inilah yang membawa kod utama}

Langkah 3:

Disyorkan: