20 November 2024

Team 5 - Donkey Kong Hat Controller

Controller Description


    The conceptual model for our controller drew inspiration from the hat item that can be found in the game Donkey Kong (1981). In the game, this item served to provide the player extra points to increase their score


    There are two types of input that the controller accepts: Movement from the two ultrasonic range sensors on the sides of the hat, and jumping from the circuit playground's accelerometer. Placing your hands in front of the ultrasonic sensors will move your character in a certain direction, moving your hand closer and farther from the sensor will also influence the character's direction.


    Though it may seem rather unorthodox, the signifiers for the controller are connected to its relation to the game. In order to get the character to move, a player must frantically move their hands up and down, similar to how Donkey Kong moves at the top in order to navigate their way up the tower. Additionally, the player must physically jump like the player character in order to jump over barrels


    These aspects of the controller are able to give the player a unique experience when it comes to controlling a game. Few games see the player control a character without holding something in their hands, and this controller asks them to control a game by (quite literally) using their head.


Question for peer review

How can the movement controls, based on hand distance from the sensors, be improved to make the experience feel more natural and easy for players to use?


Roles


Kel worked on the base code and tested its functionality, ensuring the sensors and controls were working properly. They also fixed any errors and handled the wiring to connect all the sensors. Additionally, Kel recorded and edited the video and provided the voiceover.


Thu contributed by building on Kel’s code and making modifications to accommodate design changes. She wrote the project descriptions, and acted as the demonstrator in the video. She also crafted the hat, including cutting holes and using tape and a glue gun to modify it for caging.


Controller Photo





Controller Schematic





Controller Code


#include <Adafruit_CircuitPlayground.h>
#include <Keyboard.h>
// Define ultrasonic sensor pins for directions and constants
const int trigPinLR = 6; // Trigger pin for left/right movement
const int echoPinLR = 12;  // Echo pin for left/right movement
const int trigPinFB = 9;  // Trigger pin for forward/backward movement
const int echoPinFB = 3; // Echo pin for forward/backward movement            
const int distanceCloseThreshold = 15;    // Distance threshold for closer threshold
const int distanceFartherThreshold = 25;  // Distance threshold for further threshold
const int distanceMaxThreshold = 38; //Maximum distance threshold we want the range sensors to detect
const int shakeThresh = 15;            // Threshold for detecting a shake to jump      


void setup() {
  // set up sensors + microphone
  Serial.begin (9600);
  CircuitPlayground.begin();
  //  Initialize trigger and echo pins as output and input, respectively
 // Initialize trigger and echo pins
  pinMode(trigPinLR, OUTPUT);
  pinMode(echoPinLR, INPUT);
  pinMode(trigPinFB, OUTPUT);
  pinMode(echoPinFB, INPUT);
  pinMode(CPLAY_SLIDESWITCHPIN, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(CPLAY_SLIDESWITCHPIN)) {
    // Measure distances from objects
    long distanceLR = echolocate(trigPinLR, echoPinLR); // For left/right
    long distanceFB = echolocate(trigPinFB, echoPinFB); // For forward/backward

    Serial.print(distanceLR);
    Serial.print("\t");
    Serial.println(distanceFB);

    //Shake detect for jumping//
    float shake = abs(CircuitPlayground.motionX()) +
                  abs(CircuitPlayground.motionY()) +
                  abs(CircuitPlayground.motionZ());
    if(shake > shakeThresh) {
       Keyboard.press(0x20); //press space to jump
      delay(100);            // Short delay to debounce
      Keyboard.release(0x20); // Release key
    }
   
  // Movement logic for up/down based on distance
    if (distanceFB <= distanceCloseThreshold) {
      Keyboard.press(KEY_UP_ARROW); // Press "up" when hand is closer
    } else if (distanceFB > distanceFartherThreshold) {
      Keyboard.press(KEY_DOWN_ARROW); // Press "down" when hand is further away
    }
    // Release arrow keys only if no movement is detected in either sensor
    if (distanceLR <= distanceCloseThreshold) {
      Keyboard.press(KEY_RIGHT_ARROW); // Press "right" when hand is closer
    } else if (distanceLR > distanceFartherThreshold) {
      Keyboard.press(KEY_LEFT_ARROW); // Press "left" when hand is further away
    }

    delay(100); // Add a short delay to debounce key presses
    Keyboard.releaseAll();
  }
}

long echolocate(int trigPin, int echoPin){
  //Define function-specific variables
  long distance, duration;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); // Measure echo return time
 // Determine the distance from the object (in centimeters, then return that value)
  distance = (duration / 2) / 29.1; // Distance in cm
  return distance;
}

Controller Demonstration


No comments:

Post a Comment

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