Daftar Isi:

Game Ular OLED Arduino: 3 Langkah
Game Ular OLED Arduino: 3 Langkah

Video: Game Ular OLED Arduino: 3 Langkah

Video: Game Ular OLED Arduino: 3 Langkah
Video: Arduino Project - Star Wars Game #oled #arduinoproject #starwars 2024, November
Anonim
Permainan Ular OLED Arduino
Permainan Ular OLED Arduino

Hai dan selamat datang, untuk instruksi kami tentang cara membuat dan arduino OLED Game, proyek ini muncul ketika kami mencoba membuat game pertama kami dengan arduino, soooo, kami pikir di mana lebih baik untuk memulai daripada nokia classic Snake (baik di setidaknya klon ular:)).

Apa yang Anda Butuhkan

Perlengkapan

Arduino UNO atau kloning

Tampilan OLED

4 Dioda

500-1k resistor

4 tombol pengontrol

Buzzer Piezo pasif

opsional

Papan Roti Tanpa Solder

Harap dicatat tautan ini hanya sebagai contoh

Langkah 1: Sirkuit

Sirkuit
Sirkuit

Pada gambar diatas dapat dilihat rangkaian kita, kita menggunakan pin d3 pada arduino sebagai pin request interupsi sehingga arduino akan mengutamakan membaca input controller yaitu d4 d5 d6 d7. Dasar dari rangkaian ini adalah bahwa tombol arah ditekan yang menjadi tinggi 5v ini mengaktifkan pin permintaan interupsi (d3 kabel ungu) dan pin arah yang sesuai, fungsi interupsi memanggil fungsi arah pembaruan dan kode itu menggerakkan ular sesuai dengan itu. Pin 9 digunakan sebagai pin suara karena merupakan PWM (~ modulasi lebar pulsa) yang terhubung langsung ke piezo 5v pada pin + dan - kembali ke 0v/ground.

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

Pin arah:

d4 Naik ORANGE

d5 Bawah PINK

d6 Kiri BIRU

d7 Kanan COKLAT

d9 terdengar ABU-ABU

Setiap tombol memiliki input koneksi 5v dan output yang terhubung terlebih dahulu ke input digital masing-masing pada arduino, output yang sama dari setiap tombol ini kemudian dihubungkan ke diodanya sendiri, kami menggunakan dioda untuk menghentikan umpan balik tegangan ke tombol lain dan mengaktifkannya. Pada ujung katoda (-) dari semua 4 dioda, kami menggabungkannya bersama untuk membuat sambungan keluaran yang terhubung ke d3 dan kemudian melalui resistor ke 0v/pembumian untuk menarik pin arduino rendah agar tidak meninggalkan pin mengambang saat tidak sedang diaktifkan.

(FYI pin mengambang dapat menerima tegangan hantu dan menyebabkan perilaku yang tidak biasa)

2 pin analog digunakan untuk menggerakkan tampilan, ini adalah pin i2c perangkat keras arduino.

A5 terhubung ke SCL KUNING

A4 terhubung ke SDA GREEN

Output +5v dan 0v (pembumian) dari arduino digunakan sebagai sumber daya untuk seluruh rangkaian yang dapat ditenagai oleh usb atau pengisi daya telepon.

Langkah 2: Kode

//------------------------ ANJAWARE SNAKE Games Dengan bantuan dari masyarakat net --------------- -------

#termasuk

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // set tampilan (lebar, tinggi) Adafruit_SSD1306 display(128, 64); // tentukan pin input ini adalah pin pada arduino yang tidak pernah berubah jadi #define #define INTPIN 3 // hanya pin 2 dan 3 yang dapat menjadi pin interupt pada UNO #define UPPIN 4 // ini adalah pin yang terhubung tp sakelar yang relevan #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // tentukan arah #define DIRUP 1 // nilai-nilai ini adalah apa yang "ular" lihat untuk diputuskan- #define DIRDOWN 2 // arah yang akan dilalui ular # tentukan DIRLEFT 3 #definisikan DIRRIGHT 4

// setel variabel tombol

// akantil karena kita perlu memperbaruinya dengan interupsi sehingga dapat berupa nilai siklus apa pun

// tidak pernah lebih tinggi dari 4 jadi hanya perlu 8bit int untuk menghemat sumber daya volatile uint8_t buttonpressed=0; bool butup=0; bool butdown=0; // kita menggunakan ini untuk menyetel true ke "mendeteksi" arah mana yang ditekan bool butleft=0; bool butright=0;

// int ular

byte snakePosX[30]; // array untuk membuat badan ular byte snakePosY[30];

int ularX=30; // posisi kepala ular

int ularY=30; int ukuran ular=1; // jumlah ukuran ular terbatas pada ukuran array

// int dunia

