27 November 2023

Project: The Sonic Spinball Mini Pinball Machine Controller

 

                                                    Photo of Sonic Spinball Controller


    Hello everyone, this is Kyle Amburgey here with the final build of my custom game controller: The Sonic Spinball Mini Pinball Machine. My idea for this controller was for a mini pinball machine as the game that I was designing it to work with, Sonic Spinball, is a Sonic The Hedgehog spinoff game with pinball-style gameplay and I've always wondered what it would be like to play it like an actual pinball machine, instead of with just regular buttons. The controller consists of two photocells used for moving left and right, and two mini toggle switches used for the pinball flippers and jumping.

    Starting with mappings, there are only three major controls I needed to consider when designing my project: moving, jumping, and flipping bumpers. To move Sonic left or right the player must tilt the controller to cause a small marble within the controller to cover one of the photocells within the center chamber of the controller, an action signified by the presence of two photocells within the middle of the controller and a marble that can be moved to cover them. To control the left and right flippers all the player needs to do is toggle the left and right toggle switches, respectively; this action also causes Sonic to jump, an action originally mapped to a third photocell that unfortunately stopped working after I finished building the controller.

    Moving on to my controller's conceptual model, the concept behind it is quite literal as it is just a mini pinball machine, so the mappings for the controller mimic the actions a player might perform on a full-sized pinball machine. Tilting the controller to move is just like when players tilt a pinball machine to move the pinball in a desired direction, an action considered cheating, however it is necessary in the dangerous pinball world Sonic finds himself in within Sonic Spinball. Flipping the toggle switches to flip the pinball flippers is just like controlling flippers on an actual machine, and one may see this act as making the pinball jump, making my mapping of the jump button to these switches an appropriate one conceptually.

    I would like to end off with a question about my controller: is there a better way I could have mapped movement?


Schematic


// Code written by Kyle Amburgey, 2023

// CPE library
#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>

// Keyboard library
#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>

// Define pins for all three external light sensors
int photocell0 = A7;
int photocell1 = A1;
int photocell2 = A0;

// Analog readings from photocells
int photocellReading0;
int photocellReading1;
int photocellReading2;

// Define pins for both mini toggle switches
int toggleswitch0 = A5;
int toggleswitch1 = A2;

// Debounce time of 10 milliseconds
const int debounce = 10;

void setup() {
  //Opens CPE serial port
  Serial.begin(9600);
  // Initiates switch pins
  pinMode(toggleswitch0, INPUT);
  pinMode(toggleswitch1, INPUT);
  // Initiates photocell pins
  pinMode(photocell0, INPUT);
  pinMode(photocell1, INPUT);
  pinMode(photocell2, INPUT);
  // Initiates CPE
  CircuitPlayground.begin();
  // Enables keyboard controls
  Keyboard.begin();
  // Delay of 1 second before looping
  delay(1000);
}

void loop() {
  // Photocell testing
  photocellReading0 = analogRead(photocell0);
  photocellReading1 = analogRead(photocell1);
  photocellReading2 = analogRead(photocell2);

  // If photocell0 is covered, then press and hold 'left arrow' key
  if(photocellReading0 >= 185) {
    // Release 'left arrow' key
    Keyboard.release(KEY_LEFT_ARROW);
    delay(debounce);
  } else {
    // Press and hold 'left arrow' key
    Keyboard.press(KEY_LEFT_ARROW);
    // Debounce for photocell
    delay(debounce);
  }

  // If photocell1 is covered, then press and hold 'right arrow' key
  if(photocellReading1 >= 300) {
    // Release 'right arrow' key
    Keyboard.release(KEY_RIGHT_ARROW);
    // Debounce for photocell
    delay(debounce);
  } else {
    // Press and hold 'right arrow' key
    Keyboard.press(KEY_RIGHT_ARROW);
    // Debounce for photocell
    delay(debounce);
  }

  /* ** Scrapped code for the third photocell that was **
  originally mapped to press both flippers at once and jump;
  this component unfortunately broke at some point after
  placing my circuit into the final controller case. */
    /* If photocell2 is covered, then press and hold 'c'
    (both flippers / jump),then delay for 1 second */
      /*if(photocellReading2 >= 169) {
        Keyboard.release('z');
        delay(debounce);
      } else {
        // Press and hold 'z' key
        Keyboard.press('z');
        // Debounce for photocell
        delay(debounce);
      }
      */
 
  /* If toggleswitch0 is switched on, then press and hold
  'x' and then press 'z' (right flipper control then jump). */
  if(analogRead(toggleswitch1) < 300) {
    // Release 'x' key
    Keyboard.release('x');
    // Debounce for switch
    delay(debounce);
  } else if(analogRead(toggleswitch1) > 400) {
    // Press and hold 'x' key
    Keyboard.press('x');
    // Press 'z' to jump
    Keyboard.write('z');
    // Debounce for switch
    delay(debounce);
  }

  /* If toggleswitch1 is switched on, then press and hold 's'
  and then press 'z' (left flipper control then jump). */
  if(analogRead(toggleswitch0) > 400) {
    // Release 's' key
    Keyboard.release('s');
    // Debounce for switch
    delay(debounce);
  } else if(analogRead(toggleswitch0) < 300) {
    // Press and hold 's' key
    Keyboard.press('s');
    // Press 'z' to jump
    Keyboard.write('z');
    // Debounce for switch
    delay(debounce);
  }

  // **Code for testing component readings within the serial monitor**
    // Debug code for photocells
      //Serial.print(photocellReading0);
        //Serial.print("\t");
      //Serial.print(photocellReading1);
        //Serial.print("\t");
      //Serial.print(photocellReading2);
        //Serial.print("\t");
    // Debug code for switches
      //Serial.println(analogRead(A5));
        //Serial.print("\t");
      //Serial.println(analogRead(A2));
        //Serial.print("\t");

}

                                                                     Arduino code 


                                           https://www.youtube.com/watch?v=8iJ7W54ORts


No comments:

Post a Comment

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