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!
//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.