Keyboard Input functions.

This commit is contained in:
Richard Davey 2017-01-08 14:14:21 +00:00
parent e260536f3c
commit 9aa52b5c0a
17 changed files with 525 additions and 0 deletions

View file

@ -0,0 +1,107 @@
// A generic Key object which can be passed to the Process functions (and so on)
// keycode can be either numeric or a string
var Key = function (keycode, name)
{
if (typeof keycode === 'string')
{
keycode = keycode.toUpperCase().charCodeAt(0);
}
if (name === undefined || name === '')
{
name = String.fromCharCode(keycode);
}
/**
* @property {number} keyCode - The keycode of this key.
*/
this.keyCode = keycode;
/**
* @property {string} name - A string representation of this Key (worked out via String.fromCharCode if possible, or set in the arguments)
*/
this.name = name;
/**
* @property {boolean} preventDefault - Should this Key prevent event propagation?
* @default
*/
this.preventDefault = false;
/**
* @property {boolean} enabled - Can this Key be processed?
* @default
*/
this.enabled = true;
/**
* @property {boolean} isDown - The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down.
* @default
*/
this.isDown = false;
/**
* @property {boolean} isUp - The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up.
* @default
*/
this.isUp = true;
/**
* @property {boolean} altKey - The down state of the ALT key, if pressed at the same time as this key.
* @default
*/
this.altKey = false;
/**
* @property {boolean} ctrlKey - The down state of the CTRL key, if pressed at the same time as this key.
* @default
*/
this.ctrlKey = false;
/**
* @property {boolean} shiftKey - The down state of the SHIFT key, if pressed at the same time as this key.
* @default
*/
this.shiftKey = false;
/**
* @property {number} timeDown - The timestamp when the key was last pressed down. This is based on Game.time.now.
*/
this.timeDown = 0;
/**
* If the key is down this value holds the duration of that key press and is constantly updated.
* If the key is up it holds the duration of the previous down session.
* @property {number} duration - The number of milliseconds this key has been held down for.
* @default
*/
this.duration = 0;
/**
* @property {number} timeUp - The timestamp when the key was last released. This is based on Game.time.now.
* @default
*/
this.timeUp = 0;
/**
* @property {number} repeats - If a key is held down this holds down the number of times the key has 'repeated'.
* @default
*/
this.repeats = 0;
/**
* @property {boolean} _justDown - True if the key has just been pressed (NOTE: requires to be reset, see justDown getter)
* @private
*/
this._justDown = false;
/**
* @property {boolean} _justUp - True if the key has just been pressed (NOTE: requires to be reset, see justDown getter)
* @private
*/
this._justUp = false;
};
module.exports = Key;

View file

@ -0,0 +1,19 @@
// Return boolean (true if it reached the end of the combo, false if not)
var AdvanceKeyCombo = function (event, combo)
{
combo.timeLastMatched = event.timeStamp;
combo.index++;
if (combo.index === combo.size)
{
return true;
}
else
{
combo.current = combo.keyCodes[combo.index];
return false;
}
};
module.exports = AdvanceKeyCombo;

View file

@ -0,0 +1,69 @@
var GetObjectValue = require('../../../utils/GetObjectValue');
// Keys can be either:
//
// A string (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
var KeyCombo = function (keys, config)
{
// Can't have a zero or single length combo (string or array based)
if (keys.length < 2)
{
return false;
}
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
this.current = this.keyCodes[0];
// The current index of the key being waited for in the 'keys' string
this.index = 0;
// The length of this combo (in keycodes)
this.size = this.keyCodes.length;
// The time the previous key in the combo was matched
this.timeLastMatched = 0;
// Has this Key Combo been matched yet?
this.matched = false;
// The time the entire combo was matched
this.timeMatched = 0;
// Custom options ...
// If they press the wrong key do we reset the combo?
this.resetOnWrongKey = GetObjectValue(config, 'resetOnWrongKey', true);
// The max delay in ms between each key press. Above this the combo is reset. 0 means disabled.
this.maxKeyDelay = GetObjectValue(config, 'maxKeyDelay', 0);
// If previously matched and they press Key 1 again, will it reset?
this.resetOnMatch = GetObjectValue(config, 'resetOnMatch', false);
};
module.exports = KeyCombo;

