Cyclone Game with WS2812B Led Ring使用第三方程式庫

回覆文章
cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

Cyclone Game with WS2812B Led Ring使用第三方程式庫

文章 cajhbb »

Cyclone Game with WS2812B Led Ring使用第三方程式庫

代碼: 選擇全部

#include "FastLED.h"
#define NUM_LEDS 60
#define DATA_PIN A0
#define SCORE_PIN 6
#define SCORE_LEDS 6
#define BRIGHTNESS 55
CRGB leds[NUM_LEDS];
CRGB sleds[NUM_LEDS];

bool reachedEnd = false;
byte gameState = 0;
//byte ledSpeed = 0;
int period = 1000;
unsigned long time_now = 0;
byte Position = 0;
byte level = 0;

const byte ledSpeed[6] = {50, 40, 30, 20, 14, 7};

//Debounce
bool findRandom = false;
byte spot = 0;

void setup() {
  // put your setup code here, to run once:
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.addLeds<WS2812B, SCORE_PIN, GRB>(sleds, SCORE_LEDS);
  pinMode(A3, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Reset");
}

void loop() {
  // put your main code here, to run repeatedly:
  FastLED.setBrightness(BRIGHTNESS );
  if (gameState == 0) {
    fill_rainbow(leds, NUM_LEDS, 0, 20); //2 = longer gradient strip
    fill_rainbow(sleds, SCORE_LEDS, 0, 40); //2 = longer gradient strip

    if (digitalRead(A3) == LOW) {
      Position = 0;
      findRandom = true;
      delay(500);
      for (byte i = 0; i < NUM_LEDS; i++) {
        leds[i].setRGB(0, 0, 0);
        delay(40);
        FastLED.show();
       int thisPitch = map (i, 60, 0, 100, 1500);
       tone(9, thisPitch,120);
      }
      for (byte i = 0; i < SCORE_LEDS; i++) {
        sleds[i].setRGB(0, 0, 0);
        delay(100);
        FastLED.show();
      }
      gameState = 1;
    }
    FastLED.show();
  }
  if (gameState == 1) {
    period = ledSpeed[0];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot - 1].setRGB(255, 140, 0);
      leds[spot].setRGB(0, 255, 0);
      leds[spot + 1].setRGB(255, 110, 0);
      sleds[0].setRGB(0, 255, 0);
      PlayGame(spot - 1, spot + 1);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      findRandom = false;
      if (Position > spot - 1 && Position < spot + 3) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }
  if (gameState == 2) {
//    period = 320;
    period = ledSpeed[1];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot - 1].setRGB(255, 190, 0);
      leds[spot].setRGB(0, 255, 0);
      leds[spot + 1].setRGB(255, 190, 0);
      sleds[1].setRGB(255, 255, 0);
      PlayGame(spot - 1, spot + 1);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      if (spot - 1 && Position < spot + 3) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }
  if (gameState == 3) {
    period = ledSpeed[2];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot].setRGB(0, 255, 0);
      sleds[2].setRGB(255, 50, 0);
      PlayGame(spot, spot);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      if (Position == spot+1) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }
  if (gameState == 4) {
    period = ledSpeed[3];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot].setRGB(0, 255, 0);
      sleds[3].setRGB(255, 0, 0);
      PlayGame(spot, spot);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      if (Position == spot+1) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }

  if (gameState == 5) {
    period = ledSpeed[4];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot].setRGB(0, 255, 0);
      sleds[4].setRGB(0, 50, 255);
      PlayGame(spot , spot);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      if (Position == spot+1) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }

  if (gameState == 6) {
    period = ledSpeed[5];
    if (millis() > time_now + period) {
      time_now = millis();
      if (findRandom) {
        spot = random(56) + 3;
        findRandom = false;
      }
      leds[spot].setRGB(0, 255, 0);
      sleds[5].setRGB(0, 150, 255);
      PlayGame(spot , spot);
    }
    if (digitalRead(A3) == LOW) {
      delay(300);
      if (Position == spot+1) {
        level = gameState;
        gameState = 98;
      } else {
        gameState = 99;
      }
    }
  }
  
  if (gameState == 98) {
    winner();
  }
  if (gameState == 99) {
    loser();
  }
}
void PlayGame(byte bound1, byte bound2) {
  leds[Position].setRGB(255, 0, 0);
  if (Position < bound1 + 1 || Position > bound2 + 1) {
    leds[Position - 1].setRGB(0, 0, 0);
  }
  FastLED.show();
  Position++;
  if (Position >= NUM_LEDS) {
    leds[Position - 1].setRGB(0, 0, 0);
    Position = 0;
  }
}

