Arduino LCD Ekran ile Oyun Yapımı

Arduino ve LCD Ekran ile oyun yaptığımız bu yazımızda, bir çok Arduino fonksiyonunu ve kodlama yapısını pekiştirebilirsiniz. Bir zamanların en popüler oyunlarında biri olan Flappy Bird‘ü Arduino geliştirme kartına taşıyoruz!

Flappy Bird, Dong Nguyen tarafından geliştirilen bir yandan kaydırma tabanlı bir oyundur. Oyun 2D Grafik üzerine kurulu olsa da hem Android hem de iOS platformlarında oldukça popüler hale geldi. Oyunun amacı basittir, “Faby” adı verilen kuşu yeşil boruların arasına çarpmadan uçurmaya çalışmaktır.

Doğası gereği bağımlılık yapan oyunun geliştiricisi oyunu her iki kanaldan da indirilmesini ve erişilmesini(Google Play Store ve App Store) durdurdu.

Birçok replika oyun ve klonlanmış versiyona giden yolun popülaritesi arttı. Bu projede oyunun konseptini alıp Arduino kullanarak kendin yap tipi bir Flappy Bird Oyunu geliştireceğiz.

Ayrıca tek renk bir LCD ekranla bu projeyi gerçekleştirdikten sonra OLED bir ekran ile bu oyunu renkli ve ileri bir seviyeye getirebilirsiniz.

Arduino LCD Ekran ile Oyun Yapımı LCD Ekran ile Oyun,Arduino LCD Ekran ile Oyun Yapımı

Proje kodumuzda kuşu yani karekterimizi “0” karakteri ile engelleri ise “#” karakteri ile temsil ediyoruz. Alt ve üst sıra olmak kaydıyla dizgi ile bu dizileri sürekli olarak oyunun ilerlemesi ile çoğaltıyoruz. Oyunun amacı sadece düğmeye basarak kuşu, engellerden başarıyla geçirmektir.

Daha fazla ilerlemeden önce, Arduino’daki “Kesmeler/Interrupts” kavramı bu projeyi uygulamak için çok önemlidir. Bu yüzden, Arduino’da Kesmeleri nasıl kullanılacağını kolayca anlayabileceğiniz bu basit Arduino Kesmeler Yazısını gözden geçirmenizi öneririz.

Gerekli Malzemeler

  • Arduino UNO
  • 16×2 LCD Ekran
  • Buton
  • Jumper/Kablo
  • Breadboard/ Devre kartı
  • 5V Güç Kaynağı

Devre Şeması

Arduino LCD Ekran ile Oyun Yapımı LCD Ekran ile Oyun,Arduino LCD Ekran ile Oyun Yapımı

Devre şemasından ve gerekli bileşenlerin listesinden, projenin uygulanmasının ne kadar basit olduğu hakkında bir fikir edinebilirsiniz. Tek ihtiyacınız olan 16×2 LCD ekranı Arduino UNO ile arayüzlemek ve ayrıca bir Kesme Butonu eklemek.

16×2 LCD Ekrana gelince, RS ve E pinlerini Arduino UNO’nun Dijital I/O Pinleri 8 ve 7’ye bağlayın. Veri Pinleri D4 – D7 Arduino’nun 6, 5, 4 ve 3 Pinlerine bağlanır.

16×2 LCD Ekranın kontrastını ayarlamak için 10KΩ POT bağlanır, eğer pot kullanmak istemiyorsanız doğrudan kod kısmında kontrast ayarını yapabilirsiniz. Diğer tüm bağlantılar devre şemasında açıkça belirtilmiştir.

Pin 2 ile GND arasına bir Buton bağlanır.

Proje Kodu

#include<LiquidCrystal.h>
LiquidCrystal lcd (8,7,6,5,4,3); //RS, E, D4, D5, D6, D7
int ledPin = 13;
int buttonPin = 2;

