Jessica Harrison and Chandler Crum
Controller:
Description:
For our project, we created a custom game controller for the game Suika Jelly using the Circuit Playground Express and a potentiometer. To play Suika Jelly, the player must strategically drop different fruits into a jar. Going into this project, we wanted to design a physical interface that helped the player feel more connected to the movement and placement of fruit. We decided to go with a watermelon slice because it is intuitive to hold and its half-circle shape can be manipulated almost like a steering wheel.
To use the controller, the player uses natural gestures that mirror actions that happen on the screen. Using tilt controls, the player can tilt the slice of watermelon left or right to trigger the “A” and “D” keys, positioning their fruit left or right in the game. Turning the potentiometer knob all the way to the right triggers the “space” key, dropping the fruit into place. If the potentiometer is all the way to the left, the “esc” key is triggered, pausing the game. After earning a certain amount of points, the game will enter “shake” mode. Usually, the player would use the WSAD keys to shake the jar up/down or left/right. Using our controller, the player can just shake the watermelon controller to trigger the “ctrl” key that enables shake mode, and continue moving it to shake the jar up/down or left/right.
The affordances of our controller are that the player can hold it how they normally would hold a slice of watermelon, and they can see that there is a knob on top that they can manipulate. A major signifier in our design is that the shape of the controller intuitively implies directional movement. The potentiometer only uses the highest and lowest value readings, so it’s not very easy to accidentally trigger the pause or shake menu. We used serial output to fine tune the input values.
Our controller creates a more immersive experience for Suika Jelly players, because most of the gestures, such as “shaking,” mimic exactly what is happening in-game. Our controller encourages movement and brings a new layer of fun that is concise with the game’s aesthetic and mechanics.
Questions:
1. What would be an interesting cover or replacement for the knob at the top of the controller?
2. Do you feel that this would be more immersive than using a traditional keyboard?
Schematics:
Code:
#include <Adafruit_CircuitPlayground.h>#include <Keyboard.h>const int slideSwitch = 7; // Establish slide switch (D7)const int potPin = A1; // Potentiometer to A1const int potRightMax = 900; // Potentiometer max right valueconst int potLeftMax = 0; // Potentiometer max left valueconst float shakeMax = 10.0; // Shake sensitivity, can be adjusted if neededvoid setup() {Serial.begin(9600); // Initialize serial monitorCircuitPlayground.begin(); // Initialize CPEpinMode(slideSwitch, INPUT_PULLUP); // Initialize on/off switchKeyboard.begin(); // Initialize keyboard}void loop() {bool switchState = digitalRead(slideSwitch) == LOW; // Check if switch is on/offif (switchState) { // If switch is onSerial.println("Board is online!"); // Print board statusfloat x = CircuitPlayground.motionX(); // Read X-axis motionfloat y = CircuitPlayground.motionY(); // Read Y-axis motionfloat z = CircuitPlayground.motionZ(); // Read Z-axis motionSerial.print("X: "); // Print X-axis valueSerial.println(x);Serial.print("Y: "); // Print Y-axis valueSerial.println(y);Serial.print("Z: "); // Print Z-axis valueSerial.println(z);float shakeValue = sqrt(x * x + y * y + z * z); // Calculate motion values to detect if shakingif (shakeValue > shakeMax) { // If current shake value is above the maxium, is shakingSerial.println("Shaking!"); // Print when shakingKeyboard.press(KEY_LEFT_CTRL); // Press left-ctrl key} else { // No longer shakingKeyboard.release(KEY_LEFT_CTRL); // Release left-ctrl key}if (x < -3) { // Check if tilting leftSerial.println("Moving left!"); // Print when moving leftKeyboard.press('a'); // Press a key}else if (x > 3) { // Check if tilting rightSerial.println("Moving right!"); // Print when moving rightKeyboard.press('d'); // Press d key}else { // Check if neutral positionSerial.println("No movement!"); // Print when not movingKeyboard.release('a'); // Release a keyKeyboard.release('d'); // Release d key}if (y < -3) { // Check if tilting upSerial.println("Moving up!"); // Print when moving upKeyboard.press('w'); // Press w key}else if (y > 3) { // Check if tilting downSerial.println("Moving down!"); // Print when moving downKeyboard.press('s'); // Press s key}else { // If no axis thresholds are metSerial.println("No movement!"); // Print when not movingKeyboard.release('w'); // Release w keyKeyboard.release('s'); // Release s key}int potValue = analogRead(potPin); // Read potentiometer valueSerial.print("Potentiometer Value: "); // Print potentiometer valueSerial.println(potValue);if (potValue > potRightMax) { // Drop fruit when turned fully rightSerial.println("Dropped Fruit!"); // Print when fruit is droppedKeyboard.press(' '); // Press spacebar}else {Keyboard.release(' '); // Release spacebar}if (potValue == potLeftMax) { // Pause game when potentiometer at lowest valueSerial.println("Paused!"); // Print when pausedKeyboard.press(KEY_ESC); // Press escape key}else {Keyboard.release(KEY_ESC); // Release escape key}}else {Serial.println("Board is offline!"); // Print board statusKeyboard.releaseAll(); // Release all keys}delay(50); // Delay for input stability}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.