From 9eec66654f1f07a4a2fea82537b5af16f8eba6ec Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Mon, 4 Jun 2018 15:57:52 +0100 Subject: [PATCH] Keyboard Manager updates * KeyboardManager.handler has been removed as it's no longer used internally. * The KeyboardManager.captures property has been removed as it can be more effectively handled by polling the `keys` object instead. * The Keyboard Manager will no longer process key down or up events if its `enabled` property is set to false. * The Keyboard Manager will now call `event.preventDefault` on the native DOM event as long as the Key exists in the keys array and has its `preventDefault` property set to `true` (which is the default). This means you can now control specifically which key prevents default on the browser, where-as before every key added did so. --- src/input/keyboard/KeyboardManager.js | 161 ++++++++++++++++---------- 1 file changed, 101 insertions(+), 60 deletions(-) diff --git a/src/input/keyboard/KeyboardManager.js b/src/input/keyboard/KeyboardManager.js index 30e9ac2a9..671851462 100644 --- a/src/input/keyboard/KeyboardManager.js +++ b/src/input/keyboard/KeyboardManager.js @@ -21,14 +21,36 @@ var ProcessKeyUp = require('./keys/ProcessKeyUp'); /** * @classdesc - * The Keyboard class monitors keyboard input and dispatches keyboard events. + * The Keyboard Manager is a helper class that belongs to the Input Manager. + * + * Its role is to listen for native DOM Keyboard Events and then process them. + * + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. + * + * You can access it from within a Scene using `this.input.keyboard`. For example, you can do: * - * _Note_: many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. + * ```javascript + * this.input.keyboard.on('keydown', callback, context); + * ``` + * + * Or, to listen for a specific key: + * + * ```javascript + * this.input.keyboard.on('keydown_A', callback, context); + * ``` + * + * You can also create Key objects, which you can then poll in your game loop: + * + * ```javascript + * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); + * ``` + * + * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. * See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details. * * Also please be aware that certain browser extensions can disable or override Phaser keyboard handling. - * For example the Chrome extension vimium is known to disable Phaser from using the D key. And there are others. - * So please check your extensions before opening Phaser issues. + * For example the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. + * And there are others. So, please check your extensions before opening Phaser issues about keys that don't work. * * @class KeyboardManager * @extends Phaser.Events.EventEmitter @@ -36,7 +58,7 @@ var ProcessKeyUp = require('./keys/ProcessKeyUp'); * @constructor * @since 3.0.0 * - * @param {Phaser.Input.InputManager} inputManager - [description] + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. */ var KeyboardManager = new Class({ @@ -49,7 +71,7 @@ var KeyboardManager = new Class({ EventEmitter.call(this); /** - * [description] + * A reference to the Input Manager. * * @name Phaser.Input.Keyboard.KeyboardManager#manager * @type {Phaser.Input.InputManager} @@ -58,7 +80,8 @@ var KeyboardManager = new Class({ this.manager = inputManager; /** - * [description] + * A boolean that controls if the Keyboard Manager is enabled or not. + * Can be toggled on the fly. * * @name Phaser.Input.Keyboard.KeyboardManager#enabled * @type {boolean} @@ -68,63 +91,43 @@ var KeyboardManager = new Class({ this.enabled = false; /** - * [description] + * The Keyboard Event target, as defined in the Game Config. + * Typically the browser window, but can be any interactive DOM element. * * @name Phaser.Input.Keyboard.KeyboardManager#target - * @type {?object} + * @type {any} * @since 3.0.0 */ this.target; /** - * [description] + * An array of Key objects to process. * * @name Phaser.Input.Keyboard.KeyboardManager#keys * @type {Phaser.Input.Keyboard.Key[]} - * @default [] * @since 3.0.0 */ this.keys = []; /** - * [description] + * An array of KeyCombo objects to process. * * @name Phaser.Input.Keyboard.KeyboardManager#combos * @type {Phaser.Input.Keyboard.KeyCombo[]} - * @default [] * @since 3.0.0 */ this.combos = []; - /** - * [description] - * - * @name Phaser.Input.Keyboard.KeyboardManager#captures - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.captures = []; - /** * [description] * * @name Phaser.Input.Keyboard.KeyboardManager#queue * @type {KeyboardEvent[]} - * @default [] + * @private * @since 3.0.0 */ this.queue = []; - /** - * [description] - * - * @name Phaser.Input.Keyboard.KeyboardManager#handler - * @type {?KeyboardHandler} - * @since 3.0.0 - */ - this.handler; - inputManager.events.once('boot', this.boot, this); }, @@ -132,6 +135,7 @@ var KeyboardManager = new Class({ * The Boot handler is called by Phaser.Game when it first starts up. * * @method Phaser.Input.Keyboard.KeyboardManager#boot + * @private * @since 3.0.0 */ boot: function () @@ -147,6 +151,58 @@ var KeyboardManager = new Class({ } }, + /** + * The Keyboard Down Event Handler. + * + * @method Phaser.Input.Keyboard.KeyboardManager#onKeyDown + * @since 3.10.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. + */ + onKeyDown: function (event) + { + if (event.defaultPrevented || !this.enabled) + { + // Do nothing if event already handled + return; + } + + this.queue.push(event); + + var key = this.keys[event.keyCode]; + + if (key && key.preventDefault) + { + event.preventDefault(); + } + }, + + /** + * The Keyboard Up Event Handler. + * + * @method Phaser.Input.Keyboard.KeyboardManager#onKeyUp + * @since 3.10.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. + */ + onKeyUp: function (event) + { + if (event.defaultPrevented || !this.enabled) + { + // Do nothing if event already handled + return; + } + + this.queue.push(event); + + var key = this.keys[event.keyCode]; + + if (key && key.preventDefault) + { + event.preventDefault(); + } + }, + /** * [description] * @@ -155,29 +211,8 @@ var KeyboardManager = new Class({ */ startListeners: function () { - var queue = this.queue; - var captures = this.captures; - - var handler = function (event) - { - if (event.defaultPrevented) - { - // Do nothing if event already handled - return; - } - - queue.push(event); - - if (captures[event.keyCode]) - { - event.preventDefault(); - } - }; - - this.handler = handler; - - this.target.addEventListener('keydown', handler, false); - this.target.addEventListener('keyup', handler, false); + this.target.addEventListener('keydown', this.onKeyDown.bind(this), false); + this.target.addEventListener('keyup', this.onKeyUp.bind(this), false); // Finally, listen for an update event from the Input Manager this.manager.events.on('update', this.update, this); @@ -191,8 +226,8 @@ var KeyboardManager = new Class({ */ stopListeners: function () { - this.target.removeEventListener('keydown', this.handler); - this.target.removeEventListener('keyup', this.handler); + this.target.removeEventListener('keydown', this.onKeyDown); + this.target.removeEventListener('keyup', this.onKeyUp); this.manager.events.off('update', this.update); }, @@ -271,10 +306,16 @@ var KeyboardManager = new Class({ { var keys = this.keys; + if (typeof keyCode === 'string') + { + keyCode = keyCodes[keyCode.toUpperCase()]; + } + if (!keys[keyCode]) { keys[keyCode] = new Key(keyCode); - this.captures[keyCode] = true; + + // this.captures[keyCode] = true; } return keys[keyCode]; @@ -293,7 +334,7 @@ var KeyboardManager = new Class({ if (this.keys[keyCode]) { this.keys[keyCode] = undefined; - this.captures[keyCode] = false; + // this.captures[keyCode] = false; } },