20 April 2025

Team 16: Binoculars Controller

 By Final Team 16: Jordan Norton & Briah Bellamy

Controller



Description

·    Design:

Our controller is a pair of binoculars that players hold to play the game “A Short Hike”. “A Short Hike” is a game centered around exploring a mountain on the way up to its summit, encouraging players to tread off the beaten path along their journey, so this controller also fits the nature exploration narrative. When conceptualizing this controller, different exploration tools were used to connect to the game’s main narrative, and we found this design is the most cohesive. The conceptual model we chose, binoculars, is representative of hikers using them for exploration purposes, something highly recommended and encouraged for the player’s journey.

·       Input to Output mapping:

“A Short Hike” is relatively simple control-wise, with arrow keys for Movement, Z key for Jump/Fly/Glide, X key for Use Item/Interact, and Escape key for Menu/Inventory.

  • Arrow keys are mapped to the Bela Trill ring
  • Z key is mapped to forward swipe on the Bela Trill bar
  • X key is mapped to a backward swipe on the Trill bar
  • Escape key is mapped to gesturing with the Trill bar

·       Relationship between signifiers and feedback, and how all of that connects to the theme of the game:

Signifiers are the clues given to guide users along their experiences, such as doors labeled “Push” or “Pull” to guide people how they can be opened. In “A Short Hike”, this would include visual cues in-game to teach players how to play or that incentivize them to venture off the beaten path. Feedback informs users that they’re actually taking action in their experiences, usually by following signifiers such as doors opening after pushing or pulling them. For “A Short Hike”, the visual signifiers could change when proper actions are taken and, perhaps, there would be interesting new places and treasures to reward & further encourage the nature exploration.

Contributions

·    Jordan Norton:

  • Conceptual Controller Sketch & Prototype
  • Materials
  • Coding & Schematics

·    Briah Bellamy:

  • High Fidelity Controller Sketch
  • Blog Posts
  • 3D Modeling & Spray Painting

Schematic

Code

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

//Controller code for A Short Hike
//Jordan Norton and Briah Bellamy

Trill bar;      //Trill variable for the bar
Trill ring;     //Trill variable for the ring

//Bool variables for detecting if the sensors have been touched (used for resetting inputs after each loop)
bool barTouched = false;
bool ringTouched = false;

//Input variables for trill bar
int currentPoint = -1;
int point1 = -1;
int point2 = -1;
int point3 = -1;

//Input variables for trill ring (second finger is for receinving the "open menu" gesture)
int direction;
int secondFingerRing;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  CircuitPlayground.begin();

  int retBar = bar.setup(Trill::TRILL_BAR);     //Try to initialize bar
  int retRing = ring.setup(Trill::TRILL_RING);   //Try to initialize ring

  //Check trill bar initialization for errors
  if(retBar != 0) {
    Serial.println("failed to initialise trill bar");
    Serial.print("Error code: ");
    Serial.println(retBar);
  }

  //Check trill ring initialization for errors
  if(retRing != 0) {
    Serial.println("failed to initialise trill ring");
    Serial.print("Error code: ");
    Serial.println(retRing);
  }

  Keyboard.begin();
  
}

