节奏大灯源码
#include <Adafruit_NeoPixel.h>
// ========== 引脚固定 ==========
#define L_STRIP 7
#define M_STRIP 5
#define R_STRIP 6
#define LED_CNT 6
#define KEY1 0
#define KEY2 1
#define KEY3 10
// =============================
Adafruit_NeoPixel stripL(LED_CNT, L_STRIP, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripM(LED_CNT, M_STRIP, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripR(LED_CNT, R_STRIP, R_STRIP, NEO_GRB + NEO_KHZ800);
// 游戏变量
int nowLine = 0;
int dotPos = 5;
int speed = 800;
int minSpeed = 280;
unsigned long timer = 0;
// 状态
bool waitStart = true;
bool gameFail = false;
void setup() {
Serial.begin(115200);
stripL.begin();
stripM.begin();
stripR.begin();
pinMode(KEY1, INPUT_PULLUP);
pinMode(KEY2, INPUT_PULLUP);
pinMode(KEY3, INPUT_PULLUP);
// 开机 全部全亮
showAllFull();
randomSeed(millis());
}
void loop() {
// 待机界面:全亮,按任意键开始
if(waitStart){
if(anyKeyPress()){
waitStart = false;
newWave();
}
return;
}
// 失败界面:灯闪烁,按任意键重置
if(gameFail){
failBlink();
if(anyKeyPress()){
gameFail = false;
speed = 800;
showAllFull();
waitStart = true;
}
return;
}
// 游戏运行
gameMove();
checkHit();
}
// 随机新轨道 生成音符
void newWave(){
clearAll();
// 终点第一颗常亮
stripL.setPixelColor(0, stripL.Color(0, 50, 100));
stripM.setPixelColor(0, stripM.Color(0, 50, 100));
stripR.setPixelColor(0, stripR.Color(0, 50, 100));
nowLine = random(1,4); //1左 2中 3右
dotPos = 5;
timer = millis();
refreshShow();
}
// 光点前移
void gameMove(){
if(millis() - timer >= speed){
timer = millis();
dotPos --;
// 走完没按 = 失败
if(dotPos < 0){
gameFail = true;
return;
}
refreshShow();
}
}
// 刷新当前光点
void refreshShow(){
clearAll();
stripL.setPixelColor(0, stripL.Color(0, 50, 100));
stripM.setPixelColor(0, stripM.Color(0, 50, 100));
stripR.setPixelColor(0, stripR.Color(0, 50, 100));
if(nowLine == 1) stripL.setPixelColor(dotPos, stripL.Color(200, 0, 200));
if(nowLine == 2) stripM.setPixelColor(dotPos, stripM.Color(200, 0, 200));
if(nowLine == 3) stripR.setPixelColor(dotPos, stripR.Color(200, 0, 200));
stripL.show();
stripM.show();
stripR.show();
}
// 按键判定
void checkHit(){
// 刚好到判定点 pos=0 才算命中
if(dotPos == 0){
if(KEY1==0 && digitalRead(KEY1)==LOW && nowLine==1){
hitSuccess();
}
if(digitalRead(KEY2)==LOW && nowLine==2){
hitSuccess();
}
if(digitalRead(KEY3)==LOW && nowLine==3){
hitSuccess();
}
}
}
// 命中成功 加速
void hitSuccess(){
speed -= 40;
if(speed < minSpeed) speed = minSpeed;
// 绿色反馈
if(nowLine==1){stripL.fill(stripL.Color(0,200,0));stripL.show();}
if(nowLine==2){stripM.fill(stripM.Color(0,200,0));stripM.show();}
if(nowLine==3){stripR.fill(stripR.Color(0,200,0));stripR.show();}
delay(200);
newWave();
}
// 失败 全灯闪烁
void failBlink(){
static unsigned long t = 0;
static bool flg = false;
if(millis()-t > 150){
t=millis();
flg=!flg;
if(flg){
stripL.fill(stripL.Color(200,0,0));
stripM.fill(stripM.Color(200,0,0));
stripR.fill(stripR.Color(200,0,0));
}else{
clearAll();
}
stripL.show();stripM.show();stripR.show();
}
}
// 任意按键按下
bool anyKeyPress(){
if(digitalRead(KEY1)==LOW || digitalRead(KEY2)==LOW || digitalRead(KEY3)==LOW){
delay(200);
return true;
}
return false;
}
// 全部清空
void clearAll(){
stripL.clear();
stripM.clear();
stripR.clear();
stripL.show();
stripM.show();
stripR.show();
}
// 开机全亮
void showAllFull(){
stripL.fill(stripL.Color(60,60,60));
stripM.fill(stripM.Color(60,60,60));
stripR.fill(stripR.Color(60,60,60));
stripL.show();
stripM.show();
stripR.show();
}
总结
越玩越快