void winner() {
  for (byte i = 0; i < 3; i++) {
    for (byte j = 0; j < NUM_LEDS; j++) {
      leds[j].setRGB(0, 255, 0);
        tone(9, 1000, 250);
    }
    FastLED.show();
    delay(500);
    clearLEDS();
    FastLED.show();
    delay(500);
  
  }
  findRandom = true;
  Position = 0;

  gameState = level + 1;
  if (gameState > 6) {
    gameState = 0;
  }
}
void loser() {
  for (byte i = 0; i < 3; i++) {
    for (byte j = 0; j < NUM_LEDS; j++) {
      leds[j].setRGB(255, 0, 0);
      tone(9, 200, 250);
    }
    FastLED.show();
    delay(500);
    clearLEDS();
    FastLED.show();
    delay(500);
  }
  gameState = 0;
}
void clearLEDS() {
  for (byte i = 0; i < NUM_LEDS; i++) {
    leds[i].setRGB(0, 0, 0);
  }
}
void winAll(){
  
}






cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

解釋FastLED.h第三方程式庫

文章 cajhbb »

schematic_supU5hezie.jpg
schematic_supU5hezie.jpg (137.9 KiB) 已瀏覽 834 次
CRGB leds[NUM_LEDS];
使用RGB數值表達顏色
CRGB (rVal,gVal,bVal); //紅,綠,藍
fillRainbow
fill_rainbow(leds, 30, beginHue, deltaHue)
以上語句將leds光帶的從頭數30個燈珠設置為漸變彩虹色。beginHue參數為起始色調數值。deltaHue為相鄰LED燈珠色調差。
fill_rainbow(leds+5, 30, 0, 8)
以上語句將leds光帶的從頭數30個燈珠設置為漸變彩虹色。起始色調數值為0。相鄰LED燈珠色調差為8。
FastLED.setBrightness
FastLED.setBrightness
FastLED.setBrightness函數設置LED光帶亮度。LED亮度值可選數值範圍為0 – 255。
FastLED.setBrightness(128);

cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

Adafruit_NeoPixel.h函式庫

文章 cajhbb »

Adafruit_NeoPixel.h函式庫
strip.setBrightness(255); 亮度0~255範圍
https://sites.google.com/tmail.ilc.edu. ... 8%E6%9D%BF 宜蘭
cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

第8版.8th.txt

文章 cajhbb »

代碼: 選擇全部

#include <Adafruit_NeoPixel.h>
#define DATA_PIN  A0 //環燈號訊號腳位
#define NUM_LEDS 28 //環燈燈珠顆數
#define SCORE_PIN 6 //計分燈訊號腳位
#define SCORE_LEDS 6 //計分燈燈數
#define BRIGHTNESS 10 //亮度在15~50即可,最大亮度為255

byte gameState = 0; //遊戲狀態
int period = 1000;//週期
unsigned long Start_Time = 0;
byte led_run_at = 0; //燈號落點
byte level = 0;
byte count_led = 0;
byte side1=0,side2=0;
const byte ledSpeed[6] = {60, 50, 40, 30, 20, 14}; //共有6個等級的遊戲
//消除彈跳Debounce
boolean Push_Play = false;
byte Set_Led = 0;
//-------------以上為所有宣告-----------------
//--------------------------------------------

