26 April 2026

Final Project Team 8: Hidden Folks Game Controller


Our game controller is made to reflect the theme of the game Hidden Folks. In the game, players must search through mini landscapes to find certain people, things, or objects. The game, which consists of a black and white color palette, has simple inputs, consisting of zoom in/zoom out buttons, a select button, and a pan button to move across the landscape.Due to the overall simplistic nature of the game, we chose to carry the theme into the controller by creating a treasure map controller. The controller consists of two cylinders and a middle portion, which simultaneously give the player somewhere to grab onto and also visually represent the two scroll portions of an ancient map. The middle portion is decorated overtop with a hand-drawn map, integrating both a light sensor and a touchpad into the layout.


There are a total of 4 inputs: a light sensor, a potentiometer, a touchpad sensor, and the circuit's tilt mechanism. The light sensor replaces the "click" option for the game, which allows players to select objects within the landscape. Because the player is searching for objects/people, the "X marks the spot" on the controller signifies clicking to find/search. The potentiometer replaces the zoom in/zoom out function, which allows players a closer look at the landscape. The touchpad sensor replaces the click and hold that allows players to move around the level as needed. It is shown as a square within the map to signify the search, having to press to apply pressure and look around. The tilt gives motion to move the mouse around the screen. It signifies how you have to carefully search a map such as needing to move it around to find what you need.


Peer Review Feedback: Based on the inputs we chose and the theme of the controller, are there alternative inputs that would have worked better or should have been added to have a more cohesive design?

Controller Image:




Video:


Schematic:


Code:

#include <Mouse.h>
#include <Adafruit_CircuitPlayground.h>

// ---------------- PINS ------------------
// making variables for each pin and what it connects to on the CPE
const int fsrPin = A1;
const int lightSensorPin = A2;
const int potPin = A3;

// ---------------- STATES ----------------
// variables used for keeping info to reference later
bool leftHeld = false;
int lastPotValue = 0;

// ---------------- SETUP -----------------
void setup() {
  // circuit and mouse tracking, along with the 3 analog inputs
  Serial.begin(9600);
  CircuitPlayground.begin();
  Mouse.begin();
  pinMode(fsrPin, INPUT);
  pinMode(potPin, INPUT);
  pinMode(lightSensorPin, INPUT);
  lastPotValue = analogRead(potPin);
}

// ---------------- LOOP FUNCTIONS ------------------
void loop() {
  // repeated functions
  handleSensors();
  handleTilt();
  handlePot();
  //lightCheck();
  //fsrCheck;
 
  delay(10);
}

/*void lightCheck() {
  // checking light values
  int lightVal = analogRead(lightSensorPin);
  Serial.print("Light Sensor Value: ");
  Serial.println(lightVal);

  delay(200);
}
*/

/*void fsrCheck() {
  // checking pressure values
  int fsrReading;
  fsrReading = analogRead(fsrPin);
  Serial.print("Analog Reading = ");
  Serial.print(fsrReading);

  delay(200);
}
*/

// ---------------- SENSOR HANDLING ----------------
void handleSensors() {
  // variables to get readings on each sensor / how it activates
  int fsrVal = analogRead(fsrPin);
  int lightVal = analogRead(lightSensorPin);
  bool fsrPressed = fsrVal > 500;              // pressure pad threshold
  bool lightTriggered = lightVal < 600;        // darkness threshold

  // ---------- PRESSURE PAD = HOLD ------------
  // hold down mouse when fsr pressure increases
  if (fsrPressed && !leftHeld) {
    Mouse.press(MOUSE_LEFT);
    leftHeld = true;
  }
  else if (!fsrPressed && leftHeld) {
    Mouse.release(MOUSE_LEFT);
    leftHeld = false;
  }

  // ---------- LIGHT SENSOR = PRESS ----------
  // light sensor activating in darkness presses left click
  static bool lastLightState = false;
  if (lightTriggered && !lastLightState) {
    Mouse.click(MOUSE_LEFT);
  }
  lastLightState = lightTriggered;
}

// ---------------- TILT ----------------
// tilt movement around the screen, adjusting speed as needed
void handleTilt() {
  float x = CircuitPlayground.motionX();
  float y = CircuitPlayground.motionY();
  int moveX = -x * 2;
  int moveY = y * 2;
  // dead zone
  if (abs(moveX) < 2) moveX = 0;
  if (abs(moveY) < 2) moveY = 0;
  Mouse.move(moveX,moveY);
}

// ---------------- POTENTIOMETER ----------------
void handlePot() {
  int potValue = analogRead(potPin);

  static int potFiltered = 0;
  potFiltered = (potFiltered * 3 + potValue) / 4;

  int diff = potFiltered - lastPotValue;

  if (abs(diff) > 5) {
    int scrollAmount = diff / 10;

    if (!leftHeld) {
      Mouse.move(0, 0, scrollAmount);
    }

    lastPotValue = potFiltered;
  }
}

No comments:

Post a Comment

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