src/manager/InputManager.js
- import Manager from './Manager';
- import DOMManager from './DOMManager';
- import Messager from '../utils/Messager';
- import KeyCode from '../const/KeyCode';
- import { SceneManager, Point } from '../entry';
-
- /**
- * A manager class intended to manage the javascript callback associated with the DOM.
- * The InputManager filters general DOM events such as key down, key up, left and right click.
- * The manager sorts events into referenceable lists for components to reference each game tick.
- *
- * In result, the InputManager creates a bridge between the DOM and Engine. Components should use the
- * `is` functions to determine if a specific character is down for that game tick.
- *
- * If you want to listen to all characters, for example a textbox input, use events instead. To listen to events,
- * use InputManager.events to access the event. Events are defined in InputManager.EVENT. See Messager.js for more info
- * on listening to events.
- */
- export class _InputManager extends Manager {
- /**
- * Constructor. Initializes Messager, event definitons, and
- * key and mouse states.
- */
- constructor() {
- super();
- this.events = new Messager();
- this.EVENT = {
- LEFT_PRESSED: 'mouseLeftPressed',
- LEFT_RELEASED: 'mouseLeftReleased',
- RIGHT_PRESSED: 'mouseRightPressed',
- RIGHT_RELEASED: 'mouseRightReleased',
- MOUSE_MOVE: 'mouseMove',
- KEY_DOWN: 'keyDown',
- KEY_UP: 'keyUp',
- KEY: 'keyDownRepeat',
- };
- this.KEY_DOWN = [];
- this.KEY_PRESSED = [];
- this.KEY_UP = [];
- this.LEFT_PRESSED = [];
- this.LEFT_RELEASED = [];
- this.RIGHT_PRESSED = [];
- this.RIGHT_RELEASED = [];
-
- const AllKeys = 256;
- for (let i = 0; i < AllKeys; i++) {
- this.KEY_DOWN[i] = false;
- this.KEY_PRESSED[i] = false;
- this.KEY_UP[i] = false;
- }
- }
-
- /**
- * Returns true if the key represented by this KeyCode is pressed down on
- * this game tick. Does not repeat each game tick. Must be released to re-trigger.
- * The `isKeyPressed()` will also return true when this function does.
- *
- * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
- *
- * @returns {boolean} Is this key down.
- */
- isKeyDown(KeyCode) {
- return this.KEY_DOWN[KeyCode];
- }
-
- /**
- * Returns true if the key represented by this KeyCode is held down on
- * this game tick. Repeats each game tick it is held down.
- *
- * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
- *
- * @returns {boolean} Is this key pressed (held down).
- */
- isKeyPressed(KeyCode) {
- return this.KEY_PRESSED[KeyCode];
- }
-
- /**
- * Returns true if the key represented by this KeyCode is released on
- * this game tick.
- *
- * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
- *
- * @returns {boolean} Is this key released.
- */
- isKeyUp(KeyCode) {
- return this.KEY_UP[KeyCode];
- }
-
- /**
- * Called by the EngineManager. Not intended to be referenced.
- * Sets up event listeners on the DOM.
- */
- start() {
- DOMManager.canvas.addEventListener('mouseup', (ev) => {
- ev.preventDefault();
- let event = {
- x: ev.offsetX * DOMManager.canvasDPIWidth,
- y: ev.offsetY * DOMManager.canvasDPIHeight,
- shiftHeld: ev.shiftKey,
- ctrlHeld: ev.ctrlKey,
- };
- let curScene = SceneManager.getCurrentScene();
- if (curScene != null) {
- for (let i = 0; i < curScene.viewports.length; i++) {
- if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
- let relEvent = Object.assign({}, event);
- relEvent.x -= curScene.viewports[i].getBounds().p1.x;
- relEvent.y -= curScene.viewports[i].getBounds().p1.y;
- if (ev.button == 0) {
- this.LEFT_RELEASED[i].push(relEvent);
- } else if (ev.button == 2) {
- this.RIGHT_RELEASED[i].push(relEvent);
- }
- }
- }
- }
- if (ev.button == 0) {
- this.events.set(this.EVENT.LEFT_RELEASED, event);
- } else if (ev.button == 2) {
- this.events.set(this.EVENT.RIGHT_RELEASED, event);
- }
- })
- DOMManager.canvas.addEventListener('mousedown', (ev) => {
- ev.preventDefault();
- let event = {
- x: ev.offsetX * DOMManager.canvasDPIWidth,
- y: ev.offsetY * DOMManager.canvasDPIHeight,
- shiftHeld: ev.shiftKey,
- ctrlHeld: ev.ctrlKey,
- };
- let curScene = SceneManager.getCurrentScene();
- if (curScene != null) {
- for (let i = 0; i < curScene.viewports.length; i++) {
- if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
- let relEvent = Object.assign({}, event);
- relEvent.x -= curScene.viewports[i].getBounds().p1.x;
- relEvent.y -= curScene.viewports[i].getBounds().p1.y;
- if (ev.button == 0) {
- this.LEFT_PRESSED[i].push(relEvent);
- } else if (ev.button == 2) {
- this.RIGHT_PRESSED[i].push(relEvent);
- }
- }
- }
- }
- if (ev.button == 0) {
- this.events.set(this.EVENT.LEFT_PRESSED, event);
- } else if (ev.button == 2) {
- this.events.set(this.EVENT.RIGHT_PRESSED, event);
- }
- })
-
- DOMManager.canvas.addEventListener('mousemove', (ev) => {
- ev.preventDefault();
- let event = {
- x: ev.offsetX * DOMManager.canvasDPIWidth,
- y: ev.offsetY * DOMManager.canvasDPIHeight,
- shiftHeld: ev.shiftKey,
- ctrlHeld: ev.ctrlKey,
- };
- let curScene = SceneManager.getCurrentScene();
- if (curScene != null) {
- for (let i = 0; i < curScene.viewports.length; i++) {
- if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
- event.x -= curScene.viewports[i].getBounds().p1.x;
- event.y -= curScene.viewports[i].getBounds().p1.y;
- event.viewport = i;
- break;
- }
- }
- }
- this.events.set(this.EVENT.MOUSE_MOVE, event);
- })
-
- //right click manager
- DOMManager.canvas.oncontextmenu = (ev) => {
- ev.preventDefault();
- };
-
- //Key down manager
- document.addEventListener('keydown', (event) => {
- event.preventDefault();
- let code = event.which || event.keyCode;
- this.KEY_PRESSED[code] = true;
- if (!event.repeat) {
- this.KEY_DOWN[code] = true;
- this.events.set(this.EVENT.KEY_DOWN, {
- key: event.key,
- code,
- shiftHeld: event.shiftKey,
- ctrlHeld: event.ctrlKey,
- repeat: event.repeat,
- });
- }
- this.events.set(this.EVENT.KEY, {
- key: event.key,
- code,
- shiftHeld: event.shiftKey,
- ctrlHeld: event.ctrlKey,
- repeat: event.repeat,
- });
- });
-
- //Key up manager
- document.addEventListener('keyup', (event) => {
- event.preventDefault();
- let code = event.which || event.keyCode;
- this.KEY_DOWN[code] = false;
- this.KEY_PRESSED[code] = false;
- this.KEY_UP[code] = true;
- this.events.set(this.EVENT.KEY_UP, {
- key: event.key,
- code,
- shiftHeld: event.shiftKey,
- ctrlHeld: event.ctrlKey,
- repeat: event.repeat,
- });
- });
- }
-
- /**
- * Managed by the EngineManager. Do not call directly. Updates character and mouse
- * inputs.
- */
- update() {
- this.KEY_DOWN = [];
- this.KEY_UP = [];
- this.LEFT_PRESSED = [];
- this.LEFT_RELEASED = [];
- this.RIGHT_PRESSED = [];
- this.RIGHT_RELEASED = [];
-
- let scene = null;
- if ((scene = SceneManager.getCurrentScene()) == null)
- return;
-
- for (let i = 0; i < scene.viewports.length; i++) {
- this.LEFT_PRESSED.push([]);
- this.LEFT_RELEASED.push([]);
- this.RIGHT_PRESSED.push([]);
- this.RIGHT_RELEASED.push([]);
- }
- }
- }
-
- /**
- * Singleton reference to the Input Manager.
- */
- const InputManager = new _InputManager();
- export default InputManager;