I love Old West Shoot ’em Up games, and I wanted to create a way for people to test their quick draw shooting skills with toy pistols, so I built an interactive game called “The Quick and The Dead — Fastest Draw in The West” using the Arduino and some Processing code.

toy pistol with switches

Toy pistol with switches

GAME
There are two ways to play the game: single shooter and two-person shooter.

The object of the single shooter game is to see how fast you can draw two pistols and fire them in a race against the clock. When you see the blue light turn on and hear the music play, draw your guns and fire as quickly as you can. See if you can draw and fire in less than 1.8 seconds and win the title “Fastest Gunslinger in The West — Outlaw!” When this happens, the green LED lights up. If you make it between 1.8 and 3 seconds, you win “Sharp Shooter!” and the yellow LED lights up, and if you make it in more than 3 seconds, then you are a “Dead Man!” and the red LED lights up.

The object of the two-person shooter game is to see how fast you can draw your pistol against the other person. Two people should stand and face each other, then turn around and walk step three paces away from each other. When you hear the music play, each person should turn, draw, and fire. Whoever draws and fires first, wins! The winner’s LED will light up when he/she fires first.

Fastest Draw in The West from Suzanne Kirkpatrick on Vimeo.

HOW IT WORKS
This project uses an Arduino microcontroller, tilt switches, push-button switches, and Processing code to control the music. The microcontroller is receiving five digital inputs (tilt switch #1, tilt switch #2, trigger switch #1, trigger switch #2, and LED switch), and conveying four digital outputs (blue LED, green LED, yellow LED, and red LED). When the guns are tilted from vertical to horizontal position, the tilt switches flip on. And when the gunslinger fires the trigger of each gun, the push-buttons are pressed, which completes an event.

When all four of these switches have been turned on, the microcontroller captures a score based on the number of milliseconds that have passed since the blue LED turned on indicating “Go!” The gunslinger’s score is displayed through LEDs (green, yellow, red), and can also be printed in the serial monitor of the Arduino. The actual time score (number of seconds) can also be printed, if a person wants to try and beat his/her own best score. For example, this player fired in 2.9 seconds and won. Based on this test, I decided to lower the first place threshold to 1.8 seconds to make the game more challenging.

Gunslinger's score

Gunslinger's score

I used the minim library imported into Processing to play the western song (mp3 file), and used serial communication between the Arduino and Processing to make it play when someone presses the red button.

PROJECT DESIGN
I was really excited about these pistols when they arrived in the mail. I had researched quite a few toy guns online, and had chosen this particular model because of the real likeness to a western pistol, and because of its die-cast metal material. These are most likely made of an alloy of zinc, with small quantities of aluminum and copper.

I wired the tilt switches to the sides of the barrels of the guns, so that they wouldn’t get jostled when the guns are placed inside of the holsters, like this:

tilt switch attachment

Placement of tilt switch

I went through many iterations of designs for the gun trigger switches. Originally, I thought I would use the conductivity of the gun’s metal material to make a switch, since the entire gun is conductive, except for the plastic handle. However, due to the conductive metal of the gun itself, I actually had to change the placement of the trigger switch on the gun three times before I found an accurate reading because a slight movement in the wiring occasionally returned an inaccurate 0 or 1 byte in the switch. First, I placed the switch on the hammer and the back of the handle, then I tried placing it on the top cock, and then on the bottom of the gun, but I could not insulate the wiring very well or prevent it from moving.
Gun Trigger Design Iterations

Design iterations of gun trigger switch

Finally, I decided to place a push-button switch behind the trigger, which worked and always returned an accurate reading! However, this placement of the push-button switch somewhat inhibits the trigger from reaching its full action, so if I were to iterate the design a fourth time, I would place two contacts made of copper tape which would be much thinner and thus allow the trigger to reach its full action when firing the gun.
Final placement of gun trigger switch

Final placement of trigger switch

Next, I built my circuit using a breadboard before I soldered the final layout permanently onto a perf board. Here’s diagram of the breadboard, made with Fritzing: "Fastest Draw in The West" breadboard schematic

Here’s the circuit schematic:
"Fastest Draw in The West" circuit schematic

Here’s my first prototype with a breadboard circuit:

Basic prototype with breadboard

First prototype with breadboard

Once I was satisfied with my circuit, I soldered all of my wires and resistors to a small perf board (dual mini board with 213 holes).
perf board soldering
I placed the parts inside of an aluminum project box insulated with non-conductive foam, and I made the red push-button switch and LEDs extend out through the top of the box. Then, I pasted scoring labels on the top of the box that correspond to each LED signal, like this:
project box labels

project box labels

Here’s the finished project box completely screwed shut:
Finished project box

Finished project box with LEDs

LESSONS LEARNED
1. Aluminum project boxes are light-weight and easy to drill, however they present conductivity challenges, so remember to insulate your components and the inside of the box well, using non-conductive foam, or another material that can prevent the metal leads and wires from touching the box.

2. When you want to detect whether an event has occurred or not, use the “change state detection” logic in your code to tell the microcontroller that the current state of the event does NOT equal the previous state of the event.

3. Use hot glue to strengthen your soldering points, and also to insulate your exposed wires, especially when soldering on a perf board.

4. Be careful when choosing an item that is very conductive for your project (like my pistols), as it presents certain electrical challenges when attaching leads, sensors, and switches.

CODE
Here is the code for the single shooter game:

/*
 The Quick and the Dead - "Fastest Draw in the West"
 by Suzanne Kirkpatrick, Oct 2010
 */

// variables for time counter
long startTime = 0;
long endTime = 0;

// LED connected to digital pin 7 (use a big bright blue light to indicate "GO!")
int ledPinGo = 7;
//LED connected to digital pin 8 (use a green LED to indicate 1st place)
int ledPinGreen = 8;
// LED connected to digital pin 9 (use a yellow LED to indicate 2nd place)
int ledPinYellow = 9;
// LED connected to digital pin 10 (use a red LED to indicate 3rd place: "DEAD MAN")
int ledPinRed = 10;

//variables for switch connected to LED
int ledSwitch = 6;
int ledSwitchState = LOW;
int lastledSwitchState = LOW;

// variables for first gun:
const int tiltSwitch = 2; // Input pin 2 on Arduino
const int hammerSwitch = 3; // Input pin 3 on Arduino

int tiltSwitchState = LOW;
int hammerSwitchState = LOW;
int lastHammerSwitchState = LOW;

boolean gunIsHorizontal = false;
boolean gunIsFired = false;

// variables for second gun:
const int tiltSwitchTwo = 4; // Input pin 4 on Arduino
const int hammerSwitchTwo = 5; // Input pin 5 on Arduino

int tiltSwitchTwoState = LOW;
int hammerSwitchTwoState = LOW;
int lastHammerSwitchTwoState = LOW;

boolean gunTwoIsHorizontal = false;
boolean gunTwoIsFired = false;

// variable for score
boolean printed = false;

//------------------------------------------------------------

void setup() {
  //declare the ledSwitch pin as input
  pinMode(ledSwitch,INPUT);
  // declare the tiltSwitches' pins as inputs
  pinMode(tiltSwitch,INPUT);
  pinMode(tiltSwitchTwo,INPUT);
  // declare the hammerSwitches' pins as inputs
  pinMode(hammerSwitch,INPUT);
  pinMode(hammerSwitchTwo,INPUT);
  // initialize the digital pins as outputs
  pinMode(ledPinGo,OUTPUT);
  pinMode(ledPinGreen,OUTPUT);
  pinMode(ledPinYellow,OUTPUT);
  pinMode(ledPinRed,OUTPUT);
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {

  // read our switches' inputs:
  ledSwitchState = digitalRead(ledSwitch); // recognizing pin 0 is LOW
  tiltSwitchState = digitalRead(tiltSwitch); // recognizing pin 2 is LOW (first gun is vertical)
  hammerSwitchState = digitalRead(hammerSwitch); //recognizing pin 3 is HIGH (first hammer is closed)
  tiltSwitchTwoState = digitalRead(tiltSwitchTwo); // recognizing pin 4 is LOW (second gun is vertical)
  hammerSwitchTwoState = digitalRead(hammerSwitchTwo); // recognizing pin 5 is HIGH (second hammer is closed)

  //-----------------------------------------------------------

  // turn on blue LED to indicate "GO!"
  if(ledSwitchState != lastledSwitchState) {
    if(ledSwitchState == HIGH) {
      // turn on blue LED

      Serial.print(1, BYTE);               // send 1 to Processing to play song
      // records number of milliseconds captured since blue LED was turned on
      startTime = millis();
      digitalWrite(ledPinGo, HIGH);
    }
    else {                               // If the switch is not ON,
      Serial.print(0, BYTE);               // send 0 to Processing
    }
  }

  lastledSwitchState = ledSwitchState;

  //-----------------------------------------------------------

  //person draws two guns from holsters

  // tilt switches flip when guns are horizontal
  if(tiltSwitchState == LOW) {
    gunIsHorizontal = true;
  }
  else {
    gunIsHorizontal = false;
  }

  if(tiltSwitchTwoState == LOW) {
    gunTwoIsHorizontal = true;
  }
  else {
    gunTwoIsHorizontal = false;
  }

  // check if the guns (hammers) have been fired or not
  if(hammerSwitchState != lastHammerSwitchState) {
    if(hammerSwitchState == LOW) {
      gunIsFired = true;
    }
    else {
      gunIsFired = false;
    }
  }
  if(hammerSwitchTwoState != lastHammerSwitchTwoState) {
    if(hammerSwitchTwoState == LOW) {
      gunTwoIsFired = true;
    }
    else {
      gunTwoIsFired = false;
    }
  }

  lastHammerSwitchState = hammerSwitchState;
  lastHammerSwitchTwoState = hammerSwitchTwoState;

  //--------------------------------------------------------------

  if((gunIsHorizontal == true) && (gunIsFired == true) && (gunTwoIsHorizontal == true) && (gunTwoIsFired == true)) {
    digitalWrite(ledPinGo, LOW); // turn the blue LED off
    // number of milliseconds captured from start to fire
    long endTime = millis() - startTime;
    // report the score
    if(printed == false) {

      if(endTime  1800) && (endTime  3000) && (endTime < 10000)) {
        printed = true;
        // report the losing score
        digitalWrite(ledPinRed, HIGH); // turn on the red LED
        delay(100);
        digitalWrite(ledPinRed, LOW);
        delay(100);
        digitalWrite(ledPinRed, HIGH);
        digitalWrite(ledPinRed, LOW);
        delay(100);
        digitalWrite(ledPinRed, HIGH);
        Serial.println("NOT FAST ENOUGH -- DEAD MAN");
      }
      else {
        printed = true;
        // report end game
        Serial.println("GAME OVER");
      }
    }
  }
}
//END

The code for the two-person shooter game is much more simple, because it doesn’t involve any measurement of time (milliseconds). Rather, it just detects which person has fired first.


No Responses to “Fastest Draw in The West”  

  1. 1 Tom Igoe

    Great post. Describes the thing well first, followed by the details, so the reader is never lost. A couple things that might make it even better:

    * picture or diagram of the guns at the beginning, so when you’re describing the game, the reader has a visual.
    * Drawing or schematic of the circuit.

  2. 2 suzkita

    Great, thanks for the feedback. I’ve added a schematic of the circuit and breadboard diagram for more detail.

Leave a Reply