Пишем игру на плате Arduino Nano.

Страница на этапе разработки

В данном уроке мы напишем не большую игру используя плату Arduino Nano, OLED экран и пару кнопок.

**** схема подключения***

Данная игра будет состоять из нене 

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET LED_BUILTIN // Reset pin # (or -1 if sharing Arduino reset pin)

#define up 5
#define down 4
#define push 6


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int dx=0;
int dy=0;
int count =0;
int mon=0;
int tmon=0;
int k=0;
int mt1=0;
int mt2=0;
int ndx=0;
int tdy=0;
int kdx=100;
int kdy=32;
int tp[5]={0,0,0,0,0};//количество пулек на экране и их позиция
int pucka=7;// варианты пушек
int pu[5]={0,0,0,0,0};// наличие пульки на экране
int pux[5]={0,0,0,0,0};//координаты для движения пульки
int puy[5]={0,0,0,0,0};//координаты для движения пульки
int pulkaN1=0;//наличие пульки на єкране
int pulkaN2=0;//наличие пульки на єкране
int pulkaN3=0;//наличие пульки на єкране
int pulN[4]={0,0,0,0}; //какие пушки не выжели
int pul_e[4]={1,1,1,1};// если пулька уничтожена, мы больше не проверяем ее на попадание пулькой
int flag_t=0;// флаг времени обновления экрана
int flag_b=0;// флаг для считывания кнопок
int flag_p=0;// флаг проверки попадания
int fpul=0;// флаг нажатия пульки
int ib=0;//количество пулек на экране
int buttonC=0;

ISR(TIMER1_COMPA_vect){
 flag_t++;
 flag_b++;
 flag_p++;
}


void setup(){
 cli(); // отключить глобальные прерывания
 TCCR1A = 0; // установить регистры в 0
 TCCR1B = 0;
 OCR1A = 156; // установка регистра совпадения 0,01с
 TCCR1B |= (1 << WGM12); // включить CTC режим
 TCCR1B |= (1 << CS10); // Установить биты на коэффициент деления 1024
 TCCR1B |= (1 << CS12);
 TIMSK1 |= (1 << OCIE1A); // включить прерывание по совпадению таймера
 sei(); // включить глобальные прерывания  
 // initialize with the I2C addr 0x3C
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 display.clearDisplay();
 display.display();
 Serial.begin(115200);
 pinMode(up,INPUT_PULLUP);
 pinMode(down,INPUT_PULLUP);
 pinMode(push,INPUT_PULLUP);
}
void loop() {
 if (flag_t >= 5){//обновляем экран каждые 50мс
   display.clearDisplay();
   monctrAll();// отображение монстра в сборе
   korabl (kdx, kdy);//отображение корабля
   flyPulka();//отображение пульки
   display.display();
   flag_t = 0;
  }
 if (flag_b >= 10){//проверяем нажатие кнопок каждые 100мс
   buttonClick();
   flag_b=0;
  }
 if(flag_p>=1){//проверяем условия попадания в объект каждые 10mc
   proverkaUcloviy();
 }
}

void drawCircleZ(int x, int y){// закрашенный кружочек
 display.drawCircle(x,y,3, WHITE);
 for(int t=3; t!=0;t—){
   display.drawCircle(x,y,3-t, WHITE);
  }
}

void pulka(int plx, int ply){
         if((pulN[2]!=1)and(pulkaN2!=1))drawCircleZ((3+plx),ply); // вылетают пульки
         if((pulN[1]!=1)and(pulkaN1!=1))drawCircleZ((3+plx),ply+15);// вылетают пульки
         if((pulN[3]!=1)and(pulkaN3!=1))drawCircleZ((3+plx),ply-15);// вылетают пульки
}

