18 April 2021

Vecter - Gryo Band - Game Controller


    My controller is for a game called Vecter. It is a runner-shooter arcade style game with a simple premise: drive forward, and don’t run into obstacles.



    With my controller, I want to turn the player's hand into the hovercraft that you play as. As this is a fast-paced game, mapping should be intuitive and feedback should instantaneous. The design resembles the in-game ship to reinforce this idea. You should be able to put on the controller a quickly learn how it operates. If you understand how a quad-copter or helicopter moves. It's should be obvious how to operate the device. As you tilt you hand to the side, the ship on-screen tilts simultaneously as it leans into a strafe. Tilting forward, like that of a quad-copter, causes you to accelerate. Lean further to boost. As a gesture-based device, the signifiers are a combination of prior knowledge and immediate on-screen feedback. With strong, obvious, mapping the player should quickly be able to develop the muscle memory to use the device at a high level. While looking at the controller is opposite the goal, there is some additional feedback for strafing where only the NeoPixels on the corresponding side will light up. The is a visual design feature alone.

    I’ve primarily utilized the CPE’s accelerometer to detect the x and y axis of your hand and mapped various tilting angles to the correlating inputs (WASD keyboard-only format.) Tilting left or right makes the vehicle strafe left or right ('a' and 'd.') In Vecter, rarely do you want to stop accelerating, so I made acceleration ('w') toggle on upon tilting forward for the first time, which only toggles off when tilting back to brake. This allows you to keep your hand in a more comfortable position while still playing the game optimally. Tilting further forward will activate a boost ('ctrl'.) And lastly, pinch you fingers to continuously fire ('space.')

Question:

I believe the mapping is intuitive enough to not require directions, and that one could figure out how the controller works in a few minutes of play. However, there is some innate bias since I already know all the functions well. Are there any elements of the controller's functions that should be signified on the controller itself?


Schematic:


Code:

/* 
 *  Custom Controller Final Project
 *  Gyro Band - Cameron Friday
*/

#include <Keyboard.h>
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

//pin used for shooting control
const int shootPin = A6;
int i = 0;

void setup() {
  //Initialize CPE and Keyboard output
  Serial.begin(9600);
  CircuitPlayground.begin();
  Keyboard.begin();
  
  //read shooting pin
  pinMode(shootPin, OUTPUT);
  digitalWrite(shootPin, HIGH);

  //Startup animation
  for(i = 0; i < 10; i++)
    {
      CircuitPlayground.setPixelColor(i, 82, 15, 82);
      delay(200);
    }
  delay(1000);
}

void loop() {
  //read accelerometer x and y
  float x = CircuitPlayground.motionX();
  float y = CircuitPlayground.motionY();
  Serial.print(x);
  Serial.print("\t");
  Serial.println(y);

  //set shooting if connection made
  if(digitalRead(shootPin) == LOW)
  {
    Keyboard.press(' ');
  }
  else
  {
    Keyboard.release(' ');
  }

  
  ////GYRO CONTROLS BELOW////

  //Strafe Right//
  if(x <= -4)
  {
    Keyboard.press('d');
    //light up right side Neopixels only
    CircuitPlayground.setPixelColor(0, 0, 0, 0);
    CircuitPlayground.setPixelColor(1, 0, 0, 0);
    CircuitPlayground.setPixelColor(2, 0, 0, 0);
    CircuitPlayground.setPixelColor(3, 0, 0, 0);
    CircuitPlayground.setPixelColor(4, 0, 0, 0);
    CircuitPlayground.setPixelColor(5, 82, 15, 82);
    CircuitPlayground.setPixelColor(6, 82, 15, 82);
    CircuitPlayground.setPixelColor(7, 82, 15, 82);
    CircuitPlayground.setPixelColor(8, 82, 15, 82);
    CircuitPlayground.setPixelColor(9, 82, 15, 82);
  }

  //Strafe Left//
  if(x >= 4)
  {
    Keyboard.press('a');
    //light up left side Neopixels only
    CircuitPlayground.setPixelColor(0, 82, 15, 82);
    CircuitPlayground.setPixelColor(1, 82, 15, 82);
    CircuitPlayground.setPixelColor(2, 82, 15, 82);
    CircuitPlayground.setPixelColor(3, 82, 15, 82);
    CircuitPlayground.setPixelColor(4, 82, 15, 82);
    CircuitPlayground.setPixelColor(5, 0, 0, 0);
    CircuitPlayground.setPixelColor(6, 0, 0, 0);
    CircuitPlayground.setPixelColor(7, 0, 0, 0);
    CircuitPlayground.setPixelColor(8, 0, 0, 0);
    CircuitPlayground.setPixelColor(9, 0, 0, 0);  
  }

  //Brake if tilting backwards//
  if (y >= 4)
  {
    Keyboard.press('s');
    //toggle off acceleration
    Keyboard.release('w');
    CircuitPlayground.clearPixels();
  }
  
  //Accelerate if tilting forward//
  if (y <= -4)
  {
    //toggle on acceleration
    Keyboard.press('w');
  }

  //Boost ONCE if far forward//
  if (y <= -7)
  {
    Keyboard.write(KEY_LEFT_CTRL);
  }
  
  //Neutral X Axis//
  if ((x > -4) && (x < 4))
  {
    Keyboard.release('d');
    Keyboard.release('a');
    //all Neopixels lit
    CircuitPlayground.setPixelColor(0, 82, 15, 82);
    CircuitPlayground.setPixelColor(1, 82, 15, 82);
    CircuitPlayground.setPixelColor(2, 82, 15, 82);
    CircuitPlayground.setPixelColor(3, 82, 15, 82);
    CircuitPlayground.setPixelColor(4, 82, 15, 82);
    CircuitPlayground.setPixelColor(5, 82, 15, 82);
    CircuitPlayground.setPixelColor(6, 82, 15, 82);
    CircuitPlayground.setPixelColor(7, 82, 15, 82);
    CircuitPlayground.setPixelColor(8, 82, 15, 82);
    CircuitPlayground.setPixelColor(9, 82, 15, 82);
  }
  
  //Neutral Y Axis//
  if ((y > -4) && (y < 4))
  {
    Keyboard.release('s');
  }
}

No comments:

Post a Comment

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