20 November 2024

Group 11 Controller - Touhou Broom

Controller Description

    The conceptual model for our design is to look like the broom ridden by Marisa in Touhou 4: Lotus Land Story. To achieve this, the controller has a roughly cone-shaped yellow bottom to imitate bristles, with a long brown handle like a wooden broom.


    There are three types of input that the controller accepts. The first is rotation, using the accelerometer. Rotating the controller will cause the character to move in the same direction. The second input is sound. Making a loud sound, such as a shout, will cause the character to use their Bomb ability. The final type of input is distance. Gripping the broom by the top of the handle, covering the controller’s distance sensor, will cause the character to move more slowly.


    The signifiers for the controller are connected to its relation to the game. In order to get the character to move, a player must move the controller in the same way. This makes the controls intuitive, by letting the player feel that they are directly moving the character. The controller itself does not offer much feedback outside of the character’s movements in the game. Real-world feedback on the controller is limited to the controller rotating when the player moves it (most easily seen by watching the ‘bristles’ part move).


    These aspects of the controller are able to make the player feel more immersed in the game. They move their broom like the character does to move, grip the broom at the top to make precise movements, and can call out the name of their Spell Card to use the Bomb in the same way the characters do.

 

Controller Photo

 

 

Controller Schematic

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_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>

// Variables
int trigPin = A1;
int echoPin = A2;

int rawDistance;
int duration;
int rawSound;
int rawX;
int rawY;

int mappedX;
int mappedY;
int mappedSound;
int mappedDistance;

int soundThreshold = 5;
int distanceThreshold = -5;
int xThreshold = 2;
int yThreshold = 1;

void setup() {
  // put your setup code here, to run once:
  CircuitPlayground.begin();
  Keyboard.begin();
  Serial.begin(9600);

  // Trig Pin - A1
  pinMode(trigPin, OUTPUT);
  // Echo Pin - A2
  pinMode(echoPin, INPUT);

  delay(1000);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(CPLAY_SLIDESWITCHPIN))
  {
    AcceptInput();
    MapInput();
    AutoFire();
    ControlMovement();
    ButtonEvents();

    delay(50);
  }
}

void AcceptInput()
{
  // Motion input
  rawX = CircuitPlayground.motionX();
  rawY = CircuitPlayground.motionY();
  // Sound input
  rawSound = CircuitPlayground.mic.soundPressureLevel(10);
  // Distance input
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  rawDistance = (duration / 2) / 29.1;
}

void MapInput()
{
  mappedX = map(rawX, -10, 5, -5, 5);
  mappedY = map(rawY, -10, 5, -5, 5);
  mappedY = mappedY * -1;

  mappedSound = map(rawSound, 50, 100, 0, 10);

  mappedDistance = map(rawDistance, 0, 200, -10, 40);
}

void AutoFire()
{
  // Spam z to shoot
  Keyboard.press('z');
  delayMicroseconds(5);
  Keyboard.release('z');
}

void ControlMovement()
{
  // Y - Up / Down movement
  if (mappedY > yThreshold)
  {
    // Move up
    Keyboard.release(KEY_ARROW_DOWN);
    Keyboard.press(KEY_ARROW_UP);
  } else if (mappedY < (yThreshold * -1))
  {
    // Move down
    Keyboard.release(KEY_ARROW_UP);
    Keyboard.press(KEY_ARROW_DOWN);
  } else
  {
    Keyboard.release(KEY_ARROW_DOWN);
    Keyboard.release(KEY_ARROW_UP);
  }
  // X - Left / Right movement
  if (mappedX > xThreshold)
  {
    // Move left
    Keyboard.release(KEY_ARROW_RIGHT);
    Keyboard.press(KEY_ARROW_LEFT);
  } else if (mappedX < (xThreshold * -1))
  {
    // Move right
    Keyboard.release(KEY_ARROW_LEFT);
    Keyboard.press(KEY_ARROW_RIGHT);
  } else
  {
    Keyboard.release(KEY_ARROW_RIGHT);
    Keyboard.release(KEY_ARROW_LEFT);
  }
}

void ButtonEvents()
{
  // Sound - bomb
  if (mappedSound > soundThreshold)
  {
    Keyboard.write('x');
  }

  // Distance - focus
  if (mappedDistance < distanceThreshold)
  {
    Keyboard.press(KEY_LEFT_SHIFT);
  } else
  {
    Keyboard.release(KEY_LEFT_SHIFT);
  }
}


 

Controller Video


 

Question:


Considering the aim of player immersion, are there better ways to approach the use of specific controls, such as the bomb ability or shooting?

 

No comments:

Post a Comment

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