26 November 2024

Final Project Team 16 Doom Gun Controller

    

Our game controller was created for the first person shooter Doom and we wanted the player to feel as if they were the ones running and gunning through the pits of hell killing demons.  To accomplish this goal we have created a controller in the shape of a gun appose to a standard controller, assigning the circuit playground express’s accelerometer movements on the Z and X axis to movement to feel as if the player is traveling through the game leaning to which way they want to travel.  Along with this we have assigned the accelerometer Y axis to the mouse click to fire making the player to make a recoil like motion to simulate as if the weapon is firing.  Since there is no need to look up and down we put a potentiometer on our controller to make the player look left and right along with a switch to interact with items in the game such as doors.  Two questions we have for our peers would be, what other inputs would you use to simulate this game experience and what could we have done to improve the look and feel of our controller to fit more aesthetically with the game we have chosen.






// Libraries
#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>

#include <Mouse.h>

int debounce = 10;

// Mouse Variables
const int xAxis = A1;         // Analog sensor for X axis
const int yAxis = A2;         // Analog sensor for Y axis
float wheel;                  // Scroll wheel

int range = 12;               // Output range of X or Y movement
int responseDelay = 2;        // Response delay of the mouse, in ms
int threshold = range / 4;    // Resting threshold
int center = range / 2;       // Resting position value
int minima[] = {1023, 1023};  // Actual analogRead minima for (x, y)
int maxima[] = {0, 0};        // Actual analogRead maxima for (x, y)
int axis[] = {xAxis, yAxis};  // Pin numbers for (x, y)
int mouseReading[2];          // Final mouse readings for (x, y)

void setup() {
  // put your setup code here, to run once:
  Mouse.begin(); // initalize mouse library
  Keyboard.begin();
  CircuitPlayground.begin();

  pinMode(A1, INPUT_PULLUP);

}

void loop() {
// put your main code here, to run repeatedly:

// CircuitPlayground accelerometer Z and X will be linked to arrow keys or WASD for player movement
//Serial.println(CircuitPlayground.motionZ());

if(CircuitPlayground.motionX() > 5){
  Keyboard.write('s');
  delay(debounce);
}

if(CircuitPlayground.motionX() < -5){
  Keyboard.write('w');
  delay(debounce);
}

if(CircuitPlayground.motionZ() > 5){
  Keyboard.write('d');
  delay(debounce);
}

if(CircuitPlayground.motionZ() < -5){
  Keyboard.write('a');
  delay(debounce);
}

// Switch is linked to the player interaction button (spacebar)
  if(digitalRead(A1) == LOW){
    Keyboard.write(' ');
    delay(1000);
  }

// Controller is recoiled back on the y-axis to fire in-game weapon
  Serial.println(CircuitPlayground.motionX());
  if(CircuitPlayground.motionY() >= -7){
    Mouse.click(MOUSE_LEFT);
  }

// AccelerometerX is linked to mouse scroll wheel up/down to swich weapons

 Serial.println(CircuitPlayground.motionX());
  // rotate the scroll wheel up
  if(CircuitPlayground.motionX() >= 15){
    wheel++;
    Mouse.move(0,0,1);
  }
  // rotate the scroll wheel down
  if(CircuitPlayground.motionX() <= -15){
    wheel--;
    Mouse.move(0,0,-1);
  }

// Potentiometer is linked to mouseX input to adjust where the player is looking
  // Read and scale the two axes
  int xReading = readAxis(0);
  int yReading = readAxis(1);

  // Move the mouse
  Mouse.move(xReading, 0, 0);
  delay(responseDelay);
  }

// Mouse Function
int readAxis(int axisNumber) {
  int distance = 0; // Distance from center of the output range

  // Read the analog input
  int reading = analogRead(A7);

  // Of the current reading exceeds the max or min for this axis, reset the max or min
  if (reading < minima[A7]) {
    minima[A7] = reading;
  }
  if (reading > maxima[A7]) {
    maxima[A7] = reading;
  }

  // Map the reading from the analog input range to the output range
  reading = map(reading, minima[A7], maxima[A7], 0, range);

  // If the output reading is outside from the rest position threshold,  use it
  if (abs(reading - center) > threshold) {
    distance = (reading - center);
  }

  // The Y axis needs to be inverted in order to map the movement correctly
  if (axisNumber == 1) {
    distance = -distance;
  }

  // Return the distance for this axis
  return distance;
}

 


No comments:

Post a Comment

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