Rhythm Heaven Tambourine Controller
Description:
This is a customized controller that can be used to play virtually any Rhythm Heaven minigame. Rhythm Heaven is a game series about playing hundreds of bite-sized, rhythm-based minigames with a wide variety of musicality, challenges, and wacky characters and situations. Each minigame can be played with one or two buttons, making it fun and accessible for all kinds of players.
Our controller aims to capture the playful nature of the minigames by having the user actively interact with the controller in time with the beat of the game. It measures what orientation the instrument is being held in and detects when the instrument is struck. These hits are then translated into inputs. While the controller is oriented to the left, it will translate to an "A" button press, and translate to a "B" button press when oriented to the right. This allows the user a ton of flexibility with the kinds of minigames they can play since all of them use "A" or "B" button inputs. Needing to hit the tambourine itself results in very satisfying sonic feedback accompanied by your success in the game. Lastly, a potentiometer that sticks out of the bottom of the controller allows the user to easily navigate any of the menus of the game.
Visually, our controller uses an actual tambourine as its shell. This is a direct reference to the 'Tambourine' minigame in Rhythm Heaven Fever, in which a cartoonish monkey prompts the player to play to the beat using a tiny tambourine. The back of the controller also features a few hand-drawn depictions of characters from some of the other minigames in the series. The simplicity of the controller also mirrors the minimalist art style featured in the games!
Overall, this controller is simple, yet effective and provides a whimsical and interactive way to play minigames in the Rhythm Heaven series.
Schematic:
Code:
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>
#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>
const int debounce = 500;
#define CLICKTHRESHHOLD 120
bool tapped = false;
void setup()
{
// Initialize Switch on Playground for On/Off
// Initialize Circuit Playground
// Initialize Keyboard / Controller
CircuitPlayground.begin();
pinMode(CPLAY_SLIDESWITCHPIN, INPUT_PULLUP);
Keyboard.begin();
// Init tap sensor
CircuitPlayground.setAccelRange(LIS3DH_RANGE_2_G);
CircuitPlayground.setAccelTap(1, CLICKTHRESHHOLD);
attachInterrupt(digitalPinToInterrupt(CPLAY_LIS3DH_INTERRUPT), tapTime, FALLING);
}
void tapTime(void)
{
// do something :)
Serial.print("Tap! ");
Serial.println(millis()); // the time
tapped = !tapped;
}
void loop()
{
// If the switch is on...
if(digitalRead(CPLAY_SLIDESWITCHPIN)) // Safety First!
{
//Initialize keyboard/controller stuff depending on input we use
float x = CircuitPlayground.motionX();
float BTilt = 6;
float CTilt = -6;
// Print Device Values
Serial.println(x); // Tilt
Serial.print("\t");
Serial.println(analogRead(A2)); // Knob
if (tapped == true)
{
if (x > BTilt || x < CTilt)
{
Keyboard.write('j');
}
else
{
Keyboard.write('k');
}
tapped = false;
}
//D-Pad Potentiometer
// If Potentiometer value is Neutral (between two values)
if(analogRead(A2) > 460 || analogRead(A2) < 660)
{
// Release all D-Pad Inputs
Keyboard.release(KEY_LEFT_ARROW);
Keyboard.release(KEY_RIGHT_ARROW);
Keyboard.release(KEY_UP_ARROW);
Keyboard.release(KEY_DOWN_ARROW);
}
// If Potentiometer is below a certain value (Left)
if(analogRead(A2) > 660)
{
// If Accelerometer rotation is over a certain value (Tilted)
if(x > BTilt || x < CTilt)
{
// Press Up
Keyboard.write(KEY_UP_ARROW);
delay(debounce);
}
else
{
// Press Left
Keyboard.write(KEY_LEFT_ARROW);
delay(debounce);
}
}
// If Potentiometer is over a certain value (Right)
if(analogRead(A2) < 460)
{
// If Accelerometer rotation is over a certain value (Tilted)
if(x > BTilt || x < CTilt)
{
// Press Down
Keyboard.write(KEY_DOWN_ARROW);
delay(debounce);
}
else
{
// Press Right
Keyboard.write(KEY_RIGHT_ARROW);
delay(debounce);
}
}
}
else
{
// Release buttons
Keyboard.release(KEY_LEFT_ARROW);
Keyboard.release(KEY_RIGHT_ARROW);
Keyboard.release(KEY_UP_ARROW);
Keyboard.release(KEY_DOWN_ARROW);
}
}
Video Demonstration:
Final question:
Are there any better ways we could've provided the user with feedback other than the sound of the tambourine?
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.