View file

@ -0,0 +1,57 @@
var AdvanceKeyCombo = require('./AdvanceKeyCombo');
var ProcessKeyCombo = function (event, combo)
{
if (combo.matched)
{
return true;
}
var comboMatched = false;
var keyMatched = false;
if (event.keyCode === combo.current)
{
// Key was correct
if (combo.index > 0 && combo.maxKeyDelay > 0)
{
// We have to check to see if the delay between
// the new key and the old one was too long (if enabled)
var timeLimit = combo.timeLastMatched + combo.maxKeyDelay;
// Check if they pressed it in time or not
if (event.timeStamp <= timeLimit)
{
keyMatched = true;
comboMatched = AdvanceKeyCombo(event, combo);
}
}
else
{
keyMatched = true;
// We don't check the time for the first key pressed, so just advance it
comboMatched = AdvanceKeyCombo(event, combo);
}
}
if (!keyMatched && combo.resetOnWrongKey)
{
// Wrong key was pressed
combo.index = 0;
combo.current = combo.keyCodes[0];
}
if (comboMatched)
{
combo.timeLastMatched = event.timeStamp;
combo.matched = true;
combo.timeMatched = event.timeStamp;
}
return comboMatched;
};
module.exports = ProcessKeyCombo;

View file

@ -0,0 +1,10 @@
var AddEventListener = require('../../../dom/AddEventListener');
// Adds a keydown event listener to the specified target (usually 'window')
var AddKeyDown = function (target, listener, useCapture)
{
AddEventListener(target, 'keydown', listener, useCapture);
};
module.exports = AddKeyDown;

View file

@ -0,0 +1,10 @@
var AddEventListener = require('../../../dom/AddEventListener');
// Adds a keypress event listener to the specified target (usually 'window')
var AddKeyPress = function (target, listener, useCapture)
{
AddEventListener(target, 'keypress', listener, useCapture);
};
module.exports = AddKeyPress;

View file

@ -0,0 +1,10 @@
var AddEventListener = require('../../../dom/AddEventListener');
// Adds a keyup event listener to the specified target (usually 'window')
var AddKeyUp = function (target, listener, useCapture)
{
AddEventListener(target, 'keyup', listener, useCapture);
};
module.exports = AddKeyUp;

View file

@ -0,0 +1,61 @@
// import Signal from 'system/Signal.js';
// export const onDown = new Signal();
// list = anything that can be iterated, like a Set, Map, Array or custom object with
// a Symbol.iterator
var ProcessKeyDown = function (event, list, prevent)
{
if (prevent === undefined) { prevent = false; }
if (list)
{
for (let key of list)
{
if (key.keyCode !== event.keyCode || !key.enabled)
{
continue;
}
if (key.preventDefault)
{
prevent = true;
}
key.altKey = event.altKey;
key.ctrlKey = event.ctrlKey;
key.shiftKey = event.shiftKey;
if (key.isDown)
{
key.repeats++;
}
else
{
key.isDown = true;
key.isUp = false;
key.timeDown = event.timeStamp;
key.duration = 0;
key.repeats = 0;
key._justDown = true;
key._justUp = false;
}
console.log('down', key.name);
}
}
if (prevent)
{
event.preventDefault();
}
// if (onDown.hasListeners)
// {
// onDown.dispatch(event);
// }
};
module.exports = ProcessKeyDown;

View file

@ -0,0 +1,45 @@
import Signal from 'system/Signal.js';
export const onUp = new Signal();
// list = anything that can be iterated, like a Set, Map, Array or custom object with
// a Symbol.iterator
export default function ProcessKeyUp (event, list = null, prevent = false) {
if (list)
{
for (let key of list)
{
if (key.keyCode !== event.keyCode || !key.enabled)
{
continue;
}
if (key.preventDefault)
{
prevent = true;
}
key.isDown = false;
key.isUp = true;
key.timeUp = event.timeStamp;
key.duration = key.timeUp - key.timeDown;
key._justDown = false;
key._justUp = true;
console.log('up', key.name);
}
}
if (prevent)
{
event.preventDefault();
}
if (onUp.hasListeners)
{
onUp.dispatch(event);
}
}

