Skip to content

Instantly share code, notes, and snippets.

@annibal
Created August 14, 2019 23:04
Show Gist options
  • Save annibal/e5d7c1579be0fdb040655c6ce6d9a9e9 to your computer and use it in GitHub Desktop.
Save annibal/e5d7c1579be0fdb040655c6ce6d9a9e9 to your computer and use it in GitHub Desktop.
Javascript input mapper
const getKey = inputName => (inputs[namedIndexesMap[inputName]] || {value:null}).value
//TODO gamepad
class InputMap {
constructor(inputName, type='', assignedKeyboardKeys=[], assignedGamepadButtons=[], assignedGamepadAxis=[]) {
const strArrayToKeyObj = arr => arr.reduce( (all,curr) => ({...all, [curr]: true}),{})
if (inputName == null) {
throw TypeError("Input Name cannot be null or undefined ")
}
this.inputName = inputName.toLowerCase()
this.type = type.toLowerCase()
if (this.type != "button" && this.type != "axis") {
throw TypeError("Input Type must be either BUTTON or AXIS")
}
this.assignedKeyboardKeys = strArrayToKeyObj(assignedKeyboardKeys)
// this.assignedGamepadButtons = strArrayToKeyObj(assignedGamepadButtons)
// this.assignedGamepadAxis = strArrayToKeyObj(assignedGamepadAxis)
this.value = 0
this.getValue = this.getValue.bind(this)
}
keyboardMatch = (key) => !!this.assignedKeyboardKeys[key.toLowerCase()] //unused
// gamepadButtonMatch = (idx) => !!this.assignedKeyboardKeys[key]
// TODO handle growing and decreasing
setButtonValue = (value, pressed) => {
this.value = +pressed
}
setAxisValue = (value, pressed) => {
this.value = +pressed
}
valueSetter = {
"button": this.setButtonValue,
"axis": this.setAxisValue
}
updateValue = (value, pressed = false) => this.valueSetter[this.type](value, pressed)
getValue = () => this.value
}
const inputs = [
new InputMap('forward', 'BUTTON', ['w', 'ArrowUp']),
new InputMap('backward', 'BUTTON', ['s', 'ArrowDown']),
new InputMap('left', 'BUTTON', ['a', 'ArrowLeft']),
new InputMap('right', 'BUTTON', ['b', 'ArrowRight']),
new InputMap('confirm', 'BUTTON', ['Enter', ' ', 'e']),
new InputMap('cancel', 'BUTTON', ['Escape', 'Backspace', 'Delete']),
]
// maps all assigned keys to the index on array "inputs"
const mapAssignedIndexes = inputs => inputs.reduce( (all,curr, idx) => ({
...all,
...Object.keys(curr.assignedKeyboardKeys).reduce( (_all,_curr) => ({
..._all,
[_curr.toLowerCase()]: idx
}), {})
}), {})
// maps all assigned keys to the index on array "inputs"
const mapNamedIndexes = inputs => inputs.reduce((all, curr, idx) => ({
...all,
[curr.inputName]: idx
}), {})
// save that value. if a code changes *inputs*, remap them like this
let assignedIndexesMap = {}
let namedIndexesMap = {}
const updateInputIndexes = () => {
assignedIndexesMap = mapAssignedIndexes(inputs)
namedIndexesMap = mapNamedIndexes(inputs)
}
updateInputIndexes()
console.log({ assignedIndexesMap, namedIndexesMap })
// finds the index by the key, checks if not null, updates
const updateFromAssignMap = (key, pressed, value=1) => {
const index = assignedIndexesMap[key.toLowerCase()]
if (index != null && index < inputs.length) {
inputs[index].updateValue(value,pressed)
}
}
document.addEventListener("keydown", event => {
updateFromAssignMap(event.key, true)
document.dispatchEvent(new Event("inputdown"))
document.dispatchEvent(new Event("inputchange"))
})
document.addEventListener("keyup", event => {
updateFromAssignMap(event.key, false)
document.dispatchEvent(new Event("inputup"))
document.dispatchEvent(new Event("inputchange"))
})
// document.addEventListener("inputchange", event => {
// console.log(getKey("forward"))
// })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment