基于街机游戏《Cyclone》,玩家需要尝试在特定位置停止 LED 的圆圈滚动。
这次我将向你展示如何制作一款有趣的游戏,它基于一款名为“Cyclone”的街机游戏。游戏中,玩家需要尝试在特定位置停止 LED 灯的循环滚动。游戏的目标是在 LED 灯到达指示点(红色)时停止循环滚动。如果成功,难度级别将会增加。如果失败,游戏将重新开始。
圆环由 60 个 LED 灯组成(4 个四分之一圆 Neopixel 灯,每个灯由 15 个 LED 组成)。圆环支架由 3D 打印机制作,您可以下载下方的 .stl 文件。圆环中间是一条由 6 个 RGB LED 组成的灯带,代表六个等级。基本代码取自 oKeeg 的 Instructable,我做了一些修改,使游戏更加有趣。
首先,我降低了二极管的光强度,因为在我的游戏版本中 LED 是直接可见的。
然后,环中包含 60 个 LED,而不是 40 个,因为我从我之前的一个项目(LED 环形时钟)中使用了它。
我还添加了两个级别,这样游戏现在总共有 6 个级别。
下一个非常重要的修改是我在游戏中添加了声音,现在玩起来更有趣了。
-最后,我制作了一个大的街机按钮,以便更准确地玩游戏。
游戏需要 5V/3A 或更高的电源供电。这是一个非常简单的项目,仅包含几个组件:
- Arduino 纳米微控制器
- WS2812 LED 环,带 60 个 RGB LED
- WS2812 LED 灯带,带 6 个 RGB LED
- 一个晶体管
- 蜂鸣器
- 以及大型 DIY 街机按钮
您在图片中看到的实时时钟模块未处于活动状态,并且是我之前项目的一部分。
我们也可以使用上一个项目剩下的旋转编码器按钮。在这种情况下,设备小巧紧凑,但操作起来比较困难。
启动游戏时,所有 LED 都会亮起不同的颜色。按下按钮,游戏开始。目标是在旋转二极管恰好位于静态二极管上时按下按钮。在前两级中,三个二极管是静态的,在接下来的级别中只有一个。而且,随着每个级别的增加,二极管的速度都会增加,因此在所需的时刻按下按钮会变得越来越困难。每完成一个级别,水平行中的一个二极管就会亮起。总共有六个级别,所以这一行包含六个二极管。如果我们未能通过该级别,游戏将从头开始。如果您通过了所有六个级别,游戏也将从头开始。
最后,将该装置装入由PVC板制成并涂有自粘彩色壁纸的合适盒子中。





项目代码
#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(){
}
【Arduino 动手做】 基于街机游戏《Cyclone》的LED环
项目链接:https://www.hackster.io/mircemk/diy-arduino-cyclone-game-with-ws2812b-led-ring-738c58
项目作者:北马其顿 米尔塞姆克(Mirko Pavleski)
项目视频 :https://www.youtube.com/watch?v=1K0vr-hrh0k
项目代码:https://www.hackster.io/code_files/581838/download
3D 文件:https://hacksterio.s3.amazonaws.com/uploads/attachments/1422211/ring_Vvyxo74B6t.stl


寸进2025.06.21
真的很酷炫啊
驴友花雕2025.06.21
谢谢鼓励啊