UNPKG

@theatrejs/theatrejs

Version:

🎮 A JavaScript 2D Game Engine focused on creating pixel art games.

330 lines (239 loc) • 10.7 kB
import {EVENT_CODES, EVENT_TYPES, EventGamepadAnalog, EventGamepadDigital, EventGravityAnalog, EventGravityDigital, EventGyroscopeAnalog, EventGyroscopeDigital, EventPointerAnalog, EventPointerDigital, Stage, System} from '../index.js'; /** * Creates input systems. * * @example * * const system = new SystemInput({$container}); * system.initiate(); * system.tick(); */ class SystemInput extends System { /** * Stores the container. * @type {HTMLElement} * @private */ $container; /** * Stores the input events. * @type {Array<Event>} * @private */ $events; /** * Stores the state of the accepted inputs. * @type {Object<string, boolean>} * @private */ $inputs; /** * Stores the state of the accepted analog inputs. * @type {Object<string, number>} * @private */ $inputsAnalog; /** * Creates a new input system. * @param {object} $parameters The given parameters. * @param {HTMLElement} $parameters.$container The container on which to attach input events. */ constructor({$container}) { super(); this.$container = $container; } /** * Stacks the input events for the next tick. * @param {Event} $event The input event to stack. * @private */ $stack($event) { $event.preventDefault(); this.$events.push($event); } /** * Gets the current input state value of the given digital input. * @param {string} $input The event code of the given digital input. * @returns {boolean} * @public */ getInput($input) { const input = this.$inputs[$input]; if (typeof input === 'undefined') { return false; } return input; } /** * Gets the current input state value of the given analog input. * @param {string} $input The event code of the given analog input. * @returns {number} * @public */ getInputAnalog($input) { const input = this.$inputsAnalog[$input]; if (typeof input === 'undefined') { return 0; } return input; } /** * Called when the system is being initiated. * @public */ onInitiate() { this.$events = []; this.$inputs = {}; this.$inputsAnalog = {}; window.addEventListener(EVENT_TYPES.NATIVE.BLUR, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.NATIVE.CONTEXT_MENU, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_ANALOG, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_CONNECT, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_DOWN, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_UP, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GRAVITY.GRAVITY_ANALOG, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GRAVITY.GRAVITY_DOWN, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GRAVITY.GRAVITY_UP, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_ANALOG, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_DOWN, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_UP, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.POINTER.POINTER_ANALOG, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.POINTER.POINTER_DOWN, this.$stack.bind(this)); window.addEventListener(EVENT_TYPES.POINTER.POINTER_UP, this.$stack.bind(this)); this.$container.addEventListener(EVENT_TYPES.KEYBOARD.KEY_DOWN, this.$stack.bind(this)); this.$container.addEventListener(EVENT_TYPES.KEYBOARD.KEY_UP, this.$stack.bind(this)); } /** * Called when the system is being terminated. * @returns {(undefined | Promise<void>)} * @public */ onTerminate() { window.removeEventListener(EVENT_TYPES.NATIVE.BLUR, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.NATIVE.CONTEXT_MENU, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_ANALOG, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_CONNECT, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_DOWN, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GAMEPAD.GAMEPAD_UP, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GRAVITY.GRAVITY_ANALOG, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GRAVITY.GRAVITY_DOWN, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GRAVITY.GRAVITY_UP, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_ANALOG, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_DOWN, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.GYROSCOPE.GYROSCOPE_UP, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.POINTER.POINTER_ANALOG, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.POINTER.POINTER_DOWN, this.$stack.bind(this)); window.removeEventListener(EVENT_TYPES.POINTER.POINTER_UP, this.$stack.bind(this)); this.$container.removeEventListener(EVENT_TYPES.KEYBOARD.KEY_DOWN, this.$stack.bind(this)); this.$container.removeEventListener(EVENT_TYPES.KEYBOARD.KEY_UP, this.$stack.bind(this)); return undefined; } /** * Called when the system is being updated by one tick update. * @param {object} $parameters The given parameters. * @param {Stage} $parameters.$stage The stage on which to execute the system. * @param {number} $parameters.$timetick The tick duration (in ms). * @public */ onTick({$stage, $timetick}) { void $stage; void $timetick; if (typeof this.$inputs[EVENT_CODES.GAMEPAD_STANDARD.CONNECTED] !== 'undefined') { delete this.$inputs[EVENT_CODES.GAMEPAD_STANDARD.CONNECTED]; } if (typeof this.$inputs[EVENT_CODES.GAMEPAD_STANDARD.DISCONNECTED] !== 'undefined') { delete this.$inputs[EVENT_CODES.GAMEPAD_STANDARD.DISCONNECTED]; } while (this.$events.length > 0) { const $event = this.$events.shift(); if ($event.type === EVENT_TYPES.NATIVE.BLUR) { this.$inputs = {}; this.$inputsAnalog = {}; } else if ($event instanceof EventGamepadAnalog && $event.type === EVENT_TYPES.GAMEPAD.GAMEPAD_ANALOG) { this.$inputsAnalog[$event.code] = $event.value; } else if ($event instanceof EventGamepadDigital && $event.type === EVENT_TYPES.GAMEPAD.GAMEPAD_CONNECT) { this.$inputs[$event.code] = true; } else if ($event instanceof EventGamepadDigital && $event.type === EVENT_TYPES.GAMEPAD.GAMEPAD_DOWN) { if (typeof this.$inputs[$event.code] === 'undefined') { this.$inputs[$event.code] = true; } } else if ($event instanceof EventGamepadDigital && $event.type === EVENT_TYPES.GAMEPAD.GAMEPAD_UP) { if (typeof this.$inputs[$event.code] !== 'undefined') { delete this.$inputs[$event.code]; } } else if ($event instanceof EventGravityAnalog && $event.type === EVENT_TYPES.GRAVITY.GRAVITY_ANALOG) { this.$inputsAnalog[$event.code] = $event.value; } else if ($event instanceof EventGravityDigital && $event.type === EVENT_TYPES.GRAVITY.GRAVITY_DOWN) { if (typeof this.$inputs[$event.code] === 'undefined') { this.$inputs[$event.code] = true; } } else if ($event instanceof EventGravityDigital && $event.type === EVENT_TYPES.GRAVITY.GRAVITY_UP) { if (typeof this.$inputs[$event.code] !== 'undefined') { delete this.$inputs[$event.code]; } } else if ($event instanceof EventGyroscopeAnalog && $event.type === EVENT_TYPES.GYROSCOPE.GYROSCOPE_ANALOG) { this.$inputsAnalog[$event.code] = $event.value; } else if ($event instanceof EventGyroscopeDigital && $event.type === EVENT_TYPES.GYROSCOPE.GYROSCOPE_DOWN) { if (typeof this.$inputs[$event.code] === 'undefined') { this.$inputs[$event.code] = true; } } else if ($event instanceof EventGyroscopeDigital && $event.type === EVENT_TYPES.GYROSCOPE.GYROSCOPE_UP) { if (typeof this.$inputs[$event.code] !== 'undefined') { delete this.$inputs[$event.code]; } } else if ($event instanceof KeyboardEvent && $event.type === EVENT_TYPES.KEYBOARD.KEY_DOWN) { if (typeof this.$inputs[$event.code] === 'undefined') { this.$inputs[$event.code] = true; } } else if ($event instanceof KeyboardEvent && $event.type === EVENT_TYPES.KEYBOARD.KEY_UP) { if (typeof this.$inputs[$event.code] !== 'undefined') { delete this.$inputs[$event.code]; } } else if ($event instanceof EventPointerAnalog && $event.type === EVENT_TYPES.POINTER.POINTER_ANALOG) { this.$inputsAnalog[$event.code] = $event.value; } else if ($event instanceof EventPointerDigital && $event.type === EVENT_TYPES.POINTER.POINTER_DOWN) { if (typeof this.$inputs[$event.code] === 'undefined') { this.$inputs[$event.code] = true; } } else if ($event instanceof EventPointerDigital && $event.type === EVENT_TYPES.POINTER.POINTER_UP) { if (typeof this.$inputs[$event.code] !== 'undefined') { delete this.$inputs[$event.code]; } } } } } export { SystemInput }; export default SystemInput;