18 April 2021

Marble Ball Controller Final


The controller was intended to primarily rely on an orb for movement since the player

will be able to consciously understand how to move and forward.

Moving left to right however was a challenge to get functioning. Ideally, especially with this game,

sliding the ball left and right would be the best thing to do for optimal conveyance.

However complications with the soft pot hindered this idea thus leading to the idea of using tilt controls.

This idea was inspired by the Monkey Ball games where moving left and right would tilt the camera,

creating the illusion the the stage itself was moving.

This same idea was applied to jumping, in which tilting the controller upward will simulate

the action of jumping. Obvious constraints for how far the player can slide the ball left and right needed to be considered as well. The controller relies on the rotary encoder to simulate forward and backwards moving by reading

the 2 bit output of the encoder. This meant that the encoder wasn't analog, the encoder would only

output the bits based on which way it was rotated. This was enough though since keyboard inputs

didn't need to be analog. Ideally the fast the user rolls the ball the faster the player would go.

So simply calling the encoder function more often when the encoder was rotating was sufficient.

Since keyboard input could be treated as digital input for this game accelerometers could be treated

as such as well by giving the inputs rotation  threshold to reach to output a key output.

To help provide feedback for some of the controls, the CPE lights up to covey which tilt input was

last read. Feedback for moving the ball forward seemed unnecessary due to it being the most

active part of the controller demanding the most attention of the player. All this helps simulate

the experience rolling a marble, with some conveniences to help traversal through obstacles

manageable



#include <Keyboard.h> #include <Adafruit_CircuitPlayground.h> #include <Adafruit_Circuit_Playground.h> int encoderPin1 = A2; //pin for encoder bit reading int encoderPin2 = A3; //pin for encoder bit reading volatile int lastEncoded = 0; volatile long encoderValue = 0; volatile long tempValue = 0; long lastencoderValue = 0; int lastMSB = 0; int lastLSB = 0; void setup() { CircuitPlayground.begin(); pinMode(encoderPin1, INPUT); pinMode(encoderPin2, INPUT); digitalWrite(encoderPin1, HIGH); //turn pin resistor on digitalWrite(encoderPin2, HIGH); //turn pin resistor on Serial.begin (9600); } void loop(){ float controllerX = CircuitPlayground.motionX(); float controllerZ = CircuitPlayground.motionZ(); //checks for right accelerometer tilt for right output if(controllerX >= 5 && digitalRead(CPLAY_SLIDESWITCHPIN)) { Keyboard.press(215); //change color CircuitPlayground.setPixelColor(9,10,30,50); CircuitPlayground.setPixelColor(8,10,30,50); CircuitPlayground.setPixelColor(7,10,30,50); CircuitPlayground.setPixelColor(6,10,30,50); CircuitPlayground.setPixelColor(5,10,30,50); CircuitPlayground.setPixelColor(4,10,30,50); CircuitPlayground.setPixelColor(3,10,30,50); CircuitPlayground.setPixelColor(2,10,30,50); CircuitPlayground.setPixelColor(1,10,30,50); } //checks for left accelerometer tilt for left output else if(controllerX <= -5 && digitalRead(CPLAY_SLIDESWITCHPIN)) { Keyboard.press(216); //change color CircuitPlayground.setPixelColor(9,100,30,50); CircuitPlayground.setPixelColor(8,100,30,50); CircuitPlayground.setPixelColor(7,100,30,50); CircuitPlayground.setPixelColor(6,100,30,50); CircuitPlayground.setPixelColor(5,100,30,50); CircuitPlayground.setPixelColor(4,100,30,50); CircuitPlayground.setPixelColor(3,100,30,50); CircuitPlayground.setPixelColor(2,100,30,50); CircuitPlayground.setPixelColor(1,100,30,50); } //release all press keys when controller is flat. else { Keyboard.releaseAll(); } //jump key checking if(controllerZ <= 7 && digitalRead(CPLAY_SLIDESWITCHPIN)) { Keyboard.write('z'); Serial.println("jump pressed"); } //detecting encoder rotation if(digitalRead(encoderPin1) == 0 || digitalRead(encoderPin2) == 0) { updateEncoder(); } delay(10); } void updateEncoder(){ int MSB = digitalRead(encoderPin1); //MSB = most significant bit int LSB = digitalRead(encoderPin2); //LSB = least significant bit Serial.println("Function called"); int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) { Keyboard.press(218); encoderValue++; } if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) { Keyboard.press(217); encoderValue--; } lastEncoded = encoded; //store this value for next time }


   

No comments:

Post a Comment

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