void monstr (int mx, int my, int mn){
 display.drawCircle(mx,my,20, WHITE); //основное тело
 switch (mn){
 case 1:
       {
        display.drawCircle(mx,my+15,5, WHITE); // пушка 1
     // display.drawCircle(mx,my,5, WHITE); // пушка 2
     // display.drawCircle(mx,my-15,5, WHITE); // пушка 3
        pul_e[2]=0;
        pul_e[1]=0;
        break;
      }
 case 2:
       {
     // display.drawCircle(mx,my+15,5, WHITE); // пушка 1
        display.drawCircle(mx,my,5, WHITE); // пушка 2
     // display.drawCircle(mx,my-15,5, WHITE); // пушка 3
        pul_e[1]=0;
        pul_e[3]=0;
        break;
       }
 case 3:
       {
     // display.drawCircle(mx,my+15,5, WHITE); // пушка 1
     // display.drawCircle(mx,my,5, WHITE); // пушка 2
        display.drawCircle(mx,my-15,5, WHITE); // пушка 3
        pul_e[1]=0;
        pul_e[2]=0;
        break;
       }
 case 4:
        {
        display.drawCircle(mx,my+15,5, WHITE); // пушка 1
        display.drawCircle(mx,my,5, WHITE); // пушка 2
     // display.drawCircle(mx,my-15,5, WHITE); // пушка 3
        pul_e[3]=0;
        break;
        }
 case 5:
       {
      // display.drawCircle(mx,my+15,5, WHITE); // пушка 1
         display.drawCircle(mx,my,5, WHITE); // пушка 2
         display.drawCircle(mx,my-15,5, WHITE); // пушка 3
         pul_e[1]=0;
         break;
       }
 case 6:
        {
         display.drawCircle(mx,my+15,5, WHITE); // пушка 1
      // display.drawCircle(mx,my,5, WHITE); // пушка 2
         display.drawCircle(mx,my-15,5, WHITE); // пушка 3
         pul_e[2]=0;
         break;
       }
 case 7:
       {
        display.drawCircle(mx,my+15,5, WHITE); // пушка 1
        display.drawCircle(mx,my,5, WHITE); // пушка 2
        display.drawCircle(mx,my-15,5, WHITE); // пушка 3
        break;
       }
 case 8:// победа
       {
        display.clearDisplay();
        display.setCursor(10,20);
        display.setTextSize(1);
        display.setTextColor(WHITE);
        display.print («WIN»);
        display.display();
        while(1){;}
      }
 }
}

void korabl (int kx, int ky){ // рисунок корабля
 display.drawTriangle(kx, ky+4, kx, ky-4, kx-10, ky, WHITE);
}

void pula (int px, int py){//рисунок пульки
 display.fillRoundRect(0, 15, 60, 40, 8, WHITE);
}
void buttonClick(){// проверяем нажатие кнопок
 if(digitalRead(up)==1){kdy++;if(kdy>=60)kdy=60;}// нажата кнопка для движения
 if(digitalRead(down)==1){kdy—;if(kdy<=3)kdy=3;}// нажата кнопка для движения
 if((digitalRead(push)==0)and(ib!=5)and(buttonC==0)){ // нажата кнопка для выстрела
                                      buttonC=1;
                                      for(int i=0;i!=5;i++){
                                             if(pu[i]==0){
                                                 pu[i]=1;
                                                 pux[i]=kdx;
                                                 puy[i]=kdy;
                                                 break;
                                             }
                                      }    
                                             if(ib!=5){
                                                  ib++;
                                               
                                              }
               
                                    }
 if((digitalRead(push)==1)and(buttonC==1)){
   buttonC=0;
 }
}

