久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5238|回復: 3
打印 上一主題 下一主題
收起左側

arduino制作打磚塊的小游戲

[復制鏈接]
跳轉到指定樓層
樓主
ID:387981 發表于 2018-8-20 01:15 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/**********************************************************************************************************
實現功能:
OLED 屏幕顯示溫濕度值;

實現思路:
程序的整體思路為:上電后,OLED 屏幕上實時顯示溫濕度傳感器返回的溫度值和濕度值;

實驗接線:
OLED 屏幕接A4,A5口
搖桿模塊接到A0,A1
**********************************************************************************************************/
#include "U8glib.h"//引用U8G頭文件
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);//設置設備名稱:I2C-SSD1306-128*64(OLED)
/*=========================================================
                      自定義搖桿和相關變量
  =========================================================*/

#define Direction 14           //定義搖桿水平方向上的引腳;(控制下方的木板左右移動)
#define Direction_RMB 15       //定義搖桿垂直方向上的引腳;(向上是用來選擇關卡的【也可以說是快捷控制勝利的按鍵】,向下是復位按鍵)//由于該引腳控制很強大,故定義該引腳的名字時任性一下,RMB:俗稱人民幣玩家;
#define Data_of_left 300       //定義搖桿水平方向的數值,搖桿向左擺動時,其傳感器觸發的數值(該數值要看實際情況而定);
#define Data_of_right 650      //定義搖桿水平方向的數值,搖桿向右擺動時,其傳感器觸發的數值(該數值要看實際情況而定);
#define Data_of_up 200         //定義搖桿垂直方向的數值,搖桿向上擺動時,其傳感器觸發的數值(該數值要看實際情況而定);
#define Data_of_down 750       //定義搖桿垂直方向的數值,搖桿向下擺動時,其傳感器觸發的數值(該數值要看實際情況而定);
int muban = 1;                 //該變量用來判斷磚塊是否碰到木板;
int Atmp;                      //緩存
int Btmp;                      //緩存(Atmp 和 Btmp這兩個變量用于存儲當磚塊碰到墻時,磚塊所在的位置。記錄該值,主要用于程序后面磚塊碰到墻,墻消失,實際上記錄的是要消失的墻的位置;
byte DF = 1;                   //難度 1-3(即該游戲總共有三個關卡);
int WX;                        //木板寬度
byte WL;                       //木板長度
float BX, BY;                  //球的坐標
boolean MAP[16][8];            //磚塊位置  0為空氣  1為磚塊
float AX, AY;                  //小球速度
boolean WIN;                   //該布爾值主要判斷是否勝利;
int Data_of_sensor = 0;        //定義一個存儲搖桿水平方向數據的變量;
int Data_of_sensor_RMB = 0;    //定義一個存儲搖桿垂直方向數據的變量;
/*======================================================================================================================================================================================================*
|                     只循環一次                                                                                                                                                                       |
* ======================================================================================================================================================================================================*/
void setup() {
  //串口通訊波特率設置
  Serial.begin(9600);                 //設定波特率為9600;
  pinMode(Direction,INPUT);            //設置搖桿為輸入模式;
  pinMode(Direction_RMB,INPUT);        //設置搖桿為輸出模式;
  start();                             //游戲開始;
}
/*======================================================================================================================================================================================================*
|                     不停循環                                                                                                                                                                         |
* ======================================================================================================================================================================================================*/
void loop() {
  muban = 1;                                       
  Data_of_sensor = analogRead(Direction);               //讀取搖桿水平方向的數據;
  Data_of_sensor_RMB = analogRead(Direction_RMB);       //讀取搖桿垂直方向的數據;
  if( Data_of_sensor <= Data_of_left)  { WX -= 5; }     //如果搖桿向左擺動,OLED 屏幕里的木板向左移動(速度是一次向左移動5個像素);
  if( Data_of_sensor >= Data_of_right) { WX += 5; }     //如果搖桿向右擺動,OLED 屏幕里的木板向右移動(速度是一次向右移動5個像素);
  if( Data_of_sensor_RMB <= Data_of_up) { win(); }      //如果搖桿向上擺動時,自動選擇下一關;
  if( Data_of_sensor_RMB >= Data_of_down) { Reset(); }  //如果搖桿向下擺動時,程序復位(即游戲重新開始);
  else { delay(1); }                                    //這里的否則也就是不對搖桿進行操作;


  /*=========================================================
                  計算
    =========================================================*/
  if (WIN == true) win();
  if (WX < -(WL / 2)) WX = -(WL / 2);           //防止溢出
  if (WX > 128 - (WL / 2)) WX = 128 - (WL / 2); //防止溢出
  //小球位移
  BX += AX;
  BY += AY;
  /*=========================================================
                  磚塊邊緣反彈
    =========================================================*/
  if (BX > 125) {
    BX = 125;
    AX = -AX;
  }
  if (BX < 0) {
    BX = 0;
    AX = -AX;
  }
  if (BY >= 61) {            //如果磚塊沒有被木板接住,muban=0,說明失敗了;
    BY = 61;
    muban = 0;
    draw();
    AY = -AY;
  }
  if (BY < 0) {
    BY = 0;
    AY = -AY;
  }
  /*=========================================================
                  磚塊與木板
    =========================================================*/
  if (BX >= WX && BX <= WX + WL)   {
    if (BY >= 56 - 3 && BY <= 57 - 3) {
      //接觸到木板上下部分
      AX = -(((WX + (WL / 2)) - BX) / (WL / 2));
      AX *= 1.8;
      AY = -AY;
    }
  }

  /*=========================================================
                磚塊與墻
    =========================================================*/
  if (int(BX / 8) + 1 <= 16 && int(BY / 4) + 1 <= 8) {
    Atmp = BX / 8;
    Btmp = BY / 4;
    if (MAP[Atmp][Btmp] == 1) {
      //碰到磚頭
      MAP[Atmp][Btmp] = 0;
      //反彈代碼 分類討論 分為上下和左右
      if (BY - 2 <= Btmp * 4 || BY >= Btmp * 4 + 4) {
        //上和下邊緣
        AY = -AY;
      } else
      {
        AX = -AX;
      }
    }
  }
  /*=========================================================
                    顯示
    =========================================================*/
  u8g.firstPage();
  do {
    draw();
  } while ( u8g.nextPage() );
}

