17 April 2022

Game Controller: Galaga

 

    My controller is made to be used for the game Galaga.  I chose Galaga because it has a pretty simple control scheme, and the game is so iconic.  I originally wanted to have an exact replica of the space ship, but I didn't have the correct colored filaments to achieve this, so I could only mimic the shape of the ship.  I do have the neopixels on the Circuit Playground Bluefruit change colors based off of certain actions like moving or shooting and they change to the colors of the theme of the galaga ship, the use of the neopixels correlating to actions also helps with feedback, knowing that you performed a specific action.

    For my controller I use the accelerometer for all my actions.  One of the reasons I decided on the accelerometer as my control scheme is because of how it simulates the movement of a plane in real life.  I have a tilt to the left to simulate moving left and I have tilting to the right to strafe right.  Tilting the controller back towards the user will shoot.  The binding values are programmed to overlap a bit so that you can tilt diagonally to shoot and move at the same time.  I also have the buttons on the Circuit playground binded to enter so that you can start and pause the game without having to use your mouse or keyboard.

    What signifiers could I have added to better my design or made it easier to understand or use?





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

//Author: Hiram Sun

uint8_t const desc_hid_report[] = {
  TUD_HID_REPORT_DESC_KEYBOARD()
};

Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
//https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h

const int debounce = 25;
bool isLit = false;


void setup() {
  CircuitPlayground.begin();
  pinMode(CPLAY_LEFTBUTTON, INPUT_PULLDOWN); //button A
  pinMode(CPLAY_RIGHTBUTTON, INPUT_PULLDOWN); //button B

  usb_hid.begin();
  delay(1000);
}

void loop() {
  uint8_t const report_id = 0;
  uint8_t const modifier = 0;
  uint8_t keycode[6] = { 0 };

  //
  if(isLit == false){
    isLit = true;
    for(int i = 0; i <= 9; i++){
      CircuitPlayground.setPixelColor(i, 120, 120, 120);
    }
  }

//Variables for Smoothing
  int numReads = 5;
  float xSum = 0;
  float ySum = 0;

//Get Accelerometer Orientation and smooth the value
  for (int i = 0; i < numReads; i++){
    xSum += CircuitPlayground.motionX();
    ySum += CircuitPlayground.motionY();
    delay(1);
  }
  float x = avgValue(xSum, numReads);
  float y = avgValue(ySum, numReads);  
  float rad = atan2(y, x);

//Buttons for starting or pausing game (Enter)
  if(digitalRead(CPLAY_LEFTBUTTON) || digitalRead(CPLAY_RIGHTBUTTON)){
    keycode[0] = HID_KEY_ENTER;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(200);
    usb_hid.keyboardRelease(0);
  }
  
//Strafe Right (D Key)
  if(rad < -2.05 || rad > 2.85){
    //Right Neopixels
    for(int k = 5; k <= 9; k++){
      CircuitPlayground.setPixelColor(k, 0, 0, 255);
      CircuitPlayground.setPixelColor(k - 5, 0, 0, 0);
    }
    keycode[0] = HID_KEY_D;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
  } else {
    for(int k = 5; k <= 9; k++){
      CircuitPlayground.setPixelColor(k, 120, 120, 120);
    }
  }
  

//Strafe Left (A Key)
  if(rad > -1.05 && rad < 0.3){
    //Left Neopixels
    for(int j = 0; j <= 4; j++){
      CircuitPlayground.setPixelColor(j, 0, 0, 255);
      CircuitPlayground.setPixelColor(j + 5, 0, 0, 0);
    }
    keycode[0] = HID_KEY_A;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
  } else {
    for(int j = 0; j <= 4; j++){
      CircuitPlayground.setPixelColor(j, 120, 120, 120);
    }
  }
  
//Shoot (H Key)
  if(rad < -0.55 && rad > -2.55){
    for(int l = 3; l <= 6; l++){
      CircuitPlayground.setPixelColor(l, 255, 0, 0);
    }
    delay(10);
    for(int l = 3; l <= 6; l++){
      CircuitPlayground.setPixelColor(l, 0, 0, 0);
    }
    delay(10);
    for(int l = 3; l <= 6; l++){
      CircuitPlayground.setPixelColor(l, 255, 0, 0);
    }
    keycode[0] = HID_KEY_H;
    usb_hid.keyboardReport(report_id, modifier, keycode);
    delay(debounce);
    usb_hid.keyboardRelease(0);
  }

}

//average the input value
float avgValue(float sumValue, int divisor){
  float result = sumValue / divisor;
  return result;
}

No comments:

Post a Comment

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