void proverkaUcloviy(){// проверяем условия попадания в пульку, монстра или корабль
 for(int i=0;i!=5;i++){
     if (((pux[i]-10-tp[i])==(dx+3))and ((puy[i]+4>=dy)and(puy[i]-4<=dy))and (pu[i]==1)){pulkaN2=1;tp[i]=0;pu[i]=0;
                                                                                 if(ib!=0){ib—;}
                                                                                 Serial.println(«Ok1»);
                                                                                 }// проверяем есть попадание в сняряд 2
     if (((pux[i]-10-tp[i])==(3+dx))and ((puy[i]+4>=dy+15)and(puy[i]-4<=dy+15))and (pu[i]==1)){pulkaN1=1;tp[i]=0;pu[i]=0;
                                                                                 if(ib!=0){ib—;}
                                                                                 Serial.println(«Ok2»);
                                                                                 }// проверяем есть попадание в сняряд 1
     if (((pux[i]-10-tp[i])==(3+dx))and ((puy[i]+4>=dy-15)and(puy[i]-4<=dy-15))and (pu[i]==1)){pulkaN3=1;tp[i]=0;pu[i]=0;
                                                                                if(ib!=0){ib—;}
                                                                                Serial.println(«Ok3»);
                                                                                 }// проверяем есть попадание в сняряд 3

     if (((pux[i]-10-tp[i])==3)and ((puy[i]+4>=tdy)and(puy[i]-4<=tdy))and(pul_e[2]==1)){pulN[2]=1;tp[i]=0;pu[i]=0;
                                                                                 if(ib!=0){ib—;}
                                                                                 Serial.println(«Ok4»);
                                                                                 }// проверяем есть попадание в пушку 2
     if (((pux[i]-10-tp[i])==3)and ((puy[i]+4>=tdy+15)and(puy[i]-4<=tdy+15))and(pul_e[1]==1)){pulN[1]=1;tp[i]=0;pu[i]=0;
                                                                                  if(ib!=0){ib—;}
                                                                                  Serial.println(«Ok5»);
                                                                                  }// проверяем есть попадание в пушку 1
     if (((pux[i]-10-tp[i])==3)and ((puy[i]+4>=tdy-15)and(puy[i]-4<=tdy-15))and(pul_e[3]==1)){pulN[3]=1;tp[i]=0;pu[i]=0;
                                                                                  if(ib!=0){ib—;}
                                                                                  Serial.println(«Ok6»);
                                                                                  }// проверяем есть попадание в пушку 3
 }
}

void monctrAll(){// отрисовка монстра в сборе
 if (tmon==0) {//рандомное появление монстра
                  mon=random (-11,11);
                  mt1=mon;
                  mt2=mon;
                  tmon=1;
                  }
   if(mon==0){ // монстр стоит на месте
           tmon=0;
           }

   if (mon<0){//направление движения монстра
    if(k==0){
             tdy=32+mon-mt1;
             monstr(0,tdy,pucka);// +- 11
             mt1++;
             if (mt1==0){
                          k=1;
                          }
             }
    if(k==1){
             tdy=32+mt2;
             monstr(0,tdy,pucka);// +- 11
             mt2++;
             if (mt2==0){
                         k=0;
                         tmon=0;
                         }
             }
         }
   if (mon>0){//направление движения монстра
           if(k==0){
                    tdy=32-mon+mt1;
                    monstr(0,32-mon+mt1,pucka);// +- 11
                    mt1—;
                    if (mt1==0){k=1;}
                    }
           if(k==1){
                    tdy=32-mt2;
                    monstr(0,tdy,pucka);// +- 11
                    mt2—;
                    if (mt2==0){
                                k=0;
                                tmon=0;
                                }
           }
  }
 if(ndx==0){dy=tdy;ndx=1;}// стартовое положение пульки монстра
 dx++;// пулька монстра полетела
 if(dx==128){dx=0;ndx=0;pulkaN1=0;pulkaN2=0;pulkaN3=0;}// пулька монстра долетела до конца экрана
 pulka(dx,dy);// пулька монстра
 ///////формируем условие отображения пушек//////
 if(pulN[2]==0 and pulN[1]==0 and pulN[3]==0){pucka=7;}
 if(pulN[2]==1 and pulN[1]==0 and pulN[3]==0){pucka=6;}
 if(pulN[2]==0 and pulN[1]==1 and pulN[3]==0){pucka=5;}
 if(pulN[2]==0 and pulN[1]==0 and pulN[3]==1){pucka=4;}
 if(pulN[2]==1 and pulN[1]==1 and pulN[3]==0){pucka=3;}
 if(pulN[2]==0 and pulN[1]==1 and pulN[3]==1){pucka=2;}
 if(pulN[2]==1 and pulN[1]==0 and pulN[3]==1){pucka=1;}
 if(pulN[2]==1 and pulN[1]==1 and pulN[3]==1){pucka=8;}//победа
}

void flyPulka(){//полет пульки
   for(int i=0; i!=5;i++){
     if (pu[i]==1){
            display.fillRoundRect(pux[i]-10-tp[i], puy[i], 5, 2, 1, WHITE); // пулька наша
            tp[i]++;
            if(tp[i]==100){pu[i]=0;tp[i]=0;
                                      if(ib!=0){ib—;}
                                      }//пулька долетела к концу экрана.
      }
    }
  //  buttonC=0;
}