Lunar Lander Game Controller

My main objective in making the game controller for Atari’s Lunar Lander was to have it be large so a player would have to move around a bit in order to play. Initially I thought about making it into a foot controller, retrospectively inspired by Dance Dance Revolution. But veered away from that idea after being discouraged about what materials to use. I also played around with the idea to use an accelerometer and have the controller be a wearable. And then decided against that, as it would require housing a lot of wires on the body and difficult to scale. Then suddenly, the idea of using shoe boxes came to me. What if I used a couple of shoe boxes to stack making the controller more physical? Additionally, the traditional opening of the shoe box would mean easy access to get to my circuit in case I needed to change, or fix anything (which became many times).

 

Code

#include <Mouse.h>
#include <Keyboard.h>

//mouse variables
int leftClick = 7;
//keyboard variables

int buttonA = 3;
int buttonD = 4;
int buttonW = 6;
int buttonS = 5;

int reload = 7;
int enter = 8;

int previousButtonStateA = LOW;
int previousButtonStateD = LOW;
int previousButtonStateW = LOW;
int previousButtonStateS = LOW;
void setup() {
// put your setup code here, to run once:
pinMode(buttonA, INPUT);
pinMode(buttonD, INPUT);
pinMode(buttonW, INPUT);
pinMode(buttonS, INPUT);
pinMode(leftClick, INPUT);
Serial.print(“hi”);
Mouse.begin();
Keyboard.begin();

}

void loop() {
// put your main code here, to run repeatedly:
if (digitalRead(reload) == HIGH) {
Keyboard.press(135);
Keyboard.press(‘r’);
} else {
Keyboard.releaseAll();
}

if (digitalRead(enter) == HIGH) {
Keyboard.press(176);
delay(500);
} else {
Keyboard.release(176);
}
int buttonStateA = digitalRead(buttonA);

if ((buttonStateA != previousButtonStateA) && (buttonStateA == HIGH)) {
Keyboard.press(65);
delay(500);
} else if (digitalRead(buttonStateA) == LOW) {
Keyboard.release(65);
}

int buttonStateD = digitalRead(buttonD);

if ((buttonStateD != previousButtonStateD) && (buttonStateD == HIGH)) {
Keyboard.press(68);
delay(500);
} else if (digitalRead(buttonStateA) == LOW) {
Keyboard.release(68);
}

int buttonStateW = digitalRead(buttonW);

if ((buttonStateW != previousButtonStateW) && (buttonStateW == HIGH)) {
Keyboard.press(87);
delay(500);
} else if (digitalRead(buttonStateW) == LOW) {
Keyboard.release(87);
}

int buttonStateS = digitalRead(buttonS);

if ((buttonStateS != previousButtonStateS) && (buttonStateS == HIGH)) {
Keyboard.press(83);
delay(500);
} else if (digitalRead(buttonStateS) == LOW) {
Keyboard.release(83);
}

}

 

Initial sketch

Circuit Diagram

Testing with the circuit (buttons: A, D, S, W)

Attempting to use Mouse Move with potentiometers. Each of the pots were controlling one x and y-axis.

I used the code below found from the Arduino documentation on Mouse Move

#include <Mouse.h>

const int xAxis = A0; //analog sensor for X axis
const int yAxis = A1; // analog sensor for Y axis

int range = 12; // output range of X or Y movement
int responseDelay = 2; // response delay of the mouse, in ms
int threshold = range/4; // resting threshold
int center = range/2; // resting position value
int minima[ ] = {
1023, 1023}; // actual analogRead minima for {x, y}
int maxima[ ] = {
0,0}; // actual analogRead maxima for {x, y}
int axis[ ] = {
xAxis, yAxis}; // pin numbers for {x, y}
int mouseReading[2]; // final mouse readings for {x, y}
void setup() {
Mouse.begin();
}

void loop() {

// read and scale the two axes:
int xReading = readAxis(0);
int yReading = readAxis(1);

// move the mouse:
Mouse.move(xReading, yReading, 0);
delay(responseDelay);
}

/*
reads an axis (0 or 1 for x or y) and scales the
analog input range to a range from 0 to <range>
*/

int readAxis(int axisNumber) {
int distance = 0; // distance from center of the output range

// read the analog input:
int reading = analogRead(axis[axisNumber]);

// of the current reading exceeds the max or min for this axis,
// reset the max or min:
if (reading < minima[axisNumber]) {
minima[axisNumber] = reading;
}
if (reading > maxima[axisNumber]) {
maxima[axisNumber] = reading;
}

// map the reading from the analog input range to the output range:
reading = map(reading, minima[axisNumber], maxima[axisNumber], 0, range);

// if the output reading is outside from the
// rest position threshold, use it:
if (abs(reading – center) > threshold) {
distance = (reading – center);
}

// the Y axis needs to be inverted in order to
// map the movemment correctly:
if (axisNumber == 1) {
distance = -distance;
}

// return the distance for this axis:
return distance;
}

Ultimately, I decided against using mouse move for this version and talked to some other people from the class. After speaking to Angela, she gave me the great idea of adding a reload and enter button. I used pins 7 and 8 to add a restart and start button.

Fabrication

Materials:

Two shoe boxes (one slightly larger)

Wire

Buttons for test

Conductive fabric

Electric tape

Felt

Canvas to cover the buttons

Acrylic paint

The first thing I did was test each button with wires. Then I connect a small piece of conductive fabric to each side for positive and negative. Then I made holes for each switch to come through the top of the boxes. The right, left, down arrows came out through 3 holes in the first, bottom box. The wires for the up arrow, restart, and start were fed through the top of the first box and then into the second.

Once everything was done with the circuits, I decided to paint the shoe boxes to look a little bit nicer (at least cover the brands).

After the second coat of paint had dried, I cut out 6 pieces of fabric using a canvas material to cover the soft buttons.

The final touch was just to paint the title of the game for a little fun. But it was late and I called the game Lunar Landing, instead of the real title, Lunar Lander. Forgive me, Atari.