//條燈初始化定義:strip函數-->宣告strip_long環燈 -->strip_score分數燈
Adafruit_NeoPixel strip_long(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_score(SCORE_LEDS, SCORE_PIN, NEO_GRB + NEO_KHZ800);

//------------ void setup()-----------------
void setup() {
    strip_long.begin(); //初始化(環燈)
    strip_score.begin(); //初始化(得分燈)
      strip_long.setBrightness(BRIGHTNESS); //亮度
      strip_score.setBrightness(BRIGHTNESS); //亮度
    strip_long.show();  //輸出
    strip_score.show();  //輸出
  pinMode(A3, INPUT_PULLUP);//按鈕輸入腳A3,上拉電阻
  Serial.begin(9600);
  Serial.println("Reset");
}
//------------ void loop() -----------------
void loop(){
//gameState = 0;
//gameState = 1~6是6個關卡  
//gameState = 100 winner();勝利 gameState = 99 loser();失敗 
//------------------以下為 gameState = 0-------------- 
   if (gameState == 0){
     NUM_Random();//亂數顯示燈號
     SCORE_Random();//亂數顯示燈號
    //按鈕被按下去,往下做 
    if (digitalRead(A3) == LOW) { //被按下去
      led_run_at = 0;//循環紅點位置
      Push_Play = true;//被按下去LOW,變數為true
      delay(80);
           //-----逐一點亮(環燈=黃燈)+蜂鳴器(音效)-----
                for (byte i = 0; i < NUM_LEDS; i++) { //燈珠顆數:從0累加直到小於NUM_LEDS
                strip_long.setPixelColor(i, 255, 255, 0);//環燈逐顆,設為黃色
                delay(100);
                strip_long.show(); 
                //map(輸入數值來源,來源最小值,來源最大值,轉換後的最小值,轉換後的最大值)
               int thisPitch = map (i, 60, 0, 100, 1500);
                //範例:tone(2,1000,500);數位接腳2輸出1000Hz方波,時間0.5秒。
               tone(9, thisPitch,100);//蜂鳴器接D9
              }
           //-----逐一點亮(計分燈=紅燈)-----
                for (byte i = 0; i < SCORE_LEDS; i++) {
                      strip_score.setPixelColor(i, strip_score.Color(255,0,0));//計分燈號=紅燈
                  strip_score.show();
          delay(80);
                  }
    strip_score.clear();    
    strip_score.show();
      gameState=1;//切換至第一關(遊戲開始)
    }
    strip_long.show();
  }

//------------------以下為 gameState = 1(第一關)-------------- 
//millis()當呼叫函式時,會回傳Arduino從開機到現在所經過的時間(毫秒ms),大約50天後數字會溢出(也就是會歸零)。
//使用delay來讓led閃爍:程式因為delay讓處理器空轉,導致Arduino無法做其他事。
//必須改用millis()
  if (gameState == 1) { 
    period = ledSpeed[0];  //LED跑的速度=50(數字愈大愈慢)
  //====== 平時(>大於)不成立...繞圈圈等待第一關'開關'被push =======
    if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
      Start_Time = millis(); // Start_Time=開機時間
      if (Push_Play) {    //如果第一關被push按下Push_Play=true    
      //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
        Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
        Push_Play = false;
      }
   //===============================================================  
      strip_long.setPixelColor(Set_Led-1, 255, 255, 0);//(黃)前一個燈=57
      strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
      strip_long.setPixelColor(Set_Led+1, 255, 255, 0);//(黃)後一個燈=59
     // strip_score.setPixelColor(0, 0, 255, 0);//???得分燈=綠色
      Serial.println(Set_Led);//隨機值random假設最大Set_Led=5a8 
      Ring_Run(Set_Led - 1, Set_Led + 1);//(前57 X 後59)前往設定燈號
    }
    if (digitalRead(A3) == LOW) { //(設定完成等待,玩家按下按鈕
      delay(80);//除火花
      Push_Play = false;
      if (led_run_at > Set_Led - 1 && led_run_at < Set_Led + 3) { ////循環紅點位置 落點 >57 且 落點 < 59
        level = gameState;
        gameState = 100; //勝利
      } else {
        gameState = 99; //失敗
    }
    }
   }
//------------------以下為 gameState = 2(第二關)-------------- 
          if (gameState == 2) {
        //    period = 320;
          period = ledSpeed[1];
          if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
            Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
            Push_Play = false;
            }
        //=============================================================== 
            strip_long.setPixelColor(Set_Led-1, 255, 255, 0);//(黃)前一個燈=57
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
            strip_long.setPixelColor(Set_Led+1, 255, 255, 0);//(黃)後一個燈=59
           // strip_score.setPixelColor(0, 0, 255, 0);//???得分燈=綠色
            Serial.println(Set_Led);//隨機值random假設最大Set_Led=58 
            Ring_Run(Set_Led - 1, Set_Led + 1);//(前57 X 後59)前往設定燈號
          }
           if (digitalRead(A3) == LOW) { //(設定完成等待,玩家按下按鈕
            delay(80);//除火花
            Push_Play = false;
            if (led_run_at > Set_Led - 1 && led_run_at < Set_Led + 3) { ////循環紅點位置 落點 >57 且 落點 < 59
            level = gameState;
            gameState = 100; //勝利
            } else {
            gameState = 99; //失敗
            }
          }
           }
