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;
}
}
}