uint8_t worldMinX=0; // ini mengatur batas area bermain

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

// kumpulkan scran(makanan) dan posisi scran

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

// nilai variabel

skor putar panjang=0; skor tinggi panjang=30; // atur skor tinggi menjadi 3 kumpulkan sebagai titik awal

//--------------------------- inilah yang dieksekusi interupt pada kenaikan tegangan ------------ -------------

void interupsi ditekan() { delay(150); // sedikit penundaan untuk menambahkan "bounce" perlindungan updatedirection(); } // ------------------ update nilai arah dari penekanan tombol ----------------- void updatedirection() { // Serial.println("memperbarui arah"); butup=digitalRead(UPPIN); // periksa input mana yang tinggi dan setel bool true butdown=digitalRead(DWNPIN); butleft=digitalRead(LFTPIN); butright=digitalRead(RHTPIN); // pernyataan if ini melihat input mana yang menjadi tinggi dan memasukkan nilai yang relevan dalam variabel "ditekan tombol" //, variabel ini menentukan arah pergerakan if(butup==true) { buttonpressed=DIRUP; // Serial.println("Atas ditekan"); // Serial.println(tekan tombol); butup=salah; nada (SND, 1500, 10); } if(butdown==true) { buttonpressed=DIRDOWN; // Serial.println("Tekan BAWAH"); // Serial.println(tekan tombol); butdown=salah; nada (SND, 1500, 10); }

jika (tetapi kiri == benar)

{ tombol ditekan=DIRLEFT; // Serial.println("TEKAN KIRI"); // Serial.println(tekan tombol); butleft=salah; nada (SND, 1500, 10); } if(butright==true) { buttonpressed=DIRRIGHT; // Serial.println("Tekan KANAN"); // Serial.println(tekan tombol); butright=salah; nada (SND, 1500, 10); } }

//--------------------------- menggambar rutinitas tampilan------------------ -----------------

void updateDisplay() // menggambar skor dan garis besar

{ // Serial.println("Perbarui Tampilan");

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

tampilan.setTextSize(0); display.setTextColor(PUTIH); // menggambar skor display.setCursor(2, 1); display.print("Nilai:"); display.print(String(playscore, DEC)); display.setCursor(66, 1); display.print("Tinggi:"); display.print(String(skor tinggi, DEC)); // menggambar area bermain // pos 1x, 1y, 2x, 2y, tampilan warna.drawLine(0, 0, 127, 0, WHITE); // tampilan batas paling atas.drawLine(63, 0, 63, 9, WHITE); // tampilan pemisah skor.drawLine(0, 9, 127, 9, WHITE); // di bawah tampilan batas teks.drawLine(0, 63, 127, 63, WHITE); // tampilan batas bawah.drawLine(0, 0, 0, 63, WHITE); // tampilan batas kiri.drawLine(127, 0, 127, 63, WHITE); //batas kanan

}

//----------------------------------- perbarui area bermain ---------- --------------------

void updateGame() // ini memperbarui tampilan area game

{ tampilan.clearDisplay();

display.drawPixel(scranPosX, scranPosY, WHITE);

scranAte = scranMakanan();

// periksa rutinitas ular

jika (outOfArea()||selfCollision())

{ tamat(); }

// tampilkan ular

for(int i=0;i0;i--) { snakePosX = snakePosX[i-1]; snakePosY = snakePosY[i-1]; } // tambahkan piksel ekstra ke ular if(scranAte) { snakeSize+=1; snakePosX[snakeSize-1]=snakeX; snakePosY[snakeSize-1]=snakeY; }

switch(ditekan tombol) // adalah snakeDirection

{ kasus DIRUP: snakeY-=1; merusak; kasus DIRDOWN: ularY+=1; merusak; kasus DIRLEFT: snakeX-=1; merusak; kasus DIRRIGHT: snakeX+=1; merusak; } snakePosX[0] = snakeX; ularPosY[0] = ularY; perbarui Tampilan(); tampilan.tampilan(); // --------------------- letakkan scran -------------------

batalkan tempatScran()

{ scranPosX=random(worldMinX+1, worldMaxX-1); scranPosY=random(worldMinY+1, worldMaxY-1); } //------------------------ SCRAN ATE POINT UP ---------------- bool scranFood() { if(snakeX==scranPosX&&snakeY==scranPosY) { playcore=playscore+10; nada (SND, 2000, 10); perbarui Tampilan(); tempatScran(); kembali 1; } lain { kembali 0; } } //--------------------- di luar area---------------------------------- bool outOfArea() { kembalikan snakeX =worldMaxX ||snakeY=worldMaxY; } //---------------------- tamat----------------------- --- void gameOver() { uint8_t rectX1, rectY1, rectX2, rectY2; rectX1=38; rectY1=28; rectX2=58; rectY2=12; tampilan.clearDisplay(); display.setCursor(40, 30); display.setTextSize(1); nada (SND, 2000, 50); display.print("PERTANDINGAN"); nada (SND, 1000, 50); display.print("LEBIH"); if(playscore>=highscore) //periksa untuk melihat apakah skor lebih tinggi dari skor tinggi { highscore=playscore; //pernyataan if tunggal untuk memperbarui skor tinggi } for(int i=0;i<=16;i++) // ini untuk menggambar persegi panjang di sekitar game melalui { display.drawRect(rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println("jika loop"); tampilan.tampilan(); rectX1-=2; // bergeser 2 piksel rectY1-=2; persegiX2+=4; // menggeser lebih dari 2 piksel dari titik terakhir rectY2+=4; nada(SND, i*200, 3); } tampilan.tampilan(); //Layar Lap setelah ketenaran melalui rectX1=0; // setel posisi awal garis rectY1=0; rectX2=0; rectY2=63; for (int i =0;i<=127;i++) { uint8_t cnt=0; display.drawLine(rectX1, rectY1, rectX2, rectY2, HITAM); rectX1++; rectX2++; tampilan.tampilan(); } tampilan.clearDisplay(); skor putar=0; // reset detail ular dan pemain snakeSize=1; snakeX=display.width()/2; ularY=tampilan.tinggi()/2; tungguUntukTekan(); // tunggu pemain memulai permainan } //--------------tunggu press loop ---------- --------------- void waitForPress() { bool waiting=0; // loop berakhir ketika ini benar display.clearDisplay(); while(menunggu==0) { drawALineForMe(PUTIH); // menggambar garis putih acak drawALineForMe(HITAM); // menggambar garis hitam acak sehingga layar tidak sepenuhnya memenuhi tampilan putih.fillRect(19, 20, 90, 32, BLACK); // latar belakang kosong untuk tampilan teks.setTextColor(WHITE); display.setCursor(35, 25); display.setTextSize(2); // tampilan font lebih besar.println("SNAKE"); // x y w h r col display.drawRoundRect(33, 22, 62, 20, 4, WHITE); // border Snake display.drawRect(19, 20, 90, 32, WHITE); // kotak perbatasan - 3 display.setCursor(28, 42); tampilan.setTextSize(0); // font kembali ke tampilan normal.println("tekan sembarang tombol"); tampilan.tampilan(); menunggu = digitalRead(INTPIN); // periksa untuk melihat apakah tombol menunggu yang ditekan akan berubah menjadi 1 berakhir saat tombol ditekan=0; // tekan tombol reset } } //--------------------GAMBAR warna input garis acak uint8_t-------------- ----- batal drawALineForMe(uint8_t clr) { uint8_t line1X, line1Y, line2X, line2Y=0; // atur koordinat acak untuk sebuah garis lalu gambar // variabel tidak kurang tidak lebih line1X = random(worldMinX+1, worldMaxX-1); line1Y = acak(worldMinY+1, worldMaxY-1); line2X = acak(worldMinX+1, worldMaxX-1); line2Y = acak(worldMinY+1, worldMaxY-1); display.drawLine(line1X, line1Y, line2X, line2Y, clr); } //------------------------------------- deteksi tabrakan -------- -----------------------

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

//-------------------------------- MEMPERSIAPKAN--------------- -------------------------------

batalkan pengaturan() { penundaan(100); // beri kesempatan untuk "boot" // Serial.begin(9600); // hapus centang ini jika Anda ingin melihat output serial display.begin(SSD1306_SWITCHCAPVCC, 0x3C); tampilan.clearDisplay(); // mulai dengan tampilan bersih display.setTextColor(WHITE);// mengatur ukuran rotasi warna teks dll display.setRotation(0); display.setTextWrap(salah); tampilan.dim(0); // mengatur kecerahan tampilan pinMode(INTPIN, INPUT); // setel port yang benar ke input pinMode(UPPIN, INPUT); pinMode(DWNPIN, INPUT); pinMode(LFTPIN, INPUT); pinMode(RHTPIN, INPUT); // ini adalah perintah interupt ini "menghentikan" arduino untuk membaca input // perintah- fungsi- pin-fungsi untuk mengeksekusi-kondisi pada pin attachInterrupt(digitalPinToInterrupt(INTPIN), interruptpressed, RISING); // Serial.println("Konfigurasi Lulus"); tungguUntukTekan(); // menampilkan layar pengaktifan ular placeScran(); // tempatkan sedikit makanan pertama } //---------------------MAIN LOOP----------------- ---------------------- void loop() { updateGame(); // fungsi ini yang membawa kode utama }

Langkah 3:

Direkomendasikan: