Arduino小游戏

#include"U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);//设置设备名称:I2C-SSD1306-128*64(OLED)

#define UP 11//定义方向键上为Arduino引脚11号引脚
#define DOWN 10//定义方向键下为Arduino引脚10号引脚
#define LEFT 9//定义方向键上为Arduino引脚9号引脚
#define RIGHT 8//定义方向键上为Arduino引脚8号引脚
#define A 7//定义方向键上为Arduino引脚7号引脚
#define B 6//定义方向键上为Arduino引脚6号引脚
/***********************************************/
//初始化变量
//声明变量很多地方用了byte类型不用int类型,可以节约内存
byte wait=40;//延迟
int HP=20;//HP
byte PPX=4;//初始化玩家X位置
byte PPY=2;//初始化玩家Y位置
byte PX=0;//初始化玩家X轴坐标
byte PY=0;//初始化玩家Y轴坐标
int RT=1;//初始化运行周期
int S=0;//分数
byte OA;//障碍物
byte OB;//障碍物
byte OC;//障碍物
byte OD;//障碍物
int Atmp=0;//缓存A
int Btmp;//缓存B

//下面湿障碍物的数据,我们把障碍物数据保存在数组里,由运行内存显示,每隔20次运行周期会重新覆盖,保存内存不溢出
byte CA[50];//障碍物A的位置
byte CB[50];//障碍物B的位置
byte CC[50];//障碍物C的位置
byte CD[50];//障碍物D的位置

//下面湿障碍物A、B、C、D的坐标信息
byte CAX[50];//障碍物A_X轴
byte CBX[50];//障碍物B_X轴
byte CCX[50];//障碍物C_X轴
byte CDX[50];//障碍物D_X轴
byte CAY[50];//障碍物A_Y轴
byte CBY[50];//障碍物B_Y轴
byte CCY[50];//障碍物C_Y轴
byte CDY[50];//障碍物D_Y轴

//载入位图
const uint8_t title[] PROGMEM=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const uint8_t QR[] PROGMEM=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const uint8_t pause[] PROGMEM=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const uint8_t plane[] PROGMEM=
{0x8,0xc,0x8c,0xff,0xff,0x8c,0xc,0x8};

const uint8_t BOA[] PROGMEM=
{0xcc,0xcc,0x33,0x33,0xcc,0xcc,0x33,0x33};

const uint8_t BOB[] PROGMEM=
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

const uint8_t BOC[] PROGMEM=
{0x18,0x66,0x7e,0xbd,0xbd,0x7e,0x66,0x18};

const uint8_t BOD[] PROGMEM=
{0x0,0x7e,0x42,0x5a,0x5a,0x42,0x7e,0x0};

const uint8_t life[] PROGMEM=
{0x0,0x66,0xff,0xcf,0xdf,0x7e,0x3c,0x18};

/********************************************************/

void setup() {
  // put your setup code here, to run once:
  //初始化按钮
  pinMode(UP,INPUT);//定义方向键上的引脚状态
  pinMode(DOWN,INPUT);//定义方向键下的引脚状态
  pinMode(LEFT,INPUT);//定义方向键左的引脚状态
  pinMode(RIGHT,INPUT);//定义方向键右的引脚状态
  pinMode(A,INPUT);//定义A的引脚状态
  pinMode(B,INPUT);//定义B的引脚状态
  randomSeed(analogRead(A0));//伪随机数PIN
  u8g.firstPage();
  do
  {
    u8g.drawXBMP(0,0,128,64,title);
    }
    while(u8g.nextPage());
    delay(1024);
}
/**********************************************************/
void(* resetFunc)(void)=0;//制造从起命令的函数,下面会用到


void loop() {
  // put your main code here, to run repeatedly:
  //下面是GAME OVER或胜利后的处理
  if(HP<0||S>30000)
  {
    //循环检测按钮
    while(1)
    {
      //如果GAME OVER就等待按下A键复位游戏
      if(digitalRead(A)==HIGH)
      if(HP<0) resetFunc();//调用前面的软复位函数,达到软件重启Arduino的目的
      //如果检测到分数大于3万,就判断赢了游戏,放出二维码彩蛋
      if(S>=30000){
        while(1)
         {u8g.setColorIndex(1);
          u8g.firstPage();
          do
          {
            u8g.drawXBMP(40,8,56,49,QR);
            }
            while(u8g.nextPage());
         }
        }
      }
    }
    if(digitalRead(UP)==HIGH)
    {
      delay(10);
      if(digitalRead(UP)==HIGH)
      {
        if(PPY>1) PPY-=1;
        }
      }

      if(digitalRead(DOWN)==HIGH)
    {
      delay(10);
      if(digitalRead(DOWN)==HIGH)
      {
        if(PPY<4) PPY+=1;
        }
      }
      
    if(digitalRead(LEFT)==HIGH)
    {
      delay(10);
      if(digitalRead(LEFT)==HIGH)
      {
        if(PPX>1) PPX-=1;
        }
      }
          if(digitalRead(RIGHT)==HIGH)
    {
      delay(10);
      if(digitalRead(RIGHT)==HIGH)
      {
        if(PPX<15) PPX+=1;
        }
      }
        if(digitalRead(B)==HIGH)
    {
      delay(10);
      if(digitalRead(B)==HIGH)
      {
        delay(200);
        u8g.firstPage();
        do
        {
          draw();
          u8g.setColorIndex(0);
          u8g.drawBox(42,10,46,28);//先覆盖掉原屏幕,避免下面的图片变透明
          u8g.setColorIndex(1);
          u8g.drawXBMP(45,13,40,22,pause);
          }
          while(u8g.nextPage());
          while(1)
          {
            if(digitalRead(B)==HIGH)
            {
              delay(10);
              if(digitalRead(B)==HIGH)
              {
                delay(200);
                break;
                }
               }
            }
        }
      }
      /**************************************/
      //计算
      S+=1;
      PX=PPX*8;
      PY=PPY*8;
      OA=9;
      OB=9;
      OC=9;
      OD=9;
      if(RT<16)
      {
        Atmp=random(1,100);
        if(Atmp<=70)
        {
          OA=random(0,5);
          }
          //乌云

        Atmp=random(1,100);
        if(Atmp<=30)
        {
          OB=random(0,5);
          }

          //加油机
            Atmp=random(1,100);
        if(Atmp<=5)
        {
          OB=random(0,5);
          }
          
          //其他飞机
            Atmp=random(1,100);
        if(Atmp<=50)
        {
          OB=random(0,5);
          }   
        }

        if(HP>12)HP=12;
        //保存障碍物位置
        CAY[RT]=OA*8;
        CBY[RT]=OB*8;
        CCY[RT]=OC*8;
        CDY[RT]=OD*8;
        CA[RT]=OA;
        CB[RT]=OB;
        CC[RT]=OC;
        CD[RT]=OD;
        CAX[RT]=120;
        CBX[RT]=120;
        CCX[RT]=120;
        CDX[RT]=120;
        //判断伤害
        Btmp=15-PPX;
        if(RT>Btmp)
        {
          Atmp=RT-Btmp;
          if(PPY==CA[Atmp])
          {
            HP-=1;
            }
          

          if(PPY==CB[Atmp])
          {
            HP-=2;
            }

            if(PPY==CC[Atmp])
            {
              Atmp=random(1,3);
              HP+=Atmp;
              S+=30;
              }

              if(PPY==CD[Atmp])
              {
                Atmp=random(1,100);
                if(Atmp<50)
                {
                  HP+=1;
                  S+=15;
                  }
                  else
                  {
                    HP-=1;
                    }
                }
        }

        /*******************************华丽的分割线*******************/
        u8g.firstPage();
        do
        {
          draw();  
          }
          while(u8g.nextPage());
          //障碍物往下移
          Atmp=RT-16;
          if(Atmp<1)
          {
            Atmp=1;
            }
            for(Atmp;Atmp<=RT;Atmp++)
            {
              CAX[Atmp]-=8;//把障碍物的数组下移
              CBX[Atmp]-=8;
              CCX[Atmp]-=8;
              CDX[Atmp]-=8;
              }
              RT+=1;
              if(RT>=32)
              {
                RT=1;
                }
                delay(wait);//防止游戏运行到不能玩的级别
                   
}
void draw()
{
  //障碍物循环码初始化计算
  Atmp=RT-16;
  if(Atmp<1)
  {
    Atmp=1;
    }
    //障碍物显示
    for(Atmp;Atmp<=RT;Atmp++)
    {
      if(CCX[Atmp]>0)
      {
        u8g.drawBitmapP(CCX[Atmp],CCY[Atmp],1,8,BOC);
        
        }
      if(CDX[Atmp]>0)
      {
        u8g.drawBitmapP(CDX[Atmp],CDY[Atmp],1,8,BOD);
        }
         if(CAX[Atmp]>0)
      {
        u8g.drawBitmapP(CAX[Atmp],CAY[Atmp],1,8,BOA);
        }
          if(CBX[Atmp]>0)
      {
        u8g.drawBitmapP(CBX[Atmp],CBY[Atmp],1,8,BOB);
        }
      }

      //显示玩家
      u8g.drawBitmapP(PX,PY,1,8,plane);

      //生命及分数
      u8g.setFont(u8g_font_helvB08);

      if(HP>0)
      {
        u8g.setPrintPos(8,54);
        u8g.print("HP:");
        for(Atmp=1;Atmp<=HP;Atmp++)
        {
          Btmp=Atmp*8+20;
          u8g.drawBitmapP(Btmp,45,1,8,life);
          }
        }
      u8g.setPrintPos(8,62);
      u8g.print("score:");
      u8g.print(S);
      if(HP<0||S>=30000)
      {
        u8g.setColorIndex(255);
        u8g.drawBox(0,0,128,64);
        u8g.setFont(u8g_font_fub14);
        u8g.setColorIndex(0);
        u8g.setPrintPos(4,21);
        if(HP<0) u8g.print("GAME OVER");
        if(S>=30000) u8g.print("You Win");
        u8g.setFont(u8g_font_helvB08);
        u8g.setPrintPos(35,39);
        u8g.print("score:");
        if(HP<0) u8g.print(S);
        if(S>=30000) u8g.print(30000);
        u8g.setPrintPos(2,62);
        if(HP<0)
        u8g.print("please push A to RESET");
        if(S>=30000)
        u8g.print("A to QR code");
        
        }
  }

程序要使用到u8glib图形库,不了解的同学可以看下面那个地址

https://blog.csdn.net/u010104301/article/details/80015972

点击打开链接

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非愚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值