Introduction: Cyclone LED Arcade Game
The intent of this project was to create a simple game using an Arduino that would be interactive and entertaining for kids. I remember the Cyclone arcade game being one of my favorite arcade games when I was younger, so I decided to replicate it. This is a very simple project that consists of an Arduino, string of individually adressable LEDs, and a push button.
The goal of the game is to stop the cycling light when it reaches the indicated (red) LED. If successful, the difficulty level will increase. If unsuccessful, the light cycle will restart at the current difficulty level.
This instructable was a huge resource for the core of my coding.
Step 1: Gather Supplies
- Main Components:
- Framework:
- Electronics housing (I modified a wooden lamp fixture from Goodwill)
- LED housing (I modified your standard wall clock and drilled holes using the minute identifiers as hole markings. Use a wood clock if possible to make drilling easier.)
- Button housing (I used an elbow PVC pipe)
- Tools / Other Materials:
- Spare wiring for your circuit
- 10K (pull-down resistor for switch) and 470 ohm (for data wire on LEDs) resistors
- Drill for creating holes to house your LEDs and and making any necessary holes in your fixture to pass wires through
- Soldering iron for soldering your circuit to a PCB
- Hot glue gun for securing the LEDs to your fixture
- Velcro or some means of securing the framework together
- Gaskets optional for holes drilled for wires to pass through
Step 2: Upload Code
Make sure you download and add the "FastLED" library
The core of the code (void loop) consists of two states: push button high (End Game) and push button low (Playing). Once the user presses the button, the LED address the light was stopped on is compared to the address of the center LED. If they are not the same, all the lights flash red twice and the current level restarts. If they are the same, cylon (FastLED library script) runs twice, the difficulty level increases, and playing resumes. Once the player beats the last level, cylon runs eighth times and the game restarts at level 1.
//Cyclone Game #include "FastLED.h" //up to 50 #define NUM_LEDS 40 #define CENTER_LED 21 #define DATA_PIN 7 #define LED_TYPE WS2811 #define COLOR_ORDER RGB //range 0-64 #define BRIGHTNESS 50 //Definition of difficulty levels #define EASY 1 #define MEDIUM 2 #define HARD 3 #define ON_SPEED 4 #define SONIC_SPEED 5 #define ROCKET_SPEED 6 #define LIGHT_SPEED 7 #define MISSION_IMPOSSIBLE 8 //Starting difficulty int difficulty = 1; // Define the array of leds CRGB leds[NUM_LEDS]; // Did player win this round? This tag is used for difficulty parameters. bool wonThisRound = false; // Starting location of the cycling light int LEDaddress = 0; // Is game running? bool Playing = true; // Is this the first win? bool CycleEnded = true; // Button details const int buttonPin = 9; int buttonState = 0; // Initialize the led library and arduino functions void setup() { FastLED.addLeds(leds, NUM_LEDS); FastLED.setBrightness(BRIGHTNESS); pinMode(buttonPin, INPUT); Serial.begin(9600); } // The meat and potatoes //Two Modes - Playing and End Game void loop() { //END GAME buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { Playing = false; //User has pressed the button, and the LED has stopped on the winning address. for (int i = 0; i < NUM_LEDS; i++) { leds [i] = CRGB::Black; } leds[CENTER_LED] = CRGB::Red; leds[LEDaddress] = CRGB::Green; FastLED.show(); if (CycleEnded = true) { int diff = abs(CENTER_LED - LEDaddress); //Finds distance between the lit led and the center led if (diff == 0) { wonThisRound = true; //Player sucessfully beat the level if (difficulty != MISSION_IMPOSSIBLE) { for (int i = 0; i < 2; i++) { cylon(); } } if (difficulty == MISSION_IMPOSSIBLE) { for (int i = 0; i < 8; i++) { cylon(); } difficulty = 0; } increaseDifficulty(); wonThisRound = false; } else { delay(1000); for (int i = 0; i < 2; i++) { flash(); } } CycleEnded = false; } LEDaddress = 0; delay(250); buttonState = digitalRead(buttonPin); if (buttonState == LOW) { Playing = true; } } //PLAYING if(Playing) { for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CRGB::Black; //Turns off all the leds } leds[CENTER_LED] = CRGB::Red; //Sets center led color to green leds[LEDaddress] = CRGB::Green; //Sets cyling led color to red FastLED.show(); //Initializes light cycle LEDaddress++; //Sets light cycle to one led at a time if (LEDaddress == NUM_LEDS) { LEDaddress = 0; } delay(getTime(difficulty)); buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { Playing = false; CycleEnded = true; } } } //Level Parameters int getTime(int diff) // Returns time delay for led movement base on difficulty { int timeValue = 0; switch (diff) { case EASY: timeValue = 100; break; case MEDIUM: timeValue = 80; break; case HARD: timeValue = 60; break; case ON_SPEED: timeValue = 40; break; case SONIC_SPEED: timeValue = 30; break; case ROCKET_SPEED: timeValue = 20; break; case LIGHT_SPEED: timeValue = 13; break; case MISSION_IMPOSSIBLE: timeValue = 7; } return timeValue;// Return the delay amount } //Winning difficulty increase parameters void increaseDifficulty() { if (difficulty != MISSION_IMPOSSIBLE && wonThisRound) { difficulty++; } } //Lost LED Show void flash() { fill_solid(leds, NUM_LEDS, CRGB::Red); FastLED.show(); delay(500); fill_solid(leds, NUM_LEDS, CRGB::Black); FastLED.show(); delay(500); } //Won LED Show void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } } void cylon() { static uint8_t hue = 0; Serial.print("x"); // First slide the led in one direction for(int i = 0; i < NUM_LEDS; i++) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } Serial.print("x"); // Now go in the other direction. for(int i = (NUM_LEDS)-1; i >= 0; i--) { // Set the i'th led to red leds[i] = CHSV(hue++, 255, 255); // Show the leds FastLED.show(); // now that we've shown the leds, reset the i'th led to black // leds[i] = CRGB::Black; fadeall(); // Wait a little bit before we loop around and do it again delay(10); } }
Step 3: Install in Fixture
I am not going to go into details in this section. There are a thousand different ways to go about this part and I think you should be creative to make it look how you like it. That being said, the clock was pretty convenient to use for housing the LEDs as it had minute indicators that I was able to use as drill markings. Also, the glass cover also lets me use this as a table.
The velcro was very useful as well for securing the LED fixture to the electronics housing fixture. I also used velcro on the Arduino. This made it very convenient for pulling the Arduino out if I ever want to modify the code.