Controls and Bindings - rogerscg/era-engine GitHub Wiki

The ERA Engine gives you better control over user input handling, such as forwarding input to specific entities, setting custom bindings, controller support, and split screen support.

There are a few terms to be familiar with when using the ERA Engine:
Action - Labels for things that an entity can do, such as FORWARD, BACKWARD, FIRE, ROLL, etc.
Bindings - The set of actions and their inputs associated with an entity
Input Type - The user input type, such as Keyboard, Mouse, Controller, etc.
Keys - The input value (keycode, button code, axes code) for a particular action

Bindings and Actions

At the heart of the controls schema are the Bindings and Action objects. These classes are essentially wrappers around an object defined by the developer:

const ENTITY_BINDINGS = {
  FORWARD: {
    keys: {
      keyboard: 87,
      controller: '-axes1',
    }
  },
  BACKWARD: {
    keys: {
      keyboard: 83,
      controller: '+axes1',
    }
  },
  
  FIRE: {
    keys: {
      keyboard: 32,
      controller: 'button0',
    }
  },
}

In the example above, the entire object ENTITY_BINDINGS is the Bindings object. FORWARD, BACKWARD, and FIRE are the Actions the entity can perform, and the keys object dictate how that Action is triggered.

Let's look at the FORWARD action. We can see that the keyboard input is 87, the keycode for the W key. For the controller input, we see a value of -axes1. This represents the left joystick in the "up" direction. If we wanted the value of axes1 in any direction, we would omit the sign before axes1.

For entity-specific handling of input, please read the Controls section of the Entity page.

Split Screen/Local Co-op

If you want to support multiple local players playing your game, the ERA Engine can help. Simply add the split_screen: true field to your Action:

const ENTITY_BINDINGS = {
  BACKWARD: {
    keys: {
      keyboard: [83, 71, 75, 40],
      controller: '+axes1',
    },
    split_screen: true,
  },
  FORWARD: {
    keys: {
      keyboard: [87, 84, 73, 38],
      controller: '-axes1',
    },
    split_screen: true,
  },
}

You'll notice that there is an array of keycodes for the keyboard input type, but controller remains the same. This is because the ERA engine expects each player to have their own controller, while a single keyboard is indistinguishable from having multiple keyboards plugged in.

Custom Bindings

Your users and players will often want to customize the default bindings you have in place. ERA can help with that. Within the Controls library, there is a set of functions that allow you to set custom keys for every granularity of Bindings and Actions.

Controls.get().setCustomBinding(controlsId, action, inputType, key);

Where controlsId is the ID of the Entity bindings.

If the user wants to reset their bindings to default, there are also functions for that:

Controls.get().clearAllCustomBindings();

Will clear all custom bindings for the user for all IDs, Actions, and Input Types,

Controls.get().clearCustomBindingsForEntity(controlsId);

Will clear all custom bindings for a given Entity,

Controls.get().clearCustomBindingsForAction(controlsId, actionName, inputType);

Will clear custom bindings for given Entity's action. If not input type is specified, all custom bindings are cleared for that action.

Registering Entities

Once you have your bindings defined for an Entity, you will need to register instances for control. Let's say you've made an instance of Ball and want the user to control it. You would use:

Controls.get().registerEntity(ball);  

Likewise, if you would like to release control of an entity, call:

Controls.get().unregisterEntity(ball);  

Notes

  • An example page of how to handle custom player bindings + UI would be incredibly helpful to ERA Engine users.
  • Currently, mouse movement is completely neglected in documentation and in the engine. We need to have a better example of using it, both for PointerLock and for point-and-click use cases.