23 April 2026

Team 2: Temple Run

Our Controller:



Description:

Our controller is a stylish way to play the game Temple Run. The design of the controller mimics the look of the pathways that you run through in the game, and the guy that our controller uses is designed after the guy in the game. We wanted our controller to be highly themed to create a unique experience for each person that uses it. 

The technical aspects of the controller consist of 3 photoresistors, 1 range sensor, and 1 button. The 3 photoresistors are mapped to the inputs for left, right, and slide, while the range sensor is mapped to the jump key. The button is simply used to start the game and activate your power ups when you unlock those. The code for the game simply detects in the range or light level is within a certain threshold and presses the assigned button if it is. You simply hover the guy figure over the photoresistor or range sensor to simulate this input. 

Since you are actively moving the figure around the controller, it feels as though you are physically controlling the character in the game, creating a unique controller experience.

There were certain design intentions that were not able to be translated and/or did not come out as intended. These include: the size of the controller came out smaller than anticipated and the range sensor was intended to detect if the figure was lifted off of the sensor rather than the other way around.

Do you feel that the controller would be better with the ability to lift the figure as it was originally intended, or does it not make too much of a difference?

Schematic:



Project Code:

#include <Keyboard.h>
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

//Initializing Variables
#define startButton 1

#define trigPin 9
#define echoPin 6
int disThreshold = 60;

const int photoLeft = A3;
const int photoRight = A4;
const int photoSlide = A6;
const int debounce = 200;

int lumoLeft;
int lumoRight;
int lumoSlide;
int lumoThreshold = 200;

void setup() {
  //Basic setup for code
  Serial.begin(9600);
  CircuitPlayground.begin();
  Keyboard.begin();
  delay(1000);

  //Initializing pin modes
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(startButton, INPUT);
}

void loop() {
  //Calling functions that store the code
  startButtonInputCheck();
  jumpInputCheck();
  leftInputCheck();
  rightInputCheck();
  slideInputCheck();

  //Delay between checks
  delay(150);
}

//Start button function
void startButtonInputCheck() {
  if(digitalRead(startButton) == HIGH) {
    Keyboard.write(' ');
    Serial.println("START"); //For debug/testing
    delay(debounce);
  }
}

//Left input function
void leftInputCheck() {
  lumoLeft = analogRead(photoLeft);
 
  if(lumoLeft < lumoThreshold) {
    Keyboard.write('A');
    Serial.println("LEFT"); //For debug/testing
    delay(debounce);
  }
}

//Right input function
void rightInputCheck() {
  lumoRight = analogRead(photoRight);
 
  if(lumoRight < lumoThreshold) {
    Keyboard.write('D');
    Serial.println("RIGHT"); //For debug/testing
    delay(debounce);
  }
}

//Slide input function
void slideInputCheck() {
  lumoSlide = analogRead(photoSlide);
 
  if(lumoSlide < lumoThreshold) {
    Keyboard.write('S');
    Serial.println("SLIDE"); //For debug/testing
    delay(debounce);
  }
}

//Jump input function
void jumpInputCheck() {
  //Code for range sensor
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.1715;

  //Printing distance in serial monitor for tracking and debugging
  Serial.println(distance);

  //Distance check for input
  if(distance < disThreshold) {
    Keyboard.write('W');
    Serial.println("JUMP"); //For debug/testing
    delay(debounce);
  }
}

Video Demonstration:



No comments:

Post a Comment

Note: Only a member of this blog may post a comment.