İçindekiler:

Arduino OLED Yılan Oyunu: 3 Adım
Arduino OLED Yılan Oyunu: 3 Adım

Video: Arduino OLED Yılan Oyunu: 3 Adım

Video: Arduino OLED Yılan Oyunu: 3 Adım
Video: Arduino ile Yılan Oyunu Yapımı - 3D Printed & Arduino - How To Make 2024, Temmuz
Anonim
Arduino OLED Yılan Oyunu
Arduino OLED Yılan Oyunu

Merhaba ve hoş geldiniz, arduino OLED Oyununun nasıl yapılacağına ve arduino OLED Oyununa ilişkin talimatlarımıza hoş geldiniz, bu proje bir arduino ile ilk oyunumuzu yapmaya çalışırken ortaya çıktı, soooo, nokia klasiği Snake'den daha iyi nereden başlayacağımızı düşündük (iyi en azından bir yılan klonu:)).

Neye ihtiyacınız olacak

Gereçler

Arduino UNO veya klon

OLED Ekran

4 Diyot

500-1k direnç

4 kontrol düğmesi

Pasif Piezo buzzer

isteğe bağlı

Lehimsiz Ekmek Tahtası

Lütfen bu bağlantıların yalnızca örnek olduğunu unutmayın

Adım 1: Devre

Devre
Devre

Yukarıdaki resimde gördüğünüz devremiz arduino üzerinde d3 pinini interrupt request pini olarak kullanıyoruz ki arduino d4 d5 d6 d7 olan controller girişlerini okumaya öncelik versin. Devrenin temeli, yüksek 5v'ye çıkan bir yön düğmesine basılması, bu, kesme talep pinini (d3 mor tel) ve karşılık gelen bir yön pinini etkinleştirir, kesme işlevi bir güncelleme yönü işlevini çağırır ve bu kod yılanı buna göre hareket ettirir. Pin 9, + pininde doğrudan 5v piezoya bağlanan ve - 0v/toprak'a geri dönen bir PWM (~ darbe genişlik modülasyonu) olduğu için ses pini olarak kullanılır.

