phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.
288 lines (251 loc) • 8.3 kB
JavaScript
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2013-2023 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../../utils/Class');
var Events = require('../events');
var GetFastValue = require('../../../utils/object/GetFastValue');
var ProcessKeyCombo = require('./ProcessKeyCombo');
var ResetKeyCombo = require('./ResetKeyCombo');
/**
* @classdesc
* A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them
* it will emit a `keycombomatch` event from the Keyboard Manager.
*
* The keys to be listened for can be defined as:
*
* A string (i.e. 'ATARI')
* An array of either integers (key codes) or strings, or a mixture of both
* An array of objects (such as Key objects) with a public 'keyCode' property
*
* For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter)
* you could pass the following array of key codes:
*
* ```javascript
* this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true });
*
* this.input.keyboard.on('keycombomatch', function (event) {
* console.log('Konami Code entered!');
* });
* ```
*
* Or, to listen for the user entering the word PHASER:
*
* ```javascript
* this.input.keyboard.createCombo('PHASER');
* ```
*
* @class KeyCombo
* @memberof Phaser.Input.Keyboard
* @constructor
* @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN
* @since 3.0.0
*
* @param {Phaser.Input.Keyboard.KeyboardPlugin} keyboardPlugin - A reference to the Keyboard Plugin.
* @param {(string|number[]|object[])} keys - The keys that comprise this combo.
* @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object.
*/
var KeyCombo = new Class({
initialize:
function KeyCombo (keyboardPlugin, keys, config)
{
if (config === undefined) { config = {}; }
// Can't have a zero or single length combo (string or array based)
if (keys.length < 2)
{
return false;
}
/**
* A reference to the Keyboard Manager
*
* @name Phaser.Input.Keyboard.KeyCombo#manager
* @type {Phaser.Input.Keyboard.KeyboardPlugin}
* @since 3.0.0
*/
this.manager = keyboardPlugin;
/**
* A flag that controls if this Key Combo is actively processing keys or not.
*
* @name Phaser.Input.Keyboard.KeyCombo#enabled
* @type {boolean}
* @default true
* @since 3.0.0
*/
this.enabled = true;
/**
* An array of the keycodes that comprise this combo.
*
* @name Phaser.Input.Keyboard.KeyCombo#keyCodes
* @type {array}
* @default []
* @since 3.0.0
*/
this.keyCodes = [];
// if 'keys' is a string we need to get the keycode of each character in it
for (var i = 0; i < keys.length; i++)
{
var char = keys[i];
if (typeof char === 'string')
{
this.keyCodes.push(char.toUpperCase().charCodeAt(0));
}
else if (typeof char === 'number')
{
this.keyCodes.push(char);
}
else if (char.hasOwnProperty('keyCode'))
{
this.keyCodes.push(char.keyCode);
}
}
/**
* The current keyCode the combo is waiting for.
*
* @name Phaser.Input.Keyboard.KeyCombo#current
* @type {number}
* @since 3.0.0
*/
this.current = this.keyCodes[0];
/**
* The current index of the key being waited for in the 'keys' string.
*
* @name Phaser.Input.Keyboard.KeyCombo#index
* @type {number}
* @default 0
* @since 3.0.0
*/
this.index = 0;
/**
* The length of this combo (in keycodes)
*
* @name Phaser.Input.Keyboard.KeyCombo#size
* @type {number}
* @since 3.0.0
*/
this.size = this.keyCodes.length;
/**
* The time the previous key in the combo was matched.
*
* @name Phaser.Input.Keyboard.KeyCombo#timeLastMatched
* @type {number}
* @default 0
* @since 3.0.0
*/
this.timeLastMatched = 0;
/**
* Has this Key Combo been matched yet?
*
* @name Phaser.Input.Keyboard.KeyCombo#matched
* @type {boolean}
* @default false
* @since 3.0.0
*/
this.matched = false;
/**
* The time the entire combo was matched.
*
* @name Phaser.Input.Keyboard.KeyCombo#timeMatched
* @type {number}
* @default 0
* @since 3.0.0
*/
this.timeMatched = 0;
/**
* If they press the wrong key do we reset the combo?
*
* @name Phaser.Input.Keyboard.KeyCombo#resetOnWrongKey
* @type {boolean}
* @default 0
* @since 3.0.0
*/
this.resetOnWrongKey = GetFastValue(config, 'resetOnWrongKey', true);
/**
* The max delay in ms between each key press. Above this the combo is reset. 0 means disabled.
*
* @name Phaser.Input.Keyboard.KeyCombo#maxKeyDelay
* @type {number}
* @default 0
* @since 3.0.0
*/
this.maxKeyDelay = GetFastValue(config, 'maxKeyDelay', 0);
/**
* If previously matched and they press the first key of the combo again, will it reset?
*
* @name Phaser.Input.Keyboard.KeyCombo#resetOnMatch
* @type {boolean}
* @default false
* @since 3.0.0
*/
this.resetOnMatch = GetFastValue(config, 'resetOnMatch', false);
/**
* If the combo matches, will it delete itself?
*
* @name Phaser.Input.Keyboard.KeyCombo#deleteOnMatch
* @type {boolean}
* @default false
* @since 3.0.0
*/
this.deleteOnMatch = GetFastValue(config, 'deleteOnMatch', false);
var _this = this;
var onKeyDownHandler = function (event)
{
if (_this.matched || !_this.enabled)
{
return;
}
var matched = ProcessKeyCombo(event, _this);
if (matched)
{
_this.manager.emit(Events.COMBO_MATCH, _this, event);
if (_this.resetOnMatch)
{
ResetKeyCombo(_this);
}
else if (_this.deleteOnMatch)
{
_this.destroy();
}
}
};
/**
* The internal Key Down handler.
*
* @name Phaser.Input.Keyboard.KeyCombo#onKeyDown
* @private
* @type {KeyboardKeydownCallback}
* @fires Phaser.Input.Keyboard.Events#COMBO_MATCH
* @since 3.0.0
*/
this.onKeyDown = onKeyDownHandler;
this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown);
},
/**
* How far complete is this combo? A value between 0 and 1.
*
* @name Phaser.Input.Keyboard.KeyCombo#progress
* @type {number}
* @readonly
* @since 3.0.0
*/
progress: {
get: function ()
{
return this.index / this.size;
}
},
/**
* Destroys this Key Combo and all of its references.
*
* @method Phaser.Input.Keyboard.KeyCombo#destroy
* @since 3.0.0
*/
destroy: function ()
{
this.enabled = false;
this.keyCodes = [];
this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown);
this.manager = null;
}
});
module.exports = KeyCombo;