/*====================================================================================================================================*
|               初始化游戲                                                                                                           |
* ===================================================================================================================================*/
void start() {
  WL = 32;
  for (byte i = 1; i < DF; i++) {
    WL = WL / 2;                       //遞進計算木板長度(這里的for語句就是玩家完成一個難度時,跳入下一個難度的部分)
  }
  WX = 64 - (WL / 2);                  //計算木板初始所在的中間線橫坐標
  for (byte x = 0; x < 16; x++) {
    for (byte y = 0; y < 8; y++) {
      MAP[x][y] = 1;                   //該for語句主要和后面的void draw()函數呼應,告訴void draw()這個函數相應的位置是存在墻的;
    }                                  //也就是告訴后面的void draw()函數,各個位置可以添加墻。
  }
  BX = 64;                             
  BY = 52;                             //定義初始的小磚塊所在的位置;即在OLED 屏幕的(64,52);
  AX = 2;                              //初始小球加速度
  AY = -2;
  loop();                 //雖然程序會先執行void setup(),再執行void loop();但對于比較冗長的程序,為了保險起見,再次調用loop();
}


/*====================================================================================================================================*
|               渲染游戲畫面                                                                                                         |
* ===================================================================================================================================*/
void draw() {
  if(muban == 0)
  {
    fail();               //如果磚塊碰到木板,程序進入fail();(即如果磚塊下降過程時,最終木板沒有接住磚塊,則失敗;
  }

  if (muban == 1)
  {
    no_fail();           //如果磚塊最終被木板接住,磚塊繼續被木板反彈;
  }
}
/*------------------------------------------------------------------------------------------------------*
其顯示磚塊的實心矩形的樣式為:                                                                          |
(0, 0, 7, 3);       (8, 0, 7, 3);       (16, 0, 7, 3);     (24, 0, 7, 3);        ... (120, 0, 7, 3);    |
(0, 4, 7, 3);       (8, 4, 7, 3);       (16, 4, 7, 3);     (24, 4, 7, 3);        ... (120, 4, 7, 3);    |
(0, 8, 7, 3);       (8, 8, 7, 3);           ...                   ...                      ...          |
(0, 12, 7, 3);      (8, 12, 7, 3);          ...                   ...                      ...          |
   ...                                                                                     ...          |
   ...                                                                                     ...          |
(0, 28, 7, 3);     (8, 28, 7, 3);     (16, 28, 7, 3);              ...                (120, 28, 7, 3);  |
------------------------------------------------------------------------------------------------------*/
/*==========================================================================================================================================**
|                失敗                                                                                                                       |
* ==========================================================================================================================================*/
void fail()                           
{
for(int i=0;i<3;i++)                  //這里的for語句在OLED 屏幕上顯示的效果為:先顯示“Game Over”,延時500毫秒后,接著“Game Over”不顯示(即
{                                     //先前顯示的“Game Over”消失,延時500毫秒,將這一套動作看做為一個動作,則,這個動作執行3次;
  u8g.firstPage();                     //開始加載OLED 屏幕的界面
  do {
       no_fail();
       u8g.setFont(u8g_font_courB12);  //接下來要顯示的字體的字號為u8g_font_courB12號;
       u8g.setColorIndex(0);           //不顯示,透明
       u8g.drawBox(20, 12, 88, 40);    //畫一個空心矩形,該矩形從(20,12)這個點開始(也就是矩形左上角的坐標),矩形的寬為88個像素,高為40個像素。
                                       //由于該句之前顯示的樣式為透明&&不顯示,所以這里的矩形是透明的(在OLED 屏幕上這個矩形區域是黑的);
       u8g.setColorIndex(1);           //顯示,不透明;
       u8g.setPrintPos(20, 30);        //設置該句之后的print();要顯示內容的位置;
       u8g.print("Game Over");         //在(20,30)這個位置顯示 Game Over;
  } while ( u8g.nextPage() );          //關閉OLED 屏幕界面
  delay(500);

  u8g.firstPage();
  do {
       no_fail();
       u8g.setFont(u8g_font_courB12);  //接下來要顯示的字體的字號為u8g_font_courB12號;
       u8g.setColorIndex(0);           //不顯示,透明
       u8g.drawBox(20, 12, 88, 40);    //畫一個空心矩形,該矩形從(3,12)這個點開始(也就是矩形左上角的坐標),矩形的寬為88個像素,高為40個像素。
                                       //由于該句之前顯示的樣式為透明&&不顯示,所以這里的矩形是透明的(在OLED 屏幕上這個矩形區域是黑的);
       u8g.setColorIndex(1);           //顯示,不透明;
       u8g.setPrintPos(20, 30);        //設置該句之后的print();要顯示內容的位置;
       u8g.print("");                  //在(30,30)這個位置什么都不顯示;
  } while ( u8g.nextPage() );
  delay(500);

}
  start();     
}

void no_fail()
{
  WIN = true;
  u8g.drawBox(WX, 56, WL, 3);                           //顯示底下木板           
  u8g.drawBox(int(BX), int(BY), 3, 3);                  //顯示磚塊(磚塊的初始位置在OLED 屏幕的(64,52),且磚塊的寬為3,高為3;
  for (byte x = 0; x < 16; x++) {
    for (byte y = 0; y < 8; y++) {
      if (MAP[x][y] == 1) {
        WIN = false;
        //存在墻
        u8g.drawBox(x * 8, y * 4, 7, 3);                //按照下面說明的“磚塊的實心矩形的樣式”來一個一個顯示墻
      }
    }
  }   
}
/*==========================================================================================================================================**
|                通關                                                                                                                       |
* ==========================================================================================================================================*/
void win() {
  u8g.firstPage();
  do {
    draw();
    u8g.setFont(u8g_font_courB12);  //接下來要顯示的字體的字號為u8g_font_courB12號;
    u8g.setColorIndex(0);           //不顯示,透明
    u8g.drawBox(20, 12, 88, 40);    //畫一個空心矩形,該矩形從(3,12)這個點開始(也就是矩形左上角的坐標),矩形的寬為88個像素,高為40個像素。
                                    //由于該句之前顯示的樣式為透明&&不顯示,所以這里的矩形是透明的(在OLED 屏幕上這個矩形區域是黑的);
    u8g.setColorIndex(1);           //顯示,不透明;
    u8g.setPrintPos(30, 30);        //設置該句之后的print();要顯示內容的位置;
    u8g.print("You Win");           //在(30,30)這個位置顯示 You Win;
  } while ( u8g.nextPage() );
  delay (2000);
  if (DF < 3) {                     //該for語句就是當玩家通過一個簡單的模式時,
    DF++;                           //會自動進入下一個難度(即木板會變短),
  } else {                          //該游戲主要有三個難度等級,如果三個難度
    DF = 1;                         //等級都通過后,游戲會重新開始;
  }
  start();                          //完成一個難度等級后,游戲自動開始,進入下一個等級;
}