(Arduino uno'daki FYI ve yalnızca d2 ve d3 klonları, kesme isteği pinleri olarak işlev görebilir).

Yön pimleri:

d4 Yukarı TURUNCU

d5 Aşağı PEMBE

d6 Sol MAVİ

d7 Sağ KAHVERENGİ

d9 ses GRİ

Her düğmenin 5v'lik bir bağlantı girişi ve önce arduinodaki ilgili dijital girişine bağlanan bir çıkışı vardır, her düğmenin bu aynı çıkışı daha sonra kendi diyotuna bağlanır, diyotları voltaj beslemesini durdurmak için kullanırız. diğer düğmeler ve bunları etkinleştirme. 4 diyotun hepsinin katot (-) ucunda, d3'e bağlanan bir çıkış bağlantısı oluşturmak ve ardından bir direnç aracılığıyla 0v/toprak'a arduino pinlerini düşük çekmek için onları birleştiririz, böylece olmadığında kayan pinler bırakmamak için Aktif.

(Bilginize göre kayan bir pim, fantom voltajı alabilir ve olağandışı davranışlara neden olabilir)

Ekranı sürmek için 2 analog pin kullanılır, bunlar arduino donanım i2c pinleridir.

A5, SCL SARI'ya bağlı

A4, SDA GREEN'e bağlı

Arduino'dan gelen +5v ve 0v (toprak) çıkışı, usb veya telefon şarj cihazı ile çalıştırılabilen tüm devre için güç kaynağı olarak kullanılır.

2. Adım: Kod

//------------------------ ANJAWARE SNAKE Oyunları Net insanların yardımıyla --------------- -------

#Dahil etmek

#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // ekran seti (genişlik, yükseklik) Adafruit_SSD1306 ekran(128, 64); // giriş pinlerini tanımlayın bunlar arduinodaki pinlerdir ve asla değişmezler yani #define #define INTPIN 3 // sadece pin 2 ve 3 UNO'da interupt olabilir #define UPPIN 4 // pinler bağlı pinlerdir tp ilgili switch #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // yönleri tanımlayın #define DIRUP 1 // bu değerler "yılan"ın karar vermek için baktığı şeydir- #define DIRDOWN 2 // yılanın gideceği yön # DIRLEFT 3'ü tanımla #define DIRRIGHT 4

// düğme değişkenlerini ayarla

// volitile çünkü kesinti ile güncellemeye ihtiyacımız var, böylece herhangi bir döngü değeri olabilir

// asla 4'ten yüksek değildir, bu yüzden kaynakları kurtarmak için sadece 8bit int gerekir volatile uint8_t buttonpressed=0; bool butup=0; bool butdown=0; // hangi yöne basıldığında "algılamak" için true değerini ayarlamak için bunu kullanırız bool butleft=0; bool butright=0;

// yılan girişleri

bayt yılanPosX[30]; // yılan baytının gövdesini oluşturacak dizi snakePosY[30];

int yılanX=30; // yılan başı pozisyonu

int yılanY=30; int yılanSize=1; // yılan boyutu sayısı dizinin boyutuyla sınırlıdır

// dünya bilgileri

uint8_t worldMinX=0; // bunlar oyun alanının sınırlarını belirler

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

// scran(yiyecek) ve scran konumunu topla

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

// değişkenleri puanlar

uzun oyun puanı=0; uzun yüksek puan=30; // başlangıç noktası olarak yüksek puanı 3 toplamaya ayarla

//--------------------------- Voltaj artışında kesinti bu şekilde gerçekleştirilir ------------ -------------

void interruptpressed() { gecikme(150); // eklenen "sıçrama" koruması için hafif gecikme updatedirection(); } // ------------------ düğmeye basarak yön değerini güncelleyin ----------------- void updatedirection() { // Serial.println("updatingdirection"); butup=digitalRead(UPPIN); // hangi girişin yüksek olduğunu kontrol edin ve ilgili bool değerini ayarlayın true butdown=digitalRead(DWNPIN); butleft=digitalRead(LFTPIN); butright=digitalRead(RHTPIN); // eğer ifadeler hangi girdinin yüksek olduğuna bakar ve ilgili değeri "buttonpressed" içine girer // değişken, bu değişken hareketin yönünü belirler if(butup==true) { buttonpressed=DIRUP; // Serial.println("UP tuşuna basıldı"); // Serial.println(düğmeye basılmış); butup=yanlış; ton(SND, 1500, 10); } if(butdown==true) { buttonpressed=DIRDOWN; // Serial.println("AŞAĞI basıldı"); // Serial.println(düğmeye basılmış); butdown=yanlış; ton(SND, 1500, 10); }

if(butleft==doğru)

{ düğmeye basılmış=DIRSOL; // Serial.println("SOL basılı"); // Serial.println(düğmeye basılmış); butleft=yanlış; ton(SND, 1500, 10); } if(butright==true) { buttonpressed=DIRRIGHT; // Serial.println("SAĞA basılır"); // Serial.println(düğmeye basılmış); butright=yanlış; ton(SND, 1500, 10); } }

//-------------------------- ekran rutinlerini çizin------------------ -----------------

void updateDisplay() // puanları ve ana hatları çiz

{ // Serial.println("Görüntüyü Güncelle");

display.fillRect(0, 0, display.width()-1, 8, SİYAH);

display.setTextSize(0); display.setTextColor(BEYAZ); // puanları çiz display.setCursor(2, 1); display.print("Skor:"); display.print(String(playscore, DEC)); display.setCursor(66, 1); display.print("Yüksek:"); display.print(String(yüksek puan, Aralık)); // oyun alanı çiz // konum 1x, 1y, 2x, 2y, renkli ekran.drawLine(0, 0, 127, 0, BEYAZ); // çok üst kenarlık display.drawLine(63, 0, 63, 9, BEYAZ); // puan ayırıcı display.drawLine(0, 9, 127, 9, BEYAZ); // metin çerçevesinin altında display.drawLine(0, 63, 127, 63, BEYAZ); // alt kenarlık display.drawLine(0, 0, 0, 63, BEYAZ); // sol kenarlık gösterimi.drawLine(127, 0, 127, 63, BEYAZ); //sağ kenarlık

}

//-------------------------------------- oyun alanını güncelle ---------- --------------------

void updateGame() // bu, oyun alanı görüntüsünü günceller

{ display.clearDisplay();

display.drawPixel(scranPosX, scranPosY, BEYAZ);

scranAte = scranFood();

// yılan rutinlerini kontrol et

if (outOfArea()||selfCollision())

{ oyun bitti(); }

// yılanı göster

for(int i=0;i0;i--) { yılanPosX = yılanPosX[i-1]; yılanPosY = yılanPosY[i-1]; } // yılana fazladan bir piksel ekle if(scranAte) { snakeSize+=1; yılanPosX[snakeSize-1]=snakeX; yılanPosY[snakeSize-1]=snakeY; }

switch(düğmeye basılmış) // snakeDirection idi

{ case DIRUP: yılanY-=1; kırmak; case DIRDOWN: snakeY+=1; kırmak; durum DIRLEFT: yılanX-=1; kırmak; durum DIRRIGHT: yılanX+=1; kırmak; } yılanPosX[0] = yılanX; yılanPosY[0] = yılanY; updateDisplay(); display.display(); // --------------------- taramayı yerleştir --------------------

geçersiz yerScran()

{ scranPosX=rastgele(worldMinX+1, worldMaxX-1); scranPosY=rastgele(worldMinY+1, worldMaxY-1); } //------------------------ SCRAN ATE POINT UP ---------------- bool scranFood() { if(snakeX==scranPosX&&snakeY==scranPosY) { playcore=playscore+10; ton(SND, 2000, 10); updateDisplay(); placeScran(); dönüş 1; } başka { 0 döndür; } } //--------------------- alan dışı---------------------- bool outOfArea() { return snakeX =worldMaxX ||snakeY=worldMaxY; } //---------------------- oyun bitti----------------------- --- geçersiz gameOver() { uint8_t rectX1, rectY1, rectX2, rectY2; rectX1=38; rectY1=28; rectX2=58; rectY2=12; display.clearDisplay(); display.setCursor(40, 30); display.setTextSize(1); ton(SND, 2000, 50); display.print("OYUN"); ton(SND, 1000, 50); display.print("AŞIRI"); if(playscore>=highscore) //puanın yüksek puandan yüksek olup olmadığını kontrol edin { highscore=playscore; //tek if ifadesi yüksek puanı güncellemek için } for(int i=0;i<=16;i++) // bu, { display.drawRect(rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println("if döngüsü"); display.display(); rectX1-=2; // 2 piksel kaydır rectY1-=2; rectX2+=4; // son noktadan 2 piksel öteye kaydır rectY2+=4; ton(SND, i*200, 3); } display.display(); // Şöhretten sonra ekranı sil rectX1=0; // satırın başlangıç konumunu ayarla rectY1=0; rectX2=0; rectY2=63; for (int i =0;i<=127;i++) { uint8_t cnt=0; display.drawLine(rectX1, rectY1, rectX2, rectY2, SİYAH); rectX1++; rectX2++; display.display(); } display.clearDisplay(); oyun puanı=0; // yılanı ve oyuncu ayrıntılarını sıfırla yılanSize=1; yılanX=display.width()/2; yılanY=display.height()/2; waitForPress(); // oyuncunun oyuna başlamasını bekleyin } //------------------------ basın döngüsünü bekleyin ---------- --------------- geçersiz waitForPress() { bool wait=0; // döngü bu doğru olduğunda sona erer display.clearDisplay(); while(bekleme==0) { drawALineForMe(BEYAZ); // rastgele beyaz bir çizgi çiz drawALineForMe(BLACK); // ekranın beyazı tamamen doldurmaması için rastgele bir siyah çizgi çizin display.fillRect(19, 20, 90, 32, BLACK); // metin için boş arka plan display.setTextColor(WHITE); display.setCursor(35, 25); display.setTextSize(2); // daha büyük yazı tipi display.println("SNAKE"); // x y w h r col display.drawRoundRect(33, 22, 62, 20, 4, BEYAZ); // border Snake display.drawRect(19, 20, 90, 32, BEYAZ); // kenarlık kutusu - 3 display.setCursor(28, 42); display.setTextSize(0); // yazı tipi normale dön display.println("herhangi bir tuşa basın"); display.display(); bekliyor = digitalRead(INTPIN); // tuşa basıldığında beklemenin 1 bitiş olarak değişip değişmeyeceğini kontrol edin = 0; // reset düğmesine basın } } //--------------------rastgele bir satır giriş rengi ÇİZİM uint8_t-------------- ----- geçersiz drawALineForMe(uint8_t clr) { uint8_t satır1X, satır1Y, satır2X, satır2Y=0; // bir çizgi için rasgele koordinatlar belirleyin ve onu çizin // değişken daha az değil artık line1X = rastgele(worldMinX+1, worldMaxX-1); line1Y = rastgele(worldMinY+1, worldMaxY-1); line2X = rastgele(worldMinX+1, worldMaxX-1); line2Y = rastgele(worldMinY+1, worldMaxY-1); display.drawLine(line1X, line1Y, line2X, line2Y, clr); } //------------------------------------------------ çarpışma algılama -------- --------------------------

for(byte i=4;i<snakeSize;i++) { if(snakeX==snakePosX&&snakeY==snakePosy) { return 1; ton(SND, 2000, 20); ton(SND, 1000, 20); } 0 döndür; }

//-------------------------------- KURMAK--------------- ----------------------------------

geçersiz kurulum() { gecikme(100); // sadece "önyükleme" için bir şans verin // Serial.begin(9600); // seri çıkışları görmek istiyorsanız bu işareti kaldırın display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); // temiz bir ekranla başla display.setTextColor(WHITE);// metin renk döndürme boyutunu ayarla display.setRotation(0); display.setTextWrap(yanlış); display.dim(0); // ekran parlaklığını ayarla pinMode(INTPIN, INPUT); // pinMode(UPPIN, INPUT) girişlerine doğru portları ayarlayın; pinMode(DWNPIN, INPUT); pinMode(LFTPIN, INPUT); pinMode(RHTPIN, GİRİŞ); // bu kesme komutudur bu, arduino'nun girişleri okumasını "durdurur" //komut-işlev- pin-işlevi-koşul pin üzerinde ekInterrupt(digitalPinToInterrupt(INTPIN), interruptpressed, RISING); // Serial.println("Kurulum Başarılı"); waitForPress(); // yılan başlangıç ekranını göster placeScran(); // ilk parça yiyeceği yerleştir } //---------------------ANA DÖNGÜ-------------------- ---------------------- geçersiz döngü() { updateGame(); // bu fonksiyon ana kodu taşıyan şeydir }

Aşama 3:

Önerilen: