Watergirl Controller
Photo
Description
The conceptual model of the design is a controller modeled after the main characters in the flash game Fireboy and Watergirl. The high-fidelity prototype is specifically modeled after Watergirl. The 3D printed controller has a space in one eye for the potentiometer and the other eye has small holes to signifiy a microphone in the Circuit Playground Express. On the body, there's an opening to place an external switch to be the arm of the model. By flipping the switch, the player gets to choose between playing as Watergirl or Fireboy. This is important because the game requires both characters to be played in order to complete the levels. The direction the potentiometer is turned decides on whether the player moves left or right by pressing down A Key or Left Arrow Key to go left or pressing down D Key or Right Arrow Key to go right. The microphone gets an average of the sound levels in the room, and when there's a sudden spike, the W Key or Up Arrow Key gets pressed down and the player jumps. This mapping between the inputs and outputs enhance the immersive experience by connecting the physical controller to the game's theme.
Schematic
Code
//Chelsea Soto and Molly Guinn#include <Keyboard.h>#include <KeyboardLayout.h>#include <Keyboard_da_DK.h>#include <Keyboard_de_DE.h>#include <Keyboard_es_ES.h>#include <Keyboard_fr_FR.h>#include <Keyboard_hu_HU.h>#include <Keyboard_it_IT.h>#include <Keyboard_pt_PT.h>#include <Adafruit_CircuitPlayground.h>#include <Adafruit_Circuit_Playground.h>#include <math.h>// assign pinsconst int potent = A4; // potentiometer middle pinconst int eSwitch = A7; // external switch middle pinconst int redLED = A3;const int blueLED = A2;// constant variablesconst int debounce = 100; // Debounce time in ms for each sound checkconst int threshold = 5; // Sound threshold for jumpingconst int valueNum = 10; // Number of values to calculate average sound levelunsigned long lastAverageTime = 0; // Timer for average calculationconst unsigned long averageInterval = 15000; // Time in ms between average calculationsfloat baselineAverage = 0.0; // Store initial baselinevoid setup() {// initialize librariesCircuitPlayground.begin();Keyboard.begin();// serial initializationSerial.begin(9600);// initialize pinspinMode(potent, INPUT); // potentiometerpinMode(eSwitch, INPUT_PULLUP); // external switchpinMode(redLED, OUTPUT); // red LED for FireboypinMode(blueLED, OUTPUT); // blue LED for Watergirl// Set initial LED states to offdigitalWrite(redLED, LOW);digitalWrite(blueLED, LOW);// Calculate initial baselinebaselineAverage = checkAverage(valueNum);}void loop() {// Check if the slide switch is onif (digitalRead(CPLAY_SLIDESWITCHPIN)) { // for debug purposes only// Check if it's time to recalculate the baseline averageif (millis() - lastAverageTime >= averageInterval) {baselineAverage = checkAverage(valueNum);lastAverageTime = millis();}// Check switch state for mode selectionbool mode = digitalRead(eSwitch) == LOW;// Potentiometer value checkint potValue = analogRead(potent);// FIREBOY CONTROLSif (mode) {// LEDsdigitalWrite(redLED, HIGH); // Turn on red LED for FireboydigitalWrite(blueLED, LOW); // Ensure blue LED is off// Movementif (potValue < 462) { // Move rightKeyboard.press(KEY_RIGHT_ARROW);Keyboard.release(KEY_LEFT_ARROW);} else if (potValue > 562) { // Move leftKeyboard.press(KEY_LEFT_ARROW);Keyboard.release(KEY_RIGHT_ARROW);} else { // No movementKeyboard.release(KEY_LEFT_ARROW);Keyboard.release(KEY_RIGHT_ARROW);Serial.println("not moving");}// Sound check for jumpingfloat currentValue = CircuitPlayground.soundSensor();float difference = baselineAverage - currentValue;if (difference >= threshold) {Keyboard.press(KEY_UP_ARROW); // Jump} else {Keyboard.release(KEY_UP_ARROW); // Stop jump}}// WATERGIRL CONTROLSelse {// LEDsdigitalWrite(blueLED, HIGH); // Turn on blue LED for WatergirldigitalWrite(redLED, LOW); // Ensure red LED is off// Movementif (potValue < 462) { // Move rightKeyboard.press('d');Keyboard.release('a');} else if (potValue > 562) { // Move leftKeyboard.press('a');Keyboard.release('d');} else { // No movementKeyboard.release('a');Keyboard.release('d');Serial.println("not moving");}// Sound check for jumpingfloat currentValue = CircuitPlayground.soundSensor();float difference = baselineAverage - currentValue;if (difference >= threshold) {Keyboard.press('w'); // Jump} else {Keyboard.release('w'); // Stop jump}}// Small delay to avoid switch debounce issuesdelay(50);}}// Function to check the average sound levelfloat checkAverage(int valueNum) {float valueSum = 0.0;unsigned long lastDebounceTime = 0;int count = 0;while (count < valueNum) {if (millis() - lastDebounceTime >= debounce) {lastDebounceTime = millis();float currentValue = CircuitPlayground.soundSensor();valueSum += currentValue;count++;Serial.print("Current sound level: ");Serial.println(currentValue);}}float average = valueSum / valueNum;Serial.print("AVERAGE SOUND LEVEL: ");Serial.println(average);return average;}
Video
Here is the YouTube video showing that the code is works during the low-fidelity prototype.
Right now we're having issues getting the high-fidelity prototype to work with the new controller casing and wires. We have an idea where the issue could be and are planning to gut it and restart the process for Tuesday.
UPDATE: 11/21/2024
We were able to fix it after class!
Questions
1. Should the controller be more modeled after the characters (flames or water drop) or just be different colors?
The design is meant to have two controllers, but because of time frame
there is only one, being red and blue respective to the default
controller characters.
2. What is another way we could achieve the left/right and jump movement, without making a Wii move controller?
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.