/*==========================================================================================================================================**
|                復位                                                                                                                       |
* ==========================================================================================================================================*/
void Reset() {                         //游戲復位鍵;
  u8g.firstPage();
  do {
       u8g.setFont(u8g_font_courB12);  //接下來要顯示的字體的字號為u8g_font_courB12號;
       u8g.setColorIndex(1);           //顯示,不透明;
       u8g.setPrintPos(40, 30);        //設置該句之后的print();要顯示內容的位置;
       u8g.print("Reset");             //在(40,30)這個位置顯示 You Win;
     } while ( u8g.nextPage() );
  delay (1500);
  start();                             //游戲重新開始;
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:387981 發表于 2018-8-20 01:17 | 只看該作者
代碼的注釋超級詳細,希望能幫到各位
回復

使用道具 舉報

板凳
ID:1 發表于 2018-8-20 01:36 | 只看該作者
好東東 希望有原理圖與介紹
回復

使用道具 舉報

地板
ID:656339 發表于 2019-12-4 22:14 | 只看該作者
你好,這個有完整接線圖碼
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 人人九九 | 中文字幕在线播放第一页 | 亚洲欧美激情四射 | 欧美视频三区 | 一区中文字幕 | 黄色在线观看网址 | 成人免费看黄网站在线观看 | 亚洲图片视频一区 | 超碰成人av| 久久9精品 | 久热电影 | 国产区在线观看 | 免费一级做a爰片久久毛片潮喷 | 99久久日韩精品免费热麻豆美女 | 中文字幕三区 | 亚洲精品99999| 亚洲欧洲精品成人久久奇米网 | 成人精品鲁一区一区二区 | 中文字幕在线一区 | 欧洲亚洲一区二区三区 | 亚洲一区二区三区免费在线观看 | 色网站入口 | 日韩精品一区在线观看 | 国产精品久久久久一区二区三区 | www.日本在线观看 | 2019天天操| 操到爽 | 亚洲激精日韩激精欧美精品 | 日韩欧美中文在线 | 99精品久久久久久久 | 久久一区二区三区四区 | 九九视频网 | 成人免费小视频 | 亚洲欧美激情网 | 日韩免费一区 | 免费黄色的视频 | 另类视频在线 | 九九色综合 | 成人免费在线视频 | 精品精品| 国产精品欧美日韩 |