void loop() {
  // put your main code here, to run repeatedly:
  //Serial.print("In the loop");

  bar.read();   //Read the trill bar
  ring.read();  //Read the trill ring

  direction = map(ring.touchLocation(0), 0, 3600, 0, 7);
  //secondFingerRing = map(ring.touchLocation(1), 0, 3600, 0, 7);

  //Trill bar input
  if(bar.getNumTouches() > 0) {

    currentPoint = bar.touchLocation(0);

    if ( point1 == -1 ) {

      point1 = currentPoint;
    }

    if ( point2 == -1 ) {
      
      point2 = currentPoint;
    }

    point3 = currentPoint;

    //Acknowledge that the bar was touched
    barTouched = true;

    //Debounce delay
    delay(10);

    Serial.print("currentPoint is ");
    Serial.print(currentPoint);
    Serial.print("\n");
    Serial.print("point1 is ");
    Serial.print(point1);
    Serial.print("\n");
    Serial.print("point2 is ");
    Serial.print(point2);
    Serial.print("\n");

  }
  else if(barTouched) {

    if ( (point1 != -1) && (point2 != -1) ) {
      if ( point1 > ( point2 + 100 ) ) {

        Keyboard.press('z');

        currentPoint = -1;
        point1 = -1;
        point2 = -1;
        point3 = -1;
      }
      else if ( point1 < ( point2 - 100 ) ) {

        Keyboard.press('x');

        currentPoint = -1;
        point1 = -1;
        point2 = -1;
        point3 = -1;
      }
      else if ( (point3 < point1) && (point3 > -1) ) {

        Keyboard.press(KEY_ESC);

        currentPoint = -1;
        point1 = -1;
        point2 = -1;
        point3 = -1;
      }
    }

    Keyboard.release('z');
    Keyboard.release('x');
    Keyboard.release(KEY_ESC);
    Serial.println("Z released");
    Serial.println("X released");
    Serial.println("Escape released");

    //Acknowledge that the bar is no longer being touched
    barTouched = false;

  }

  //Trill ring input
  //When a direction is inputted, all keys but but the selected direction are released
  //This allows for 360 degrees of smooth movement where the player never has to take their finger off the trill ring
  if(ring.getNumTouches() > 0) {
    //South
    if (direction == 0) {
      Keyboard.press(KEY_DOWN_ARROW);
      Serial.println("Down pressed");

      Keyboard.release(KEY_UP_ARROW);
      Keyboard.release(KEY_RIGHT_ARROW);
      Keyboard.release(KEY_LEFT_ARROW);
    }

    //Southeast
    if (direction == 1) {
      Keyboard.press(KEY_DOWN_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      Serial.println("Down and right pressed");

      Keyboard.release(KEY_UP_ARROW);
      Keyboard.release(KEY_RIGHT_ARROW);
    }

    //East
    if (direction == 2) {
      Keyboard.press(KEY_LEFT_ARROW);
      Serial.println("Right pressed");

      Keyboard.release(KEY_UP_ARROW);
      Keyboard.release(KEY_RIGHT_ARROW);
      Keyboard.release(KEY_DOWN_ARROW);
    }

    //Northeast
    if (direction == 3) {
      Keyboard.press(KEY_LEFT_ARROW);
      Keyboard.press(KEY_UP_ARROW);
      Serial.println("Right and up pressed");

      Keyboard.release(KEY_RIGHT_ARROW);
      Keyboard.release(KEY_DOWN_ARROW);
    }

    //North
    if (direction == 4) {
      Keyboard.press(KEY_UP_ARROW);
      Serial.println("Up pressed");

      Keyboard.release(KEY_RIGHT_ARROW);
      Keyboard.release(KEY_DOWN_ARROW);
      Keyboard.release(KEY_LEFT_ARROW);
    }

    //Northwest
    if (direction == 5) {
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      Serial.println("Up and left pressed");

      Keyboard.release(KEY_DOWN_ARROW);
      Keyboard.release(KEY_LEFT_ARROW);
    }

    //West
    if (direction == 6) {
      Keyboard.press(KEY_RIGHT_ARROW);
      Serial.println("Left pressed");

      Keyboard.release(KEY_UP_ARROW);
      Keyboard.release(KEY_DOWN_ARROW);
      Keyboard.release(KEY_LEFT_ARROW);
    }

    //Southwest
    if (direction == 7) {
      Keyboard.press(KEY_RIGHT_ARROW);
      Keyboard.press(KEY_DOWN_ARROW);
      Serial.println("Left and down pressed");

      Keyboard.release(KEY_UP_ARROW);
      Keyboard.release(KEY_LEFT_ARROW);
    }

    //Acknowledge that the ring was touched
    ringTouched = true;

    //Debounce delay
    delay(10);
    
  }
  else if(ringTouched) {

    //Release all movement keys
    Keyboard.release(KEY_UP_ARROW);
    Keyboard.release(KEY_RIGHT_ARROW);
    Keyboard.release(KEY_DOWN_ARROW);
    Keyboard.release(KEY_LEFT_ARROW);
    Serial.println("Arrow key(s) released");

    //Acknowledge that the ring is no longer being touched
    ringTouched = false;
  }
}

Demonstration


  Open Ended Question:

How could we implement signifiers to better indicate controls without marking up the sensors?


No comments:

Post a Comment

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