//------------------以下為 gameState = 3(第三關)--------------           
          if (gameState == 3) {
          period = ledSpeed[2];
          if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
            Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 4(第四關)--------------          
          if (gameState == 4) {
          period = ledSpeed[3];
          if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
            Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 5(第五關)--------------
          if (gameState == 5) {
          period = ledSpeed[4];
          if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
            Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 6(第六關)--------------
          if (gameState == 6) {
          period = ledSpeed[5];
          if ( period < millis() - Start_Time) { // 開機時間> Start_Time+關卡speed值
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            //random(100);實際上只會產生 0~99 的亂數整數。本題若60顆,減4再加3(隨機最大數55+3=58中間值),不處理0,1及59
            Set_Led = random(NUM_LEDS-4) + 3; //若亂數取最大數(60-4)=55,55+3=58=(Set_Led)
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            gameState = 99;
            }
          }
          }     
  if(gameState==100){
      strip_long.setPixelColor(led_run_at, 255, 255, 0);
      delay(1380);
      winner();
    }
    if(gameState==99){
      strip_long.setPixelColor(led_run_at, 255, 255, 0);
      delay(1380);
      loser();
    }    
}
//-------------------------------------------------------------
//---------------------------紅色循環燈---------------------------
void Ring_Run(byte side1, byte side2){//若random=58傳來的值(57,59)
  strip_long.setPixelColor(led_run_at, 255, 0, 0);//亮現在"紅色循環燈"的位置
  if (led_run_at < side1 + 1 || led_run_at > side2 + 1) {//位置 <58 或 位置 >60
    strip_long.setPixelColor(led_run_at-1, 0, 0, 0);//燈號不亮
  }
  strip_long.show();//亮 57.58.59 及"循環紅點位置"
  led_run_at++; ////循環紅點位置..累加
  if (led_run_at >= NUM_LEDS) { //如果循環紅點位置=60符合則歸零
    strip_long.setPixelColor(led_run_at-1, 0, 0, 0);//第59顆歸0
    led_run_at = 0;//
  }
}
//-------------------------------------------------------------
void winner(){
  for (byte i = 0; i < 3; i++) 
  {
    for (byte j = 0; j < NUM_LEDS; j++) 
  {
      strip_long.setPixelColor(j, 0, 255, 0);
      tone(9, 1000, 250);
    }
    strip_long.show();
    delay(500);
    strip_long.show();
    delay(500);
  }
  Push_Play = true;
  led_run_at = 0;
  gameState = level + 1;
   if (gameState > 6) {
    gameState = 0;
  }
  count_led = gameState-1;
 //-----count led---------
    strip_score.clear();
  for (byte j = 0; j < count_led; j++) 
  {
      strip_score.setPixelColor(j, 255, 0, 0);
    }
  strip_score.show();
   //-----------------------
}
//-------------------------------------------------------------
void loser() {
  for (byte i = 0; i < 3; i++) {
    for (byte j = 0; j < NUM_LEDS; j++) {
      //leds[j].setRGB(255, 0, 0);
      strip_long.setPixelColor(j, 255, 0, 0);
      tone(9, 200, 250);
    }
    strip_long.show();
    delay(500);
    strip_score.clear(); //clearLEDS();
    strip_long.show();
    delay(500);
  }
  gameState = 0;
  led_run_at = 0;
}
  //-------------------------------------------------------------
void winAll(){
}
//----亂數顯示燈號----
void NUM_Random(){
for (byte i = 0; i < NUM_LEDS; i++) { //環燈號訊號
        strip_long.setPixelColor(i, random(0, 255), random(0, 255), random(0, 255));//黃色
        delay(10);
        strip_long.show(); 
    }
  }
void SCORE_Random(){
for (byte i = 0; i < SCORE_LEDS; i++) { //計分燈訊號
        strip_score.setPixelColor(i, random(0, 255), random(0, 255), random(0, 255));//黃色
        delay(10);
        strip_score.show(); 
    }
  }

cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

完成

文章 cajhbb »

代碼: 選擇全部

#include <Adafruit_NeoPixel.h>
#define DATA_PIN  A0 //環燈號訊號腳位
#define NUM_LEDS 28 //環燈燈珠顆數
#define SCORE_PIN 6 //計分燈訊號腳位
#define SCORE_LEDS 6 //計分燈燈數
#define BRIGHTNESS 10 //亮度在15~50即可,最大亮度為255

int gameState = 0; //遊戲狀態
int period = 1000;//週期
unsigned long Start_Time = 0;
byte led_run_at = 0; //燈號落點
int level = 0;
int count_led = 0;
byte side1=0,side2=0;
const byte ledSpeed[6] = {100, 80, 70, 50, 40, 30}; //共有6個等級的遊戲
//const byte ledSpeed[6] = {255,255,255,255,255,255}; //共有6個等級的遊戲
//消除彈跳Debounce
boolean Push_Play = false;
byte Set_Led = 0;
//-------------以上為所有宣告-----------------
//--------------------------------------------

//條燈初始化定義:strip函數-->宣告strip_long環燈 -->strip_score分數燈
Adafruit_NeoPixel strip_long(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_score(SCORE_LEDS, SCORE_PIN, NEO_GRB + NEO_KHZ800);

//------------ void setup()-----------------
void setup() {
    strip_long.begin(); //初始化(環燈)
    strip_score.begin(); //初始化(得分燈)
      strip_long.setBrightness(BRIGHTNESS); //亮度
      strip_score.setBrightness(BRIGHTNESS); //亮度
    strip_long.show();  //輸出
    strip_score.show();  //輸出
  pinMode(A3, INPUT_PULLUP);//按鈕輸入腳A3,上拉電阻
  Serial.begin(9600);
  Serial.println("Reset");
}
//------------ void loop() -----------------
void loop(){
//gameState = 0;初始燈號=亂數
//gameState = 1~6是6個關卡 
//gameState = 100 winner();勝利
//gameState = 99 loser();失敗 
//------------------以下為 gameState = 0-------------- 
   if (gameState == 0){
     NUM_Random();//亂數顯示燈號
     SCORE_Random();//亂數顯示燈號
    //按鈕被按下去,往下做 
    if (digitalRead(A3) == LOW) { //被按下去
      led_run_at = 0;//循環紅點位置
      Push_Play = true;//被按下去LOW,變數為true,開始6關遊戲
      delay(80);
           //-----逐一點亮(環燈=黃燈)+蜂鳴器(音效)-----
                for (byte i = 0; i < NUM_LEDS; i++) { //燈珠顆數:從0累加直到小於NUM_LEDS
                strip_long.setPixelColor(i, 255, 255, 0);//環燈逐顆,設為黃色
                delay(100);
                strip_long.show(); 
                //map(輸入數值來源,來源最小值,來源最大值,轉換後的最小值,轉換後的最大值)
               int thisPitch = map (i, 60, 0, 100, 1500);
                //範例:tone(2,1000,500);數位接腳2輸出1000Hz方波,時間0.5秒。
               tone(9, thisPitch,100);//蜂鳴器接D9
              }
           //-----逐一點亮(計分燈=紅燈)-----
                for (byte i = 0; i < SCORE_LEDS; i++) {
                      strip_score.setPixelColor(i, strip_score.Color(255,0,0));//計分燈號=紅燈
                  strip_score.show();
          delay(80);
                  }
    strip_score.clear();//分數燈熄滅    
    strip_score.show();
      gameState=1;//切換至第一關(遊戲開始)
    }
    strip_long.show();
  }

//------------------以下為 gameState = 1(第一關)-------------- 
//millis()當呼叫函式時,會回傳Arduino從開機到現在所經過的時間(毫秒ms),大約50天後數字會溢出(也就是會歸零)。
//使用delay來讓led閃爍:程式因為delay讓處理器空轉,導致Arduino無法做其他事。
//------------------------------------------------------------
  if (gameState == 1) { 
    period = ledSpeed[0];  //(陣列中的數字愈大愈慢)
  //====== 平時(>大於)不成立...繞圈圈等待第一關'開關'被push =======
    if ( millis() - Start_Time > period ) 
  {   // 開機時間- Start_Time> 週期
    Start_Time = millis(); // Start_Time=開機時間
    if (Push_Play) {    //如果第一關被push按下Push_Play=true    
           Set_Led = random(NUM_LEDS-4) + 3; //亂數只取前段,其餘不處理跨界問題
       Push_Play = false;
    }
   //===============================================================  
      strip_long.setPixelColor(Set_Led-1, 255, 255, 0);//(黃)前一個燈
      strip_long.setPixelColor(Set_Led, 0, 255, 0);//    (綠)設定燈
      strip_long.setPixelColor(Set_Led+1, 255, 255, 0);//(黃)後一個燈
   //===============================================================  
   // Serial.println(Set_Led);//隨機值
      Ring_Run(Set_Led - 1, Set_Led + 1);//(前 後)前往設定燈號
    }
    if (digitalRead(A3) == LOW) { //設定完成等待,玩家按下按鈕
      delay(80);//除火花
      Push_Play = false;
      if (led_run_at > Set_Led - 1 && led_run_at < Set_Led + 3) { //循環紅點位置 落點 >前 且 落點 < 後
        level = gameState;
        gameState = 100; //勝利
      } else {
        level = gameState;
        gameState = 99; //失敗
    }
    }
   }
//------------------以下為 gameState = 2(第二關)-------------- 
  if (gameState == 2) {
  period = ledSpeed[1];
  if ( millis() - Start_Time > period ) // 開機時間- Start_Time> 週期
  { Start_Time = millis(); 
  if (Push_Play) {    
  Set_Led = random(NUM_LEDS-4) + 3; //亂數只取前段,其餘不處理跨界問題
  Push_Play = false;
  }
   //===============================================================  
      strip_long.setPixelColor(Set_Led-1, 255, 255, 0);//(黃)前一個燈
      strip_long.setPixelColor(Set_Led, 0, 255, 0);//    (綠)設定燈
      strip_long.setPixelColor(Set_Led+1, 255, 255, 0);//(黃)後一個燈
   //===============================================================  
   // Serial.println(Set_Led);//隨機值
      Ring_Run(Set_Led - 1, Set_Led + 1);//(前 後)前往設定燈號
    }
     if (digitalRead(A3) == LOW) { //(設定完成等待,玩家按下按鈕
    delay(80);//除火花
    Push_Play = false;
    if (led_run_at > Set_Led - 1 && led_run_at < Set_Led + 3) { //循環紅點位置 落點 >前 且 落點 < 後
    level = gameState;
    gameState = 100; //勝利
    } else {
    level = gameState;
    gameState = 99; //失敗
    }
   }
    }
//------------------以下為 gameState = 3(第三關)--------------           
          if (gameState == 3) {
          period = ledSpeed[2];
          if ( millis() - Start_Time > period ) { // 開機時間- Start_Time> 週期
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) { 
            Set_Led = random(NUM_LEDS-1); //亂數只取前段,其餘不處理跨界問題
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            level = gameState;
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 4(第四關)--------------          
          if (gameState == 4) {
          period = ledSpeed[3];
          if ( millis() - Start_Time > period ) { // 開機時間- Start_Time> 週期
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            Set_Led = random(NUM_LEDS-1); //亂數只取前段,其餘不處理跨界問題
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            level = gameState;
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 5(第五關)--------------
          if (gameState == 5) {
          period = ledSpeed[4];
          if ( millis() - Start_Time > period ) { // 開機時間- Start_Time> 週期
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            Set_Led = random(NUM_LEDS-1); //亂數只取前段,其餘不處理跨界問題
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            level = gameState;
            gameState = 99;
            }
          }
          }
//------------------以下為 gameState = 6(第六關)--------------
          if (gameState == 6) {
          period = ledSpeed[5];
          if ( millis() - Start_Time > period ) { // 開機時間- Start_Time> 週期
            Start_Time = millis(); // Start_Time=開機時間
            if (Push_Play) {    //如果第一關被push按下Push_Play=true    
            Set_Led = random(NUM_LEDS-1); //亂數只取前段,其餘不處理跨界問題
            Push_Play = false;
            }
        //===============================================================
            strip_long.setPixelColor(Set_Led, 0, 255, 0);//(綠)正中間=58
           //sleds[2].setRGB(255, 50, 0);//得分燈
            Ring_Run(Set_Led, Set_Led);
          }
          if (digitalRead(A3) == LOW) {
            delay(80);
            if (led_run_at == Set_Led+1) {
            level = gameState;
            gameState = 100;
            } else {
            level = gameState;
            gameState = 99;
            }
          }
          }     
  if(gameState==100){
      strip_long.setPixelColor(led_run_at, 255, 255, 0);
      delay(1380);
      winner();
    }
    if(gameState==99){
      strip_long.setPixelColor(led_run_at, 255, 255, 0);
      delay(1380);
      loser();
    }    
}
//-------------------------------------------------------------
//---------------------------紅色循環燈---------------------------
void Ring_Run(byte side1, byte side2){//若random=58傳來的值(57,59)
  strip_long.setPixelColor(led_run_at, 255, 0, 0);//亮現在"紅色循環燈"的位置
  if (led_run_at < side1 + 1 || led_run_at > side2 + 1) {//位置 <58 或 位置 >60
    strip_long.setPixelColor(led_run_at-1, 0, 0, 0);//燈號不亮
  }
  strip_long.show();//亮 57.58.59 及"循環紅點位置"
  led_run_at++; ////循環紅點位置..累加
  if (led_run_at >= NUM_LEDS) { //如果循環紅點位置=60符合則歸零
    strip_long.setPixelColor(led_run_at-1, 0, 0, 0);//第59顆歸0
    led_run_at = 0;//
  }
}
//-------------------------------------------------------------
void winner(){
//-------------得分燈-------------
  Push_Play = true;
  led_run_at = 0;
  gameState = level + 1;//下一關
   if (gameState > 6) 
   { 
  //----過完6關---
     count_led++;//加分
     strip_score.clear();
     for (byte j = 0; j < count_led; j++) 
        {
       strip_score.setPixelColor(j, 255, 0, 0);//加分(紅色)
        }
       strip_score.show();
     delay(500);
       gameState = 0;
       count_led = 0;
   } 
   else //-----count led---------
   { count_led++;//加分

     strip_score.clear();
     for (byte j = 0; j < count_led; j++) 
        {
       strip_score.setPixelColor(j, 255, 0, 0);//加分(紅色)
        }
       strip_score.show();
   }
//-------------綠環+鳴-------------  
  for (byte i = 0; i < 3; i++) 
  {
    for (byte j = 0; j < NUM_LEDS; j++) 
    {
      strip_long.setPixelColor(j, 0, 255, 0);//綠環過關
      tone(9, 1000, 250);//鳴
    }
    strip_long.show();
    delay(500);
    strip_long.clear();
    strip_long.show();
    delay(500);
  }
}
//-------------------------------------------------------------
void loser() {
//-------------失敗燈-------------
  Push_Play = true;
  led_run_at = 0;
  gameState = level + 1;//下一關
   if (count_led < 0 || gameState > 6) 
   {
    gameState = 0;
    count_led = 0;
   } else //-----count led---------
   { 
   strip_score.clear();
     for (byte j = 0; j < count_led; j++) 
        {
       strip_score.setPixelColor(j, 255, 0, 0);
        }
       strip_score.show();
   }
//-------------紅環+鳴-------------   
  for (byte i = 0; i < 3; i++)
  {
    for (byte j = 0; j < NUM_LEDS; j++) 
    {
      strip_long.setPixelColor(j, 255, 0, 0);//紅環失敗
      tone(9, 200, 250);//鳴
    }
  strip_long.show();
  delay(500);
  strip_long.clear();
  strip_long.show();
  delay(500);
  }
}
//----亂數顯示燈號----
void NUM_Random(){
for (byte i = 0; i < NUM_LEDS; i++) { //環燈號訊號
        strip_long.setPixelColor(i, random(0, 255), random(0, 255), random(0, 255));//黃色
        delay(10);
        strip_long.show(); 
    }
  }
void SCORE_Random(){
for (byte i = 0; i < SCORE_LEDS; i++) { //計分燈訊號
        strip_score.setPixelColor(i, random(0, 255), random(0, 255), random(0, 255));//黃色
        delay(10);
        strip_score.show(); 
    }
  }
cajhbb
系統管理員
文章: 903
註冊時間: 2018年 6月 30日, 02:16

電路圖

文章 cajhbb »

2023-01-17_143420.jpg
2023-01-17_143420.jpg (153.06 KiB) 已瀏覽 792 次
回覆文章