Home Reference Source Test

src/manager/InputManager.js

  1. import Manager from './Manager';
  2. import DOMManager from './DOMManager';
  3. import Messager from '../utils/Messager';
  4. import KeyCode from '../const/KeyCode';
  5. import { SceneManager, Point } from '../entry';
  6.  
  7. /**
  8. * A manager class intended to manage the javascript callback associated with the DOM.
  9. * The InputManager filters general DOM events such as key down, key up, left and right click.
  10. * The manager sorts events into referenceable lists for components to reference each game tick.
  11. *
  12. * In result, the InputManager creates a bridge between the DOM and Engine. Components should use the
  13. * `is` functions to determine if a specific character is down for that game tick.
  14. *
  15. * If you want to listen to all characters, for example a textbox input, use events instead. To listen to events,
  16. * use InputManager.events to access the event. Events are defined in InputManager.EVENT. See Messager.js for more info
  17. * on listening to events.
  18. */
  19. export class _InputManager extends Manager {
  20. /**
  21. * Constructor. Initializes Messager, event definitons, and
  22. * key and mouse states.
  23. */
  24. constructor() {
  25. super();
  26. this.events = new Messager();
  27. this.EVENT = {
  28. LEFT_PRESSED: 'mouseLeftPressed',
  29. LEFT_RELEASED: 'mouseLeftReleased',
  30. RIGHT_PRESSED: 'mouseRightPressed',
  31. RIGHT_RELEASED: 'mouseRightReleased',
  32. MOUSE_MOVE: 'mouseMove',
  33. KEY_DOWN: 'keyDown',
  34. KEY_UP: 'keyUp',
  35. KEY: 'keyDownRepeat',
  36. };
  37. this.KEY_DOWN = [];
  38. this.KEY_PRESSED = [];
  39. this.KEY_UP = [];
  40. this.LEFT_PRESSED = [];
  41. this.LEFT_RELEASED = [];
  42. this.RIGHT_PRESSED = [];
  43. this.RIGHT_RELEASED = [];
  44.  
  45. const AllKeys = 256;
  46. for (let i = 0; i < AllKeys; i++) {
  47. this.KEY_DOWN[i] = false;
  48. this.KEY_PRESSED[i] = false;
  49. this.KEY_UP[i] = false;
  50. }
  51. }
  52.  
  53. /**
  54. * Returns true if the key represented by this KeyCode is pressed down on
  55. * this game tick. Does not repeat each game tick. Must be released to re-trigger.
  56. * The `isKeyPressed()` will also return true when this function does.
  57. *
  58. * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
  59. *
  60. * @returns {boolean} Is this key down.
  61. */
  62. isKeyDown(KeyCode) {
  63. return this.KEY_DOWN[KeyCode];
  64. }
  65.  
  66. /**
  67. * Returns true if the key represented by this KeyCode is held down on
  68. * this game tick. Repeats each game tick it is held down.
  69. *
  70. * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
  71. *
  72. * @returns {boolean} Is this key pressed (held down).
  73. */
  74. isKeyPressed(KeyCode) {
  75. return this.KEY_PRESSED[KeyCode];
  76. }
  77.  
  78. /**
  79. * Returns true if the key represented by this KeyCode is released on
  80. * this game tick.
  81. *
  82. * @param {KeyCode} KeyCode Keycode enum which represents a character by number.
  83. *
  84. * @returns {boolean} Is this key released.
  85. */
  86. isKeyUp(KeyCode) {
  87. return this.KEY_UP[KeyCode];
  88. }
  89.  
  90. /**
  91. * Called by the EngineManager. Not intended to be referenced.
  92. * Sets up event listeners on the DOM.
  93. */
  94. start() {
  95. DOMManager.canvas.addEventListener('mouseup', (ev) => {
  96. ev.preventDefault();
  97. let event = {
  98. x: ev.offsetX * DOMManager.canvasDPIWidth,
  99. y: ev.offsetY * DOMManager.canvasDPIHeight,
  100. shiftHeld: ev.shiftKey,
  101. ctrlHeld: ev.ctrlKey,
  102. };
  103. let curScene = SceneManager.getCurrentScene();
  104. if (curScene != null) {
  105. for (let i = 0; i < curScene.viewports.length; i++) {
  106. if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
  107. let relEvent = Object.assign({}, event);
  108. relEvent.x -= curScene.viewports[i].getBounds().p1.x;
  109. relEvent.y -= curScene.viewports[i].getBounds().p1.y;
  110. if (ev.button == 0) {
  111. this.LEFT_RELEASED[i].push(relEvent);
  112. } else if (ev.button == 2) {
  113. this.RIGHT_RELEASED[i].push(relEvent);
  114. }
  115. }
  116. }
  117. }
  118. if (ev.button == 0) {
  119. this.events.set(this.EVENT.LEFT_RELEASED, event);
  120. } else if (ev.button == 2) {
  121. this.events.set(this.EVENT.RIGHT_RELEASED, event);
  122. }
  123. })
  124. DOMManager.canvas.addEventListener('mousedown', (ev) => {
  125. ev.preventDefault();
  126. let event = {
  127. x: ev.offsetX * DOMManager.canvasDPIWidth,
  128. y: ev.offsetY * DOMManager.canvasDPIHeight,
  129. shiftHeld: ev.shiftKey,
  130. ctrlHeld: ev.ctrlKey,
  131. };
  132. let curScene = SceneManager.getCurrentScene();
  133. if (curScene != null) {
  134. for (let i = 0; i < curScene.viewports.length; i++) {
  135. if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
  136. let relEvent = Object.assign({}, event);
  137. relEvent.x -= curScene.viewports[i].getBounds().p1.x;
  138. relEvent.y -= curScene.viewports[i].getBounds().p1.y;
  139. if (ev.button == 0) {
  140. this.LEFT_PRESSED[i].push(relEvent);
  141. } else if (ev.button == 2) {
  142. this.RIGHT_PRESSED[i].push(relEvent);
  143. }
  144. }
  145. }
  146. }
  147. if (ev.button == 0) {
  148. this.events.set(this.EVENT.LEFT_PRESSED, event);
  149. } else if (ev.button == 2) {
  150. this.events.set(this.EVENT.RIGHT_PRESSED, event);
  151. }
  152. })
  153.  
  154. DOMManager.canvas.addEventListener('mousemove', (ev) => {
  155. ev.preventDefault();
  156. let event = {
  157. x: ev.offsetX * DOMManager.canvasDPIWidth,
  158. y: ev.offsetY * DOMManager.canvasDPIHeight,
  159. shiftHeld: ev.shiftKey,
  160. ctrlHeld: ev.ctrlKey,
  161. };
  162. let curScene = SceneManager.getCurrentScene();
  163. if (curScene != null) {
  164. for (let i = 0; i < curScene.viewports.length; i++) {
  165. if (curScene.viewports[i].getBounds().isInBounds(new Point(event.x, event.y))) {
  166. event.x -= curScene.viewports[i].getBounds().p1.x;
  167. event.y -= curScene.viewports[i].getBounds().p1.y;
  168. event.viewport = i;
  169. break;
  170. }
  171. }
  172. }
  173. this.events.set(this.EVENT.MOUSE_MOVE, event);
  174. })
  175.  
  176. //right click manager
  177. DOMManager.canvas.oncontextmenu = (ev) => {
  178. ev.preventDefault();
  179. };
  180.  
  181. //Key down manager
  182. document.addEventListener('keydown', (event) => {
  183. event.preventDefault();
  184. let code = event.which || event.keyCode;
  185. this.KEY_PRESSED[code] = true;
  186. if (!event.repeat) {
  187. this.KEY_DOWN[code] = true;
  188. this.events.set(this.EVENT.KEY_DOWN, {
  189. key: event.key,
  190. code,
  191. shiftHeld: event.shiftKey,
  192. ctrlHeld: event.ctrlKey,
  193. repeat: event.repeat,
  194. });
  195. }
  196. this.events.set(this.EVENT.KEY, {
  197. key: event.key,
  198. code,
  199. shiftHeld: event.shiftKey,
  200. ctrlHeld: event.ctrlKey,
  201. repeat: event.repeat,
  202. });
  203. });
  204.  
  205. //Key up manager
  206. document.addEventListener('keyup', (event) => {
  207. event.preventDefault();
  208. let code = event.which || event.keyCode;
  209. this.KEY_DOWN[code] = false;
  210. this.KEY_PRESSED[code] = false;
  211. this.KEY_UP[code] = true;
  212. this.events.set(this.EVENT.KEY_UP, {
  213. key: event.key,
  214. code,
  215. shiftHeld: event.shiftKey,
  216. ctrlHeld: event.ctrlKey,
  217. repeat: event.repeat,
  218. });
  219. });
  220. }
  221.  
  222. /**
  223. * Managed by the EngineManager. Do not call directly. Updates character and mouse
  224. * inputs.
  225. */
  226. update() {
  227. this.KEY_DOWN = [];
  228. this.KEY_UP = [];
  229. this.LEFT_PRESSED = [];
  230. this.LEFT_RELEASED = [];
  231. this.RIGHT_PRESSED = [];
  232. this.RIGHT_RELEASED = [];
  233.  
  234. let scene = null;
  235. if ((scene = SceneManager.getCurrentScene()) == null)
  236. return;
  237.  
  238. for (let i = 0; i < scene.viewports.length; i++) {
  239. this.LEFT_PRESSED.push([]);
  240. this.LEFT_RELEASED.push([]);
  241. this.RIGHT_PRESSED.push([]);
  242. this.RIGHT_RELEASED.push([]);
  243. }
  244. }
  245. }
  246.  
  247. /**
  248. * Singleton reference to the Input Manager.
  249. */
  250. const InputManager = new _InputManager();
  251. export default InputManager;