Fastest Draw in The West
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.
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.
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:
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: 
Here’s my first prototype with a breadboard circuit:

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: Here’s the finished project box completely screwed shut:
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.











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.
Great, thanks for the feedback. I’ve added a schematic of the circuit and breadboard diagram for more detail.