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.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Gather Supplies

  • Main Components:
    • Arduino (I used an UNO)
    • String of individually addressable LEDs (I used link)
    • Push button (I used link)
    • Printed circuit board (PCB) or breadboard
    • Power Supply (I used two separate power supplies, you may get away with one if you are creative)
      • 5V 3A for LEDs
      • 9V 1A for Arduino
  • 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.

Step 4: Play!

Be the First to Share

    Recommendations

    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    5 Discussions

    0
    None
    LEDLIT1

    Question 8 months ago on Step 2

    Hi. I am building a mini version of this and wanted to use A different fastLED pattern other than cylon. I want it to trigger the fire2012 pattern or maybe something else, but I can't figure out how. Can you help me?

    2 answers
    0
    None
    ChetAkinsLEDLIT1

    Answer 8 months ago

    I donated this arcade game, so I have no way of testing. However, I may help lead you in the right direction.

    You will need to include the fire2012 code somewhere in your script. For example, I included the cylon code under "void cylon()" near the bottom of my script. Next, you will need to replace both of the "cylon();" under the "wonThisRound" section. I would tweak with the i < 2 and i < 8 in this part as well to determine how many cycles of the fire2012 you want. Hope this helps.

    Otherwise, I would recommend going through the code line by line to try and understand it. It may take awhile, but it will start making sense. Then you may organize / rewrite the code so it makes sense to you and tweak it to your liking. Good luck!

    0
    None
    LEDLIT1ChetAkins

    Reply 8 months ago

    Thank you. tweeking the the i < 2 and i < 8 helped me to understand a great deal more of what was happening in the code. I will update you in the future when I get more done. Thank you again

    0
    None
    LEDLIT1

    9 months ago on Step 2

    The code gave me an error message saying "no matching function for call to 'CFastLED::addLeds(CRGB[28], int)' ". I did some reading at https://github.com/FastLED/FastLED/wiki/Basic-usag... and figured out the problem.
    This is what fixed it. I changed code line 53 from FastLED.addLeds(leds, NUM_LEDS); to FastLED.addLeds<NEOPIXEL, DATA_PIN> (leds, NUM_LEDS); and it worked after that. Thank you for posting this game. When I am finished building my version I I will share it with you.

    Nice. I remember spending quite a few quarters on games like this.