int ledToggle;
int previousState = HIGH;
unsigned int previousPress;
volatile int buttonFlag;
int buttonDebounce = 20;
int i=0;
int pos=0;
int Speed=100;
String typea    = "                      ##        ######     ##       ####     ####       ########       ##                  ";  
String typeaa   = "                 ##       ####          ##     ####       ##         ##           ##                       ";
                                    
                
int  typeA[]    = {22,23,32,33,34,35,36,37,43,44,52,53,54,55,61,62,63,64,72,73,74,75,76,77,78,79,87,88};//28
int typeAA[]    = {17,18,26,27,28,29,40,41,47,48,49,50,58,59,69,70,82,83};//18

void setup()
{
  lcd.begin(16,2);
  lcd.begin(16,2);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), button_ISR, CHANGE);
  while(ledToggle==0)
  {
    lcd.clear();
    delay(500);
    lcd.print("   OYUNU BASLAT   ");
    delay(500);
  }
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print('O');
  //lcd.print(bala.substring(1,3));
  
}


void loop() 
{
  
while(1)
 {
   for(i=0;i<89;i++)//
   {
    if(pos==0)
    {
      lcd.setCursor(1,0);
      lcd.print(typea.substring(i+1,16+i));
    }
    else
    {
      lcd.setCursor(0,0);
      lcd.print(typea.substring(i,16+i));
    }

    
    if(pos==1)
    {
      lcd.setCursor(1,1);
      lcd.print(typeaa.substring(i+1,16+i));
    }
    else
    {
      lcd.setCursor(0,1);
      lcd.print(typeaa.substring(i,16+i));
    }
    
   
    
    for(int j=0;j<28;j++)
    {
      if(typeA[j]==i)
      {
        if(pos==0)
        {
          gameover();
        }
      }
    }
    for(int j=0;j<18;j++)
    {
      if(typeAA[j]==i)
      {
        if(pos==1)
        {
          gameover();
        }
      }
    }
    delay(Speed);
  }
   winner();
 }
}

void gameover (void)
{
  detachInterrupt(digitalPinToInterrupt(2));
  while(1)
  {
    lcd.clear();
    delay(500);
    lcd.print("    OYUN BITTI   ");
    delay(500);
  }
}
void winner (void)
{
  detachInterrupt(digitalPinToInterrupt(2));
  while(1)
  {
    lcd.clear();
    delay(500);
    lcd.print(" KA ZAN DIN!");
    lcd.setCursor(0,1);
    lcd.print(" TEBRIKLER ");
    delay(500);
  }
}

void button_ISR()
{
   buttonFlag = 1;
   if((millis() - previousPress) > buttonDebounce && buttonFlag)
  {
    previousPress = millis();
    if(digitalRead(buttonPin) == LOW && previousState == HIGH)
    {
      ledToggle =! ledToggle;
      digitalWrite(ledPin, ledToggle);
      previousState = LOW;
      if(ledToggle)
      {
       lcd.setCursor(0,0);
       lcd.print('O');
       lcd.setCursor(0,1);
       lcd.print(' ');
       pos=0;
      }
      else
      {
       lcd.setCursor(0,1);
       lcd.print('O');
       lcd.setCursor(0,0);
       lcd.print(' ');
       pos=1;
      }

    }
    
    else if(digitalRead(buttonPin) == HIGH && previousState == LOW)
    {
      previousState = HIGH;
    }
    buttonFlag = 0;
  }
}

Tüm bağlantıları devre şemasına göre yaptıktan sonra kodu Arduino’ya yükleyin. Güç kaynağını açtığınız anda, oyun LCD’de “OYUNA BASLA” görüntüleyerek başlar.

Oyun başladıktan sonra, Flappy Bird, basma düğmesi yardımıyla kesme pimi kullanılarak konumu değiştirilebilir. Kuş üstteyse, düğmeye basarak onu aşağı veya tam tersine hareket ettirebilirsiniz.

Kuş engellerden herhangi birine dokunursa kaybedersiniz oyun biter. Bu oyunun basit bir versiyonu olduğu için sadece birkaç engel var ve tüm bu engelleri başarıyla aşarsanız oyunu kazanacaksınız.

