21 April 2025

WEBFISHING Hat Controller: Team 21

 WEBFISHING Hat: Team 21

Our Bucket Hat Controller for the game WEBFISHING is designed to be an extension of the self, where the player can truly feel a part of this world where they can socialize and fish. The most apparent part of this design is the Bucket Hat wearable component.

We have mapped the tilting direction of your head to the movement of either your in-game character, or with a toggle of the light sensor, the movement of your mouse for menu-navigation. We chose to use a light sensor instead of a standard button, as this input will be on top of the users head and no longer visible. The light sensor required users to be less precise than they needed to with a button, making it significantly more reliable when worn on top of your head.

For camera control, WEBFISHING has an orbiting camera with a third-person view of the player. In order to create an input for this, we chose to use a rotary encoder, with the rotation of the knob being directly mapped to the mouse when not in a menu.

The most important mechanic in WEBFISHING however, is undoubtedly the fishing. Now, when fishing in real life, you truly do have to pour your all into casting your reel. It takes a semblance of effort built up from deep inside, expelling out of you in one sudden burst in order for you to succeed. For this crucial task, our priority was having the player feel this sense of urgency and personal connection when they cast their reel.

It is for this reason we chose to go with a microphone as our trigger for casting in WEBFISHING. While it does require a little humility the first time, as you yell into the microphone, you simulate the same emotional build-up that you do as you when you fish in real life!

In what way could we make this controller more absurd to use?



//libraries
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>
#include <Keyboard.h>
#include <KeyboardLayout.h>
#include <Mouse.h>
#include <Rotary.h>

//Pin Names
#define RotaryOutputA A2
#define RotaryOutputB A3
#define MicInput A1

float accelX, accelY;
float accelSensitivity = 5;
unsigned long startMillis;
unsigned long rotMillis;
unsigned long menuMillis;
int xMouse = 0;
int yMouse = 0;
int peakToPeak, signalMin, signalMax, sample;
int currentRotA, lastRotA, mouseGo;
bool menuActive = false;
bool mouseDown = false;
Rotary r = Rotary(RotaryOutputA, RotaryOutputB);

void setup() {
  //buttons for testing if needed
  //pinMode(CPLAY_RIGHTBUTTON, INPUT);
  //pinMode(CPLAY_LEFTBUTTON, INPUT);
 

  CircuitPlayground.begin();
  CircuitPlayground.setAccelRange(LIS3DH_RANGE_2_G);
  Serial.begin(9600);
  Mouse.begin();

    //Testing pins
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A1, INPUT);
  pinMode(CPLAY_LIGHTSENSOR, INPUT);

  r.setChangedHandler(rotate);
  r.setLeftRotationHandler(showDirection);
  r.setRightRotationHandler(showDirection);
  lastRotA = r.getPosition();
  rotMillis = millis();
}

void loop() {
  // put your main code here, to run repeatedly:
  if(CircuitPlayground.slideSwitch()){
    //set up accelerometer data
    accelX = CircuitPlayground.motionX();
    accelY = CircuitPlayground.motionY();

    if (menuActive == false){
      //uses accel to control WASD if menus inactive
      accelX = map(accelX, 10, -10, -2,3);
      accelY = map(accelY, 10, -10, -2,3);

      if (accelX < 1 && accelX > -1){
        Keyboard.release('a');
        Keyboard.release('d');
      }
      else if (accelX >= 1){
        Keyboard.press('d');
      }
      else if (accelX <= -1){
        Keyboard.press('a');
      }

      if (accelY < 1 && accelY > -1){
        Keyboard.release('w');
        Keyboard.release('s');
      }
      else if (accelY >= 1){
        Keyboard.press('w');
      }
      else if (accelY <= -1){
        Keyboard.press('s');
      }
    }
    else{
      //uses accel to control mouse if menus active
      accelX = map(accelX, 10, -10, -100, 101);
      accelY = map(accelY, 10, -10, -100, 101);

      Mouse.move(accelX, accelY);
    }
     
    //set up sound data
    startMillis = millis();
    peakToPeak = 0;
    signalMax = 0;
    signalMin = 1024;

    //interpret sound data for 50 millis
    while (millis()-startMillis < 50){
      sample = analogRead(MicInput);
      if (sample > signalMax){
        signalMax = sample;
      }
      if (sample < signalMin){
        signalMin = sample;
      }
    }
    peakToPeak = signalMax - signalMin;

    //control left mouse button with sound data
    if (peakToPeak >= 570){
      Mouse.press();
      mouseDown = true;
      //Serial.print(peakToPeak);
      //Serial.print(" ");
      //Serial.print(sample);
      //Serial.println(" Clicked Mouse with Mic");
    }
    else if (peakToPeak < 570 && mouseDown == true){
      Mouse.release();
      mouseDown = false;
      //Serial.print(peakToPeak);
      //Serial.print(" ");
      //Serial.print(sample);
      //Serial.println(" Released Mouse");
    }

    //control cursor and right mouse button with rotary encoder
    r.loop();
    currentRotA = r.getPosition();
    if (currentRotA != lastRotA && (millis()-rotMillis > 250)){
      rotMillis = millis();
      lastRotA = currentRotA;
      if(r.directionToString(r.getDirection()) == "LEFT"){
        mouseGo = -40;
      }
      else{
        mouseGo = 40;
      }

      Mouse.press(MOUSE_RIGHT);
      Mouse.move(mouseGo, 0);
      Mouse.release(MOUSE_RIGHT);
      Serial.print("Mouse goes: ");
      Serial.println(r.directionToString(r.getDirection()));
    }

    while (millis()-rotMillis < 250){
      currentRotA = r.getPosition();
      lastRotA = currentRotA;
    }

   
    //toggles menus and tab key with low light sensor value
    if (analogRead(CPLAY_LIGHTSENSOR) < 15 && (millis()-menuMillis > 1000)){
      menuMillis = millis();
     
      menuActive = !menuActive;
      //Serial.println(menuActive);

      Keyboard.press(KEY_TAB);
      Keyboard.release(KEY_TAB);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
    }  
                                                                                                                                             
  }
  else{
    Keyboard.releaseAll();
    Mouse.release();
  }
}

// on change
void rotate(Rotary& r) {
   Serial.println(r.getPosition());
}

// on left or right rotattion
void showDirection(Rotary& r) {
  Serial.println(r.directionToString(r.getDirection()));
}

No comments:

Post a Comment

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