mirror of
https://github.com/photonstorm/phaser
synced 2024-11-27 15:12:18 +00:00
Added capture handling and event queue.
This commit is contained in:
parent
a7fba605ad
commit
114d61cf59
1 changed files with 254 additions and 49 deletions
|
@ -4,17 +4,19 @@
|
|||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var ArrayRemove = require('../../utils/array/Remove');
|
||||
var Class = require('../../utils/Class');
|
||||
var Features = require('../../device/Features');
|
||||
var KeyCodes = require('../../input/keyboard/keys/KeyCodes');
|
||||
var NOOP = require('../../utils/Class');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* The Keyboard Manager is a helper class that belongs to the Input Manager.
|
||||
* The Keyboard Manager is a helper class that belongs to the global Input Manager.
|
||||
*
|
||||
* Its role is to listen for native DOM Keyboard Events and then pass them onto the Input Manager for further processing.
|
||||
* Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin.
|
||||
*
|
||||
* You do not need to create this class directly, the Input Manager will create an instance of it automatically.
|
||||
* You do not need to create this class directly, the Input Manager will create an instance of it automatically if keyboard
|
||||
* input has been enabled in the Game Config.
|
||||
*
|
||||
* @class KeyboardManager
|
||||
* @memberof Phaser.Input.Keyboard
|
||||
|
@ -39,14 +41,59 @@ var KeyboardManager = new Class({
|
|||
this.manager = inputManager;
|
||||
|
||||
/**
|
||||
* If true the DOM keyboard events will have event.preventDefault applied to them, if false they will propagate fully.
|
||||
* An internal event queue.
|
||||
*
|
||||
* @name Phaser.Input.Keyboard.KeyboardManager#capture
|
||||
* @type {boolean}
|
||||
* @default true
|
||||
* @name Phaser.Input.Keyboard.KeyboardManager#queue
|
||||
* @type {KeyboardEvent[]}
|
||||
* @private
|
||||
* @since 3.16.0
|
||||
*/
|
||||
this.capture = true;
|
||||
this.queue = [];
|
||||
|
||||
/**
|
||||
* A flag that controls if the non-modified keys, matching those stored in the `captures` array,
|
||||
* have `preventDefault` called on them or not.
|
||||
*
|
||||
* A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are
|
||||
* shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows).
|
||||
* Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier.
|
||||
* However, if the user presses just the r key on its own, it will have its event prevented.
|
||||
*
|
||||
* If you wish to stop capturing the keys, for example switching out to a DOM based element, then
|
||||
* you can toggle this property at run-time.
|
||||
*
|
||||
* @name Phaser.Input.Keyboard.KeyboardManager#preventDefault
|
||||
* @type {boolean}
|
||||
* @since 3.16.0
|
||||
*/
|
||||
this.preventDefault = true;
|
||||
|
||||
/**
|
||||
* An array of Key Code values that will automatically have `preventDefault` called on them,
|
||||
* as long as the `KeyboardManager.preventDefault` boolean is set to `true`.
|
||||
*
|
||||
* By default the array contains: The Space Key, the Cursor Keys, 0 to 9 and A to Z.
|
||||
*
|
||||
* The key must be non-modified when pressed in order to be captured.
|
||||
*
|
||||
* A non-modified key is one that doesn't have a modifier key held down with it. The modifier keys are
|
||||
* shift, control, alt and the meta key (Command on a Mac, the Windows Key on Windows).
|
||||
* Therefore, if the user presses shift + r, it won't prevent this combination, because of the modifier.
|
||||
* However, if the user presses just the r key on its own, it will have its event prevented.
|
||||
*
|
||||
* If you wish to stop capturing the keys, for example switching out to a DOM based element, then
|
||||
* you can toggle the `KeyboardManager.preventDefault` boolean at run-time.
|
||||
*
|
||||
* If you need more specific control, you can create Key objects and set the flag on each of those instead.
|
||||
*
|
||||
* This array can be populated via the Game Config by setting the `input.keyboard.capture` array, or you
|
||||
* can call the `addCapture` method. See also `removeCapture` and `clearCaptures`.
|
||||
*
|
||||
* @name Phaser.Input.Keyboard.KeyboardManager#captures
|
||||
* @type {integer[]}
|
||||
* @since 3.16.0
|
||||
*/
|
||||
this.captures = [];
|
||||
|
||||
/**
|
||||
* A boolean that controls if the Keyboard Manager is enabled or not.
|
||||
|
@ -61,7 +108,7 @@ var KeyboardManager = new Class({
|
|||
|
||||
/**
|
||||
* The Keyboard Event target, as defined in the Game Config.
|
||||
* Typically the canvas to which the game is rendering, but can be any interactive DOM element.
|
||||
* Typically the window in which the game is rendering, but can be any interactive DOM element.
|
||||
*
|
||||
* @name Phaser.Input.Keyboard.KeyboardManager#target
|
||||
* @type {any}
|
||||
|
@ -105,23 +152,26 @@ var KeyboardManager = new Class({
|
|||
{
|
||||
var config = this.manager.config;
|
||||
|
||||
// this.enabled = config.inputMouse;
|
||||
// this.target = config.inputMouseEventTarget;
|
||||
// this.capture = config.inputMouseCapture;
|
||||
this.enabled = config.inputKeyboard;
|
||||
this.target = config.inputKeyboardEventTarget;
|
||||
|
||||
if (!this.target)
|
||||
this.addCapture(config.inputKeyboardCapture);
|
||||
|
||||
if (!this.target && window)
|
||||
{
|
||||
this.target = this.manager.game.canvas;
|
||||
this.target = window;
|
||||
}
|
||||
|
||||
if (this.enabled && this.target)
|
||||
{
|
||||
this.startListeners();
|
||||
}
|
||||
|
||||
this.manager.game.events.on('poststep', this.postUpdate, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the Mouse Event listeners running.
|
||||
* Starts the Keyboard Event listeners running.
|
||||
* This is called automatically and does not need to be manually invoked.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#startListeners
|
||||
|
@ -130,25 +180,26 @@ var KeyboardManager = new Class({
|
|||
startListeners: function ()
|
||||
{
|
||||
var _this = this;
|
||||
var canvas = this.manager.canvas;
|
||||
|
||||
this.onMouseDown = function (event)
|
||||
this.onKeyDown = function (event)
|
||||
{
|
||||
if (event.defaultPrevented || !_this.enabled || !_this.manager)
|
||||
{
|
||||
// Do nothing if event already handled
|
||||
return;
|
||||
}
|
||||
|
||||
_this.queue.push(event);
|
||||
|
||||
_this.manager.queueMouseDown(event);
|
||||
|
||||
if (_this.capture && event.target === canvas)
|
||||
var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey);
|
||||
|
||||
if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1)
|
||||
{
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
this.onMouseUp = function (event)
|
||||
this.onKeyUp = function (event)
|
||||
{
|
||||
if (event.defaultPrevented || !_this.enabled || !_this.manager)
|
||||
{
|
||||
|
@ -156,9 +207,11 @@ var KeyboardManager = new Class({
|
|||
return;
|
||||
}
|
||||
|
||||
_this.manager.queueMouseUp(event);
|
||||
_this.queue.push(event);
|
||||
|
||||
if (_this.capture && event.target === canvas)
|
||||
var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey);
|
||||
|
||||
if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1)
|
||||
{
|
||||
event.preventDefault();
|
||||
}
|
||||
|
@ -166,28 +219,17 @@ var KeyboardManager = new Class({
|
|||
|
||||
var target = this.target;
|
||||
|
||||
if (!target)
|
||||
if (target)
|
||||
{
|
||||
return;
|
||||
target.addEventListener('keydown', this.onKeyDown, false);
|
||||
target.addEventListener('keyup', this.onKeyUp, false);
|
||||
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
var passive = { passive: true };
|
||||
var nonPassive = { passive: false };
|
||||
|
||||
target.addEventListener('mousedown', this.onMouseDown, (this.capture) ? nonPassive : passive);
|
||||
target.addEventListener('mouseup', this.onMouseUp, (this.capture) ? nonPassive : passive);
|
||||
|
||||
if (window)
|
||||
{
|
||||
window.addEventListener('mousedown', this.onMouseDown, nonPassive);
|
||||
window.addEventListener('mouseup', this.onMouseUp, nonPassive);
|
||||
}
|
||||
|
||||
this.enabled = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the Mouse Event listeners.
|
||||
* Stops the Key Event listeners.
|
||||
* This is called automatically and does not need to be manually invoked.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#stopListeners
|
||||
|
@ -197,18 +239,175 @@ var KeyboardManager = new Class({
|
|||
{
|
||||
var target = this.target;
|
||||
|
||||
target.removeEventListener('mousedown', this.onMouseDown);
|
||||
target.removeEventListener('mouseup', this.onMouseUp);
|
||||
target.removeEventListener('keydown', this.onKeyDown, false);
|
||||
target.removeEventListener('keyup', this.onKeyUp, false);
|
||||
|
||||
if (window)
|
||||
{
|
||||
window.removeEventListener('mousedown', this.onMouseDown);
|
||||
window.removeEventListener('mouseup', this.onMouseUp);
|
||||
}
|
||||
this.enabled = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys this Mouse Manager instance.
|
||||
* Clears the event queue.
|
||||
* Called automatically by the Input Manager.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#postUpdate
|
||||
* @private
|
||||
* @since 3.16.0
|
||||
*/
|
||||
postUpdate: function ()
|
||||
{
|
||||
this.queue = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* By default when a key is pressed Phaser will not stop the event from propagating up to the browser.
|
||||
* There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll.
|
||||
*
|
||||
* This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser
|
||||
* and cause the default browser behavior.
|
||||
*
|
||||
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent
|
||||
* the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one.
|
||||
*
|
||||
* You can pass in a single key code value, or an array of key codes, or a string:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.addCapture(62);
|
||||
* ```
|
||||
*
|
||||
* An array of key codes:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.addCapture([ 62, 63, 64 ]);
|
||||
* ```
|
||||
*
|
||||
* Or a string:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.addCapture('W,S,A,D');
|
||||
* ```
|
||||
*
|
||||
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
|
||||
*
|
||||
* You can also provide an array mixing both strings and key code integers.
|
||||
*
|
||||
* If there are active captures after calling this method, the `preventDefault` property is set to `true`.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#addCapture
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {(string|integer|integer[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser.
|
||||
*/
|
||||
addCapture: function (keycode)
|
||||
{
|
||||
if (typeof keycode === 'string')
|
||||
{
|
||||
keycode = keycode.split(',');
|
||||
}
|
||||
|
||||
if (!Array.isArray(keycode))
|
||||
{
|
||||
keycode = [ keycode ];
|
||||
}
|
||||
|
||||
var captures = this.captures;
|
||||
|
||||
for (var i = 0; i < keycode.length; i++)
|
||||
{
|
||||
var code = keycode[i];
|
||||
|
||||
if (typeof code === 'string')
|
||||
{
|
||||
code = KeyCodes[code.toUpperCase()];
|
||||
}
|
||||
|
||||
if (captures.indexOf(code) === -1)
|
||||
{
|
||||
captures.push(code);
|
||||
}
|
||||
}
|
||||
|
||||
this.preventDefault = captures.length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes an existing key capture.
|
||||
*
|
||||
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove
|
||||
* the capture of a key, then it will remove it for any Scene in your game, not just the calling one.
|
||||
*
|
||||
* You can pass in a single key code value, or an array of key codes, or a string:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.removeCapture(62);
|
||||
* ```
|
||||
*
|
||||
* An array of key codes:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.removeCapture([ 62, 63, 64 ]);
|
||||
* ```
|
||||
*
|
||||
* Or a string:
|
||||
*
|
||||
* ```javascript
|
||||
* this.input.keyboard.removeCapture('W,S,A,D');
|
||||
* ```
|
||||
*
|
||||
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
|
||||
*
|
||||
* You can also provide an array mixing both strings and key code integers.
|
||||
*
|
||||
* If there are no captures left after calling this method, the `preventDefault` property is set to `false`.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#removeCapture
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {(string|integer|integer[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again.
|
||||
*/
|
||||
removeCapture: function (keycode)
|
||||
{
|
||||
if (typeof keycode === 'string')
|
||||
{
|
||||
keycode = keycode.split(',');
|
||||
}
|
||||
|
||||
if (!Array.isArray(keycode))
|
||||
{
|
||||
keycode = [ keycode ];
|
||||
}
|
||||
|
||||
var captures = this.captures;
|
||||
|
||||
for (var i = 0; i < keycode.length; i++)
|
||||
{
|
||||
var code = keycode[i];
|
||||
|
||||
if (typeof code === 'string')
|
||||
{
|
||||
code = KeyCodes[code.toUpperCase()];
|
||||
}
|
||||
|
||||
ArrayRemove(captures, code);
|
||||
}
|
||||
|
||||
this.preventDefault = captures.length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all keyboard captures and sets the `preventDefault` property to `false`.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures
|
||||
* @since 3.16.0
|
||||
*/
|
||||
clearCaptures: function ()
|
||||
{
|
||||
this.captures = [];
|
||||
|
||||
this.preventDefault = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys this Keyboard Manager instance.
|
||||
*
|
||||
* @method Phaser.Input.Keyboard.KeyboardManager#destroy
|
||||
* @since 3.16.0
|
||||
|
@ -217,6 +416,12 @@ var KeyboardManager = new Class({
|
|||
{
|
||||
this.stopListeners();
|
||||
|
||||
this.clearCaptures();
|
||||
|
||||
this.queue = [];
|
||||
|
||||
this.manager.game.events.off('poststep', this.postUpdate, this);
|
||||
|
||||
this.target = null;
|
||||
this.enabled = false;
|
||||
this.manager = null;
|
||||
|
|
Loading…
Reference in a new issue