View file

@ -0,0 +1,8 @@
var RemoveEventListener = require('../../../dom/RemoveEventListener');
var RemoveKeyDown = function (target, listener)
{
RemoveEventListener(target, 'keydown', listener);
};
module.exports = RemoveKeyDown;

View file

@ -0,0 +1,8 @@
var RemoveEventListener = require('../../../dom/RemoveEventListener');
var RemoveKeyPress = function (target, listener)
{
RemoveEventListener(target, 'keypress', listener);
};
module.exports = RemoveKeyPress;

View file

@ -0,0 +1,8 @@
var RemoveEventListener = require('../../../dom/RemoveEventListener');
var RemoveKeyUp = function (target, listener)
{
RemoveEventListener(target, 'keyup', listener);
};
module.exports = RemoveKeyUp;

View file

@ -0,0 +1,16 @@
/**
* Returns `true` if the Key was pressed down within the `duration` value given, or `false` if it either isn't down,
* or was pressed down longer ago than then given duration.
*
* @method Phaser.Key#downDuration
* @param {number} [duration=50] - The duration within which the key is considered as being just pressed. Given in ms.
* @return {boolean} True if the key was pressed down within the given duration.
*/
var DownDuration = function (key, duration)
{
if (duration === undefined) { duration = 50; }
return (key.isDown && key.duration < duration);
};
module.exports = DownDuration;

View file

@ -0,0 +1,25 @@
/**
* The justDown value allows you to test if this Key has just been pressed down or not.
* When you check this value it will return `true` if the Key is down, otherwise `false`.
* You can only call justDown once per key press. It will only return `true` once, until the Key is released and pressed down again.
* This allows you to use it in situations where you want to check if this key is down without using a Signal, such as in a core game loop.
*
* @property {boolean} justDown
* @memberof Phaser.Key
* @default false
*/
var JustDown = function (key)
{
var current = false;
if (key.isDown)
{
current = key._justDown;
key._justDown = false;
}
return current;
};
module.exports = JustDown;

View file

@ -0,0 +1,25 @@
/**
* The justUp value allows you to test if this Key has just been released or not.
* When you check this value it will return `true` if the Key is up, otherwise `false`.
* You can only call justUp once per key release. It will only return `true` once, until the Key is pressed down and released again.
* This allows you to use it in situations where you want to check if this key is up without using a Signal, such as in a core game loop.
*
* @property {boolean} justUp
* @memberof Phaser.Key
* @default false
*/
var JustUp = function (key)
{
var current = false;
if (key.isDown)
{
current = key._justUp;
key._justUp = false;
}
return current;
};
module.exports = JustUp;

View file

@ -0,0 +1,31 @@
// Resets a Key object back to its default settings.
// Optionally resets the keyCode as well.
var ResetKey = function (key, clearKeyCode)
{
if (clearKeyCode === undefined) { clearKeyCode = false; }
key.preventDefault = false;
key.enabled = true;
key.isDown = false;
key.isUp = true;
key.altKey = false;
key.ctrlKey = false;
key.shiftKey = false;
key.timeDown = 0;
key.duration = 0;
key.timeUp = 0;
key.repeats = 0;
key._justDown = false;
key._justUp = false;
if (clearKeyCode)
{
key.keyCode = 0;
key.char = '';
}
return key;
};
module.exports = ResetKey;

View file

@ -0,0 +1,16 @@
/**
* Returns `true` if the Key was released within the `duration` value given, or `false` if it either isn't up,
* or was released longer ago than then given duration.
*
* @method Phaser.Key#upDuration
* @param {number} [duration=50] - The duration within which the key is considered as being just released. Given in ms.
* @return {boolean} True if the key was released within the given duration.
*/
var UpDuration = function (key, duration)
{
if (duration === undefined) { duration = 50; }
return (key.isUp && key.duration < duration);
};
module.exports = UpDuration;