27 November 2023

Final Project: Cuphead Game Controller

For this project, I decided to create a game controller for the game "Cuphead", a popular boss rush game inspired by 1920s cartoons. The point of the game is that you made an unintentional deal with the devil and now you must defeat bosses and collect their soul contracts to get out of the deal. 

Given this context, I wanted the controller to let players feel like they were the devil controlling the characters.  I designed the controller as a cup since the character has an actual cup as a head. I wanted the cup to have enough space for the required wiring and accessories, however, I did not consider the mount for the Adafruit circuit playground and had to think of other ways to attach it to the model. 


For the mechanics of my controller, the player would tilt the cup left, right, up, and down to move the character in the corresponding direction. The red nose button on the front would get the player to jump and parry. For shooting and dashing, I decided to use touch sensors. Originally, I wanted the player to scream into the Adafruit to shoot projectiles because I thought it would be a little funny. However, after some feedback, I realized that it would be very inconvenient to the player and was recommended to use the touch sensors. One on the handle for projectiles and easy gripping since the player will almost always be shooting at the boss. The touch sensor on the left of the controller is for dashing. If the player wants to stay in one place and shoot at a target, they can cover the light sensor on the Adafruit circuit to lock the character in place. There is a light that is close to the sensor that will go dark if the light sensor is covered enough. As the player shoots enemies and bosses, they charge up for special attacks that can be activated with the sound sensor. A simple snap of the figures is enough to activate it.




Schematics:



Question for the readers:

Question 1: The button on the front is used for jumping, but if I wanted to use a different accessory for jumping and parrying, what would you recommend?

Question 2: What are your most favorite and most hated bosses in Cuphead?


Video:

I asked a volunteer if they could do a few bosses with this controller to see the functionality of the controller.


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

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

const int debounce = 1;
int direction;
int shoot;
int dash;
int sound = 0;
int light = 0;
int thresh = 400;
float value;


void setup()
{
// put your setup code here, to run once:
CircuitPlayground.begin();
pinMode(A1, INPUT_PULLUP); // button for jumping
pinMode(A2, INPUT_PULLUP);//touchsensor for shooting
pinMode(A5, INPUT_PULLUP);//touch sensor for dashing
pinMode(CPLAY_SOUNDSENSOR, INPUT);//sound sensor for special attacks
pinMode(CPLAY_LIGHTSENSOR, INPUT);// light sensor for locking

Keyboard.begin();
Serial.begin(9600);
delay(0);
}

void loop()
{
// put your main code here, to run repeatedly:
int t = CircuitPlayground.readCap(A2);
int d = CircuitPlayground.readCap(A5);
float x = CircuitPlayground.motionX();
float y = CircuitPlayground.motionY();
float light = CircuitPlayground.lightSensor();
float sound = CircuitPlayground.soundSensor();


if (x < -3)
{
Keyboard.press(KEY_RIGHT_ARROW);//move teh character right
delay(10);
Serial.print(direction); Serial.println("Right");
}
else
{
Keyboard.release(KEY_RIGHT_ARROW);
}


if(x > 3){
Keyboard.press(KEY_LEFT_ARROW);//moev the character left
delay(10);
Serial.print(direction); Serial.println("Left");
}
else
{
Keyboard.release(KEY_LEFT_ARROW);
}


if (y > 3)
{
Keyboard.press(KEY_UP_ARROW);//move the character up
delay(10);
Serial.print("direction: "); Serial.println("Up");
}
else
{
Keyboard.release(KEY_UP_ARROW);
}


if (y < -3)
{
Keyboard.press(KEY_DOWN_ARROW);//move the character down
delay(10);
Serial.print("direction: "); Serial.println("Down");
}
else
{
Keyboard.release(KEY_DOWN_ARROW);
}


if( ! digitalRead(A1) )//push the button to jump. push it again to parry
{
Keyboard.press('z');
Serial.print(direction); Serial.println("Jump");
delay(0);
}
else
{
Keyboard.release('z');
}


if (sound > 25) //speak into the adafruit to use special attacks
{
Keyboard.press('v');//special attack
int soundValue = digitalRead(sound);
value = CircuitPlayground.mic.soundPressureLevel(10);
Serial.print("Sound Level: ");
Serial.println(value);

}
else
{
Keyboard.release('v');
}


if (light < 15) //cover the cup to lock the character in place
{
Keyboard.press('c');//lock
int lightValue = digitalRead(light);
value = CircuitPlayground.lightSensor();
CircuitPlayground.setPixelColor(0, 0, 0, 0);//if the light sensor is covered, teh light will turn off.
Serial.print("Light Level: ");
Serial.println(value);
Serial.print(light); Serial.println("Lock");
}
else
{
Keyboard.release('c');
CircuitPlayground.setPixelColor(0, 0, 30, 0);
}


if(d < thresh) //cover the touch sensor on teh left to dash
{
Keyboard.press('d');
Serial.print(dash); Serial.println("Dash");
}
else
{
Keyboard.release('d');
}


if(t < thresh) //cover the touch sensor on the handle to shoot projectiles
{
Keyboard.press('x');
Serial.print(shoot); Serial.println("Shoot");
}
else
{
Keyboard.release('x');
}

Serial.println(t);
Serial.println(d);
delay(debounce);
//
//
}






No comments:

Post a Comment

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