Bonus: I2C Ekran İçin Arduino Kodu

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int ledPin = 13;
int buttonPin = 2;

int ledToggle;
int previousState = HIGH;
unsigned int previousPress;
volatile int buttonFlag;
int buttonDebounce = 20;
int i = 0;
int pos = 0;
int Speed = 100;
String typea    = "                      ##        ######     ##       ####     ####       ########       ##                  ";
String typeaa   = "                 ##       ####          ##     ####       ##         ##           ##                       ";


int  typeA[]    = {22, 23, 32, 33, 34, 35, 36, 37, 43, 44, 52, 53, 54, 55, 61, 62, 63, 64, 72, 73, 74, 75, 76, 77, 78, 79, 87, 88}; //28
int typeAA[]    = {17, 18, 26, 27, 28, 29, 40, 41, 47, 48, 49, 50, 58, 59, 69, 70, 82, 83}; //18

void setup()
{
  lcd.begin(16, 2);
  lcd.backlight();
  lcd.clear();
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), button_ISR, CHANGE);
  while (ledToggle == 0)
  {
    lcd.clear();
    delay(500);
    lcd.print("   OYUNU BASLAT   ");
    delay(500);
  }
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print('O');
  //lcd.print(bala.substring(1,3));

}


void loop()
{

  while (1)
  {
    for (i = 0; i < 89; i++) //
    {
      if (pos == 0)
      {
        lcd.setCursor(1, 0);
        lcd.print(typea.substring(i + 1, 16 + i));
      }
      else
      {
        lcd.setCursor(0, 0);
        lcd.print(typea.substring(i, 16 + i));
      }


      if (pos == 1)
      {
        lcd.setCursor(1, 1);
        lcd.print(typeaa.substring(i + 1, 16 + i));
      }
      else
      {
        lcd.setCursor(0, 1);
        lcd.print(typeaa.substring(i, 16 + i));
      }



      for (int j = 0; j < 28; j++)
      {
        if (typeA[j] == i)
        {
          if (pos == 0)
          {
            gameover();
          }
        }
      }
      for (int j = 0; j < 18; j++)
      {
        if (typeAA[j] == i)
        {
          if (pos == 1)
          {
            gameover();
          }
        }
      }
      delay(Speed);
    }
    winner();
  }
}

void gameover (void)
{
  detachInterrupt(digitalPinToInterrupt(2));
  while (1)
  {
    lcd.clear();
    delay(500);
    lcd.print("    OYUN BITTI   ");
    delay(500);
  }
}
void winner (void)
{
  detachInterrupt(digitalPinToInterrupt(2));
  while (1)
  {
    lcd.clear();
    delay(500);
    lcd.print(" KA ZAN DIN!");
    lcd.setCursor(0, 1);
    lcd.print(" TEBRIKLER ");
    delay(500);
  }
}

void button_ISR()
{
  buttonFlag = 1;
  if ((millis() - previousPress) > buttonDebounce && buttonFlag)
  {
    previousPress = millis();
    if (digitalRead(buttonPin) == LOW && previousState == HIGH)
    {
      ledToggle = ! ledToggle;
      digitalWrite(ledPin, ledToggle);
      previousState = LOW;
      if (ledToggle)
      {
        lcd.setCursor(0, 0);
        lcd.print('O');
        lcd.setCursor(0, 1);
        lcd.print(' ');
        pos = 0;
      }
      else
      {
        lcd.setCursor(0, 1);
        lcd.print('O');
        lcd.setCursor(0, 0);
        lcd.print(' ');
        pos = 1;
      }

    }

    else if (digitalRead(buttonPin) == HIGH && previousState == LOW)
    {
      previousState = HIGH;
    }
    buttonFlag = 0;
  }
}

Yorum yapma özelliği, forum tarafından gelen istek sebebiyle kapatılmıştır. Lütfen tartışmalar ve sorularınız için topluluk forumumuza katılın.