27 November 2023

LIMBO Game Controller

 

I chose to create a game controller for Limbo, developed by Playdead. The conceptual model draws inspiration from one of the NPCs in the game, the "maggot eater." These helpful characters spawn with three heads that are almost constantly chomping and help the player by eating the mind controlling maggots that get stuck on their head. The controller has five inputs and outputs. The leftmost head can be swiveled to control vertical movement (up and down), while the rightmost head can be swiveled to control horizontal movement (left and right). To mirror some of the in-game behavior, the mouth on the leftmost head can be opened and closed to hold and pull or push items in the game. Input is mostly prompted by the springs, which suggest that there is some interactable mechanism attached to the model. Some of the most prominent forms of feedback that this controller gives to the player is the sounds of the mouths opening and closing, and sounds associated with swiveling each head. Overall, the controller is very monotone and challenges the user to quickly switch between different inputs which maps perfectly onto Limbo's monochromatic atmosphere and unforgiving gameplay. How could I improve the controller's signifiers and feedback?

Circuit:



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_it_IT.h>

#include <Keyboard_sv_SE.h>


#include <Adafruit_CircuitPlayground.h>

#include <Adafruit_Circuit_Playground.h>


int inputThreshold = 3;

bool firstLoop = false;

int defaultLightValue = 0;


// boolean for if player was pressing left ctrl before (wasControlling)


void setup() {

  // put your setup code here, to run once:

  CircuitPlayground.begin();  // begin Circuit Playground

  firstLoop = false;          // reset boolean for getting default light value in play environment

  Keyboard.begin();           // begin Keyboard library

  Serial.begin(9600);         // begin Serial for debug

  delay(100);

}


void loop() {

  // put your main code here, to run repeatedly:


  int inputX = map(analogRead(A3), 0, 1023, -inputThreshold, inputThreshold);

  int inputY = map(analogRead(A6), 0, 1023, -inputThreshold, inputThreshold);

  int inputLight = map(analogRead(A7), 0, 1023, -6, 6);  // map later if necessary


  Serial.println(inputLight);

  // read value from right potentiometer


  // if value is greater than 0, "press" the right arrow key

  if (inputX > 0) {

    Keyboard.press(KEY_RIGHT_ARROW);

  }

  // if value is equal to 0, "relase" both left and right arrow keys and return

  if (inputX == 0) {

    Keyboard.release(KEY_RIGHT_ARROW);

    Keyboard.release(KEY_LEFT_ARROW);

  }

  // if value is less than 0, "press" the left arrow key

  if (inputX < 0) {

    Keyboard.press(KEY_LEFT_ARROW);

  }


  // read value from left potentiometer


  // if value is greater than 0, "press" the up arrow key

  if (inputY > 0) {

    Keyboard.press(KEY_UP_ARROW);

  }

  // if value is equal to 0, "release" the up and down arrow keys and return

  if (inputY == 0) {

    Keyboard.release(KEY_UP_ARROW);

    Keyboard.release(KEY_DOWN_ARROW);

  }

  // if value is less than 0, "press" the down arrow key

  if (inputY < 0) {

    Keyboard.press(KEY_DOWN_ARROW);

  }


  // read value from photoresistor


 // if value is greater than default reading, "press" the left ctrl key

  if (inputLight > 2) {

    Keyboard.press(KEY_LEFT_CTRL);

  }

  // if value is less than default reading, "release" the left ctrl key if it was pressed before

  if (inputLight < 5) {

    Keyboard.release(KEY_LEFT_CTRL);

  }

}

Video: 





No comments:

Post a Comment

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