20 November 2024

Team 10: Crypt of the NecroDancer Mimic Controller

Description:

Crypt of the NecroDancer is a game in which the player traverses a dungeon to the rhythm of the music playing in the background. The player can use a multitude of items at their disposal, including but not limited to: bombs, thrown weapons, and spells.

Conceptually, the controller is designed like a Mimic; a classic medieval fantasy monster which also appears in the game itself. In a sense, the player themself has to brave the strange depths of this creature to be able to simultaneously brave the depths of the dungeons in the game. The game is controlled via the Mimics overt fleshy bits. The tongue of the Mimic can be used to move up or down as well as throwing your weapon, and the inside of the Mimic possesses two fleshy sores that can be pressed on to move the player left or right. The inputs can also be combined to perform their respective actions in game. The inputs are meant to be discovered easily by the way they stick out compared to the rest of the Mimics body; Both in terms of texture as well as proportions.

In terms of affordances our chosen electronic components were perfect for the aesthetics we wanted to achieve, but it was somewhat challenging to fully determine how we would use those components to achieve all of the basics of gameplay; Using a linear potentiometer to house multiple inputs was particularly interesting.

Feedback Question: If you were to make a controller like this, would you have used any different inputs or sensors? (edited)

Video Demonstration:

Schematic:


Code:

#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 <Keyboard_sv_SE.h>

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

int fsrAnalogPinOne = A2;
int fsrAnalogPinTwo = A1;
int fsrReadingRight;
int fsrReadingLeft;

int potPin = A0;
int potVal = 0;

//bools used to track whether sensors are being made contact with or not
bool contact;
bool potContactUp;
bool potContactDown;
bool fsrContactL;
bool fsrContactR;
bool LEFTRIGHT;
bool DOWNLEFT;
bool UPLEFT;
bool DOWNRIGHT;
bool UPRIGHT;
bool RIGHTLEFT;
bool UPDOWN;

void setup()
{
  Serial.begin(9600);
  Keyboard.begin();
}

void loop()
{
  fsrReadingRight = analogRead(fsrAnalogPinTwo); //reads input numbers from right sore sensor
  fsrReadingLeft = analogRead(fsrAnalogPinOne); //reads input numbers from left sore sensor
 
  potVal = analogRead(potPin); //reads input numbers from tongue sensor

  //Ensures the neutral state of sensor doesn't read anything and resets values
  if(potVal < 25)
  {
    potContactUp = false;
    potContactDown = false;
  }

  //Range used to act as the combination keys of UP+DOWN
  else if (potVal < 200 && potVal > 100 && !UPDOWN && !potContactUp && !potContactDown)
  {
      UPDOWN = true;
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_DOWN_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      UPDOWN = false;
      return;
  }

  //Middle of the range (230-50) which is used to represent the UP key
  else if (potVal < 500 && potVal > 230 && !potContactUp)
  {
    potContactUp = true;

    //Case that UP + LEFT is pressed at the same time and inputs those keys
    if (fsrReadingLeft >= 100 && !UPLEFT)
    {
      UPLEFT = true;
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      UPLEFT = false;
      return;
    }

    //Case that UP + RIGHT is pressed at the same time and inputs those keys
    if (fsrReadingRight >= 100 && !UPRIGHT)
    {
      UPRIGHT = true;
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      UPRIGHT = false;
      return;
    }
    Keyboard.write(KEY_UP_ARROW);
  }
 
  //Upper third of the range (615-1023) which is used to represent the DOWN key
  else if (potVal >= 615 && !potContactDown)
  {
    potContactDown = true;

    //Case that DOWN + LEFT is pressed at the same time and inputs those keys
    if (fsrReadingLeft >= 100 && !DOWNLEFT)
    {
      DOWNLEFT = true;
      Keyboard.press(KEY_DOWN_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      DOWNLEFT = false;
      return;
    }
   
    //Case that DOWN + RIGHT is pressed at the same time and inputs those keys
    if (fsrReadingRight >= 100 && !DOWNRIGHT)
    {
      DOWNRIGHT = true;
      Keyboard.press(KEY_DOWN_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      DOWNRIGHT = false;
      return;
    }
    Keyboard.write(KEY_DOWN_ARROW);
  }

  //Reset values to false if there is no contact
  if (fsrReadingRight < 100)
  {
    fsrContactR = false;
  }

  //When right sensor receives a minimum amount of force, press right key
  else if (fsrReadingRight >= 100 && !fsrContactR) {
    fsrContactR = true;

    //Case that RIGHT + DOWN is pressed at the same time and inputs those keys
    if(potVal >= 615 && !DOWNRIGHT)
    {
      DOWNRIGHT = true;
      Keyboard.press(KEY_DOWN_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      DOWNRIGHT = false;
      return;
    }
   
    //Case that RIGHT + UP is pressed at the same time and inputs those keys
    if(potVal < 500 && potVal > 230 && !UPRIGHT)
    {
      UPRIGHT = true;
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      UPRIGHT = false;
      return;
    }
   
    //Case that RIGHT + LEFT is pressed at the same time and inputs those keys
    if(fsrReadingLeft >= 100 && !LEFTRIGHT)
    {
      LEFTRIGHT = true;
      Keyboard.press(KEY_LEFT_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      LEFTRIGHT = false;
      return;
    }
    Keyboard.write(KEY_RIGHT_ARROW);
  }

  //Reset values to false if there is no contact
  if (fsrReadingLeft < 100)
  {
    fsrContactL = false;
  }

  //When left sensor receives a minimum amount of force, press left key
  else if (fsrReadingLeft >= 100 && !fsrContactL) {
    fsrContactL = true;

    //Case that LEFT + DOWN is pressed at the same time and inputs those keys
    if(potVal >= 615 && !DOWNLEFT)
    {
      DOWNLEFT = true;
      Keyboard.press(KEY_DOWN_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      DOWNLEFT = false;
      return;
    }

    //Case that LEFT + UP is pressed at the same time and inputs those keys
    if(potVal < 500 && potVal > 230 && !UPLEFT)
    {
      UPLEFT = true;
      Keyboard.press(KEY_UP_ARROW);
      Keyboard.press(KEY_LEFT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      UPLEFT = false;
      return;
    }

    //Case that LEFT + RIGHT is pressed at the same time and inputs those keys
    if(fsrReadingRight >= 100 && !LEFTRIGHT)
    {
      LEFTRIGHT = true;
      Keyboard.press(KEY_LEFT_ARROW);
      Keyboard.press(KEY_RIGHT_ARROW);
      delay(10);
      Keyboard.releaseAll();
      delay(50);
      LEFTRIGHT = false;
      return;
    }
    Keyboard.write(KEY_LEFT_ARROW);
  }
}


No comments:

Post a Comment

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