Controller Photo
Controller Description
This project is for the game Undertale. It focuses on adapting the main villain of the game- flowey as a full controller. We used a lot of the flower theme with our photo resistors functioning as petals that absorb light. We wanted to take the theme of the game into account too so we decided to go more into the soul angle. A soul or a person feels something in one way or another. So we added both touch and sound into the controller. The pressure sensor was our confirm key and the CPE's mic was our cancel key. Whenever someone clapped it got registered. Our controller itself reacts to everything you do in a physical setting, almost like something alive.
The input-to-output mapping utilizes four photoresistors to control movement. By covering, the player creates a shadow that maps to the Up, Down, Left, or Right arrow keys. For dialogue and interaction, a pressure sensor and a potentiometer are used. The pressure sensor maps to the 'Z' key for the confirm button, while the potentiometer serves as a macro for 'X' to skip dialogue. Finally, a microphone sensor maps a loud sound like a clap to the 'X' key for cancelling or opening the menu.
In this design, the signifiers are these elements coming together in one design. Shadows allow for movement, potentiometer allows for text skipping, and the clap not only cancels but gives menu access. Like mentioned before this controller responds to any player feedback in an organic way.
What do you think of the potentiometer as a modern dialogue skipper that most RPGs have nowadays but being used as a macro for a game like Undertale that came out in 2015?
Controller Schematic
#include <Keyboard.h>#include <Adafruit_CircuitPlayground.h>//Pin Definitionsconst int potPin = A1; //Potentiometer to A1 (Auto z/x)const int pinUp = A2; // Photoresistor to A2 (W)const int pinRight = A3; // Photoresistor to A3 (D)const int pinDown = A4; // Photoresistor to A4 (S)const int pinLeft = A5; // Photoresistor to A5 (A)const int pinZ = A6; // Pressure Sensor to A6 (Z)//Treshold stuffconst int lightTreshold = 150;const int pressureTreshold = 200;const int potTreshold = 10;const int soundTreshold = 85;//Tracking variables to fix the spam stuffbool stateUp = false;bool stateLeft = false;bool stateDown = false;bool stateRight = false;bool stateZ = false;//Clap variablesunsigned long lastClapTime = 0;const unsigned long clapCooldown = 500; //cooldown to prevent clap spam// Variables for the potentiometer delayunsigned long lastPotActionTime = 0;const unsigned long potInterval = 50; // Delay for the potentiometer spambool potIsPressed = false;void setup(){Serial.begin(9600);CircuitPlayground.begin();Keyboard.begin();}void loop(){// 1. Read sensorsint valUp = analogRead(pinUp);int valRight = analogRead(pinRight);int valDown = analogRead(pinDown);int valLeft = analogRead(pinLeft);int valZ = analogRead(pinZ);int potVal = analogRead(potPin);// 2 Movement//Wbool currentUp = (valUp < lightTreshold);if (currentUp && !stateUp){Keyboard.press(KEY_UP_ARROW);stateUp = true;}else if (!currentUp && stateUp){Keyboard.release(KEY_UP_ARROW);stateUp = false;}//Abool currentLeft = (valLeft < lightTreshold);if (currentLeft && !stateLeft){Keyboard.press(KEY_LEFT_ARROW);stateLeft = true;}else if (!currentLeft && stateLeft){Keyboard.release(KEY_LEFT_ARROW);stateLeft = false;}//Sbool currentDown = (valDown < lightTreshold);if (currentDown && !stateDown){Keyboard.press(KEY_DOWN_ARROW);stateDown = true;}else if (!currentDown && stateDown){Keyboard.release(KEY_DOWN_ARROW);stateDown = false;}//Dbool currentRight = (valRight < lightTreshold);if (currentRight && !stateRight){Keyboard.press(KEY_RIGHT_ARROW);stateRight = true;}else if (!currentRight && stateRight){Keyboard.release(KEY_RIGHT_ARROW);stateRight = false;}// 3 confirm (z) Checks if the sensor is pressedbool currentZ = (valZ < pressureTreshold);if (currentZ && !stateZ){Keyboard.press('z');stateZ = true;}else if (!currentZ && stateZ){Keyboard.release('z');stateZ = false;}// 4 Cancel (X)float sound = CircuitPlayground.mic.soundPressureLevel(10);if (sound > soundTreshold && (millis() - lastClapTime > clapCooldown)){Keyboard.write('x'); //millis reset the timer and .write presses it instantlylastClapTime = millis();//TO TEST CircuitPlayground.setPixelColor(0, 0, 255, 0); delay(50); CircuitPlayground.clearPixels(); this flashes a light for the mic}// 5 Potentiometer(Dialogue Skip "Z" and "X")if (potVal > potTreshold){if (millis() - lastPotActionTime > potInterval){if (!potIsPressed){Keyboard.press('x'); // skip text typingpotIsPressed = true;}else{Keyboard.release('x');potIsPressed = false;}lastPotActionTime = millis();}}else if (potIsPressed){Keyboard.release('x');potIsPressed = false;}delay(10); // Small delay for everything to loop properly}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.