class PlayerInput { constructor(name) { if (name !== undefined) { this.name = name; } else { this.name = "unnnamed"; } this.inputs = 1; this.state = false; this.lastState = false; this.value = 0; this.lastValue = 0; this.hasChanged = false; this.isPressed = false; this.justPressed = false; this.justReleased = false; this.lowerDeadZone = -0.15; this.upperDeadZone = 0.15; this.stateThreshold = 0.1; } updateState(newValue /* value of 0 - 1 */) { if (newValue > this.lowerDeadZone && newValue < this.upperDeadZone) newValue = 0; this.lastState = this.state; this.state = Math.abs(newValue) > this.stateThreshold; this.hasChanged = this.lastValue != newValue; this.lastValue = this.value; this.value = newValue; //was pressed on the last frame, is not now. this.justReleased = this.isPressed && !this.state; this.justPressed = !this.isPressed && this.state; this.isPressed = this.state; if (this.justReleased){ console.log(this.name + "was released" + " is pressed is "+this.isPressed) } } } class PlayerInput2D extends PlayerInput { constructor(name) { super(name); this.inputs = 2; this.x = 0; this.y = 0; } updateState(xValue, yValue) { if (xValue > this.lowerDeadZone && xValue < this.upperDeadZone) xValue = 0; if (yValue > this.lowerDeadZone && yValue < this.upperDeadZone) yValue = 0; this.lastState = this.state; this.state = Math.abs(xValue) > this.stateThreshold && Math.abs(yValue) > this.stateThreshold; this.hasChanged = this.lastX != xValue || this.lastY != yValue; this.lastX = this.x; this.x = xValue; this.lastY = this.y; this.y = yValue; //was pressed on the last frame, is not now. this.justReleased = this.isPressed && !this.state; this.justPressed = !this.isPressed && this.state; this.isPressed = this.state; } } class KeyboardInputBinding { constructor(playerInput, key, reverseKey) { this.playerInput = playerInput; this.key = key; this.reverseKey = reverseKey; this.isTwoAxis = false; } setTwoAxis(keyX, reverseKeyX, keyY, reverseKeyY) { this.isTwoAxis = true; this.keyX = keyX; this.reverseKeyX = reverseKeyX; this.keyY = keyY; this.reverseKeyY = reverseKeyY; } } class GamepadInputBinding { constructor(playerInput, button, isAxis) { this.playerInput = playerInput; this.button = button; this.isTwoAxis = false; if (isAxis === undefined) isAxis = false; this.isAxis = isAxis; } setTwoAxis(axisX, axisY) { this.isTwoAxis = true; this.axisX = axisX; this.axisY = axisY; } } class InputBindingSet { constructor() { this.bindings = []; this.bindingsByName = {}; this.activeBindingsByName = {}; this.hasChanged = false; } getInput(name) { if (this.bindingsByName[name] !== undefined) { var activeBinding = this.activeBindingsByName[name]; for (var i = 0; i < this.bindingsByName[name].length; i++) { if (this.bindingsByName[name][i].playerInput.hasChanged) { this.activeBindingsByName[name] = this.bindingsByName[name][i]; } } if (activeBinding === undefined) activeBinding = this.bindingsByName[name][0]; return activeBinding.playerInput; } return null; } addBinding(binding) { this.bindings.push(binding); if (this.bindingsByName[binding.playerInput.name] === undefined) { this.bindingsByName[binding.playerInput.name] = []; } var bindings = this.bindingsByName[binding.playerInput.name]; if (bindings.indexOf(binding) == -1) { bindings.push(binding); } } update() { //impliment in extended class } } class KeyboardInputBindingSet extends InputBindingSet { constructor() { super(); } createInputBinding(name, key, reverseKey) { var input = new PlayerInput(name); var binding = this.createBinding(input, key, reverseKey); return binding; } createTwoAxisInputBinding(name, keyX, reverseKeyX, keyY, reverseKeyY) { var input = new PlayerInput2D(name); var binding = this.createBinding(input, keyX, reverseKeyX); binding.setTwoAxis(keyX, reverseKeyX, keyY, reverseKeyY); return binding; } createBinding(playerInput, key, reverseKey) { var newBinding = new KeyboardInputBinding(playerInput, key, reverseKey); this.addBinding(newBinding); return newBinding; } update() { this.hasChanged = false; var keyStates = KeyboardManager.keyStates; for (var i = 0; i < this.bindings.length; i++) { if (this.bindings[i].isTwoAxis) { this.bindings[i].playerInput.updateState(keyStates[this.bindings[i].keyX] - keyStates[this.bindings[i].reverseKeyX], keyStates[this.bindings[i].keyY] - keyStates[this.bindings[i].reverseKeyY]); } else if (this.bindings[i].reverseKey) { this.bindings[i].playerInput.updateState(keyStates[this.bindings[i].key] - keyStates[this.bindings[i].reverseKey]); } else { this.bindings[i].playerInput.updateState(keyStates[this.bindings[i].key]); } if (this.bindings[i].playerInput.hasChanged) this.hasChanged = true; } } } class GamepadInputBindingSet extends InputBindingSet { constructor(gamePadIndex) { super(); this.gamePadIndex = gamePadIndex; } createInputBinding(name, button, isAxis) { var input = new PlayerInput(name); var binding = this.createBinding(input, button, isAxis); return binding; } createTwoAxisInputBinding(name, axisX, axisY) { var input = new PlayerInput2D(name); var binding = this.createBinding(input, axisX, true); binding.setTwoAxis(axisX, axisY); return binding; } createBinding(playerInput, button, isAxis) { var newBinding = new GamepadInputBinding(playerInput, button, isAxis); this.addBinding(newBinding); return newBinding; } update() { this.hasChanged = false; GamepadManager.scangamepads(); var controller = GamepadManager.controllers[this.gamePadIndex]; if (controller === undefined || controller == null) return; for (var i = 0; i < this.bindings.length; i++) { if (!this.bindings[i].isAxis) { var val = controller.buttons[this.bindings[i].button]; var pressed = val == 1.0; if (typeof(val) == "object") { pressed = val.pressed; val = val.value; } this.bindings[i].playerInput.updateState(val); } else { if (this.bindings[i].isTwoAxis) { this.bindings[i].playerInput.updateState(controller.axes[this.bindings[i].axisX], controller.axes[this.bindings[i].axisY]); } else { this.bindings[i].playerInput.updateState(controller.axes[this.bindings[i].button]); } } if (this.bindings[i].playerInput.hasChanged) this.hasChanged = true; } } }