The Keyboard class has had a complete overhaul. Phaser.Key objects are created automatically, there are fixes against duration and keys reset properly on visibility loss.

Keyboard.removeKey has been removed. The way the new keyboard manager works means it's no longer required.
Fixes issue #462
This commit is contained in:
photonstorm
2014-02-24 15:58:02 +00:00
parent 9d9fd06392
commit d9cadc70ac
7 changed files with 191 additions and 110 deletions
+4 -1
View File
@@ -73,7 +73,9 @@ Significant API changes:
* After defining tiles that collide on a Tilemap, you need to call Tilemap.generateCollisionData(layer) to populate the physics world with the data required.
* Phaser.QuadTree has been removed from core and moved to a plugin. It's no longer required, nor works with the physics system.
* Phaser.Animation.frame now returns the frame of the current animation, rather than the global frame from the sprite sheet / atlas.
* When adding a Group if the parent value is `null` the Group won't be added to the World, so you can add it when ready. If parent is `undefined` it's added to World by default.
* When adding a Group if the parent value is `null` the Group won't be added to the World, so you can add it when ready. If parent is `undefined` it's added by default.
* The Keyboard class has had a complete overhaul. Phaser.Key objects are created automatically, there are fixes against duration and keys reset properly on visibility loss.
* Keyboard.removeKey has been removed. The way the new keyboard manager works means it's no longer required.
New features:
@@ -107,6 +109,7 @@ New features:
* Loader can now load JSON files specifically (game.load.json) and they are parsed and stored in the Game.Cache. Retrieve with game.cache.getJSON(key).
* TileSprites can now receive full Input events, dragging, etc and be positioned in-world and fixed to cameras.
* The StateManager now looks for a function called 'resumed' which is called when a game un-pauses.
* Key.onHold added. This event is dispatched every time the browser sends a keydown event and the key is already being held down.
Updates:
+33
View File
@@ -0,0 +1,33 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
}
var text;
var key1;
var key2;
function create() {
game.stage.setBackgroundColor(0x0b7276);
game.add.text(32, 16, "SPACE");
game.add.text(32, 170, "A");
key1 = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
key2 = game.input.keyboard.addKey(Phaser.Keyboard.A);
}
function update() {
}
function render() {
game.debug.renderKey(key1, 32, 64);
game.debug.renderKey(key2, 32, 220);
}
+1
View File
@@ -741,6 +741,7 @@ Object.defineProperty(Phaser.Game.prototype, "paused", {
if (this._paused)
{
this._paused = false;
this.input.reset();
this.onResume.dispatch(this);
}
}
+2
View File
@@ -428,6 +428,8 @@ Phaser.Input.prototype = {
*/
update: function () {
this.keyboard.update();
if (this.pollRate > 0 && this._pollCounter < this.pollRate)
{
this._pollCounter++;
+63 -23
View File
@@ -49,8 +49,7 @@ Phaser.Key = function (game, keycode) {
this.shiftKey = false;
/**
* @property {number} timeDown - The timestamp when the key was last pressed down.
* @default
* @property {number} timeDown - The timestamp when the key was last pressed down. This is based on Game.time.now.
*/
this.timeDown = 0;
@@ -63,10 +62,10 @@ Phaser.Key = function (game, keycode) {
this.duration = 0;
/**
* @property {number} timeUp - The timestamp when the key was last released.
* @property {number} timeUp - The timestamp when the key was last released. This is based on Game.time.now.
* @default
*/
this.timeUp = 0;
this.timeUp = -2500;
/**
* @property {number} repeats - If a key is held down this holds down the number of times the key has 'repeated'.
@@ -84,6 +83,16 @@ Phaser.Key = function (game, keycode) {
*/
this.onDown = new Phaser.Signal();
/**
* @property {function} onHoldCallback - A callback that is called while this Key is held down. Warning: Depending on refresh rate that could be 60+ times per second.
*/
this.onHoldCallback = null;
/**
* @property {object} onHoldContext - The context under which the onHoldCallback will be called.
*/
this.onHoldContext = null;
/**
* @property {Phaser.Signal} onUp - This Signal is dispatched every time this Key is pressed down. It is only dispatched once (until the key is released again).
*/
@@ -93,6 +102,21 @@ Phaser.Key = function (game, keycode) {
Phaser.Key.prototype = {
update: function () {
if (this.isDown)
{
this.duration = this.game.time.now - this.timeDown;
this.repeats++;
if (this.onHoldCallback)
{
this.onHoldCallback.call(this.onHoldContext, this);
}
}
},
/**
* Called automatically by Phaser.Keyboard.
* @method Phaser.Key#processKeyDown
@@ -101,26 +125,22 @@ Phaser.Key.prototype = {
*/
processKeyDown: function (event) {
if (this.isDown)
{
return;
}
this.altKey = event.altKey;
this.ctrlKey = event.ctrlKey;
this.shiftKey = event.shiftKey;
if (this.isDown)
{
// Key was already held down, this must be a repeat rate based event
this.duration = event.timeStamp - this.timeDown;
this.repeats++;
}
else
{
this.isDown = true;
this.isUp = false;
this.timeDown = event.timeStamp;
this.duration = 0;
this.repeats = 0;
this.isDown = true;
this.isUp = false;
this.timeDown = this.game.time.now;
this.duration = 0;
this.repeats = 0;
this.onDown.dispatch(this);
}
this.onDown.dispatch(this);
},
@@ -132,14 +152,34 @@ Phaser.Key.prototype = {
*/
processKeyUp: function (event) {
if (this.isUp)
{
return;
}
this.isDown = false;
this.isUp = true;
this.timeUp = event.timeStamp;
this.timeUp = this.game.time.now;
this.duration = this.game.time.now - this.timeDown;
this.onUp.dispatch(this);
},
/**
* Resets the state of this Key.
*
* @method Phaser.Key#reset
*/
reset: function () {
this.isDown = false;
this.isUp = true;
this.timeUp = this.game.time.now;
this.duration = this.game.time.now - this.timeDown;
},
/**
* Returns the "just pressed" state of the Key. Just pressed is considered true if the key was pressed down within the duration given (default 250ms)
* @method Phaser.Key#justPressed
@@ -148,7 +188,7 @@ Phaser.Key.prototype = {
*/
justPressed: function (duration) {
if (typeof duration === "undefined") { duration = 250; }
if (typeof duration === "undefined") { duration = 2500; }
return (this.isDown && this.duration < duration);
@@ -162,9 +202,9 @@ Phaser.Key.prototype = {
*/
justReleased: function (duration) {
if (typeof duration === "undefined") { duration = 250; }
if (typeof duration === "undefined") { duration = 2500; }
return (this.isDown === false && (this.game.time.now - this.timeUp < duration));
return (!this.isDown && ((this.game.time.now - this.timeUp) < duration));
}
+68 -86
View File
@@ -19,22 +19,16 @@ Phaser.Keyboard = function (game) {
this.game = game;
/**
* @property {object} _keys - The object the key values are stored in.
* @property {array<Phaser.Key>} _keys - The array the Phaser.Key objects are stored in.
* @private
*/
this._keys = {};
this._keys = [];
/**
* @property {object} _hotkeys - The object the hot keys are stored in.
* @property {array} _capture - The array the key capture values are stored in.
* @private
*/
this._hotkeys = {};
/**
* @property {object} _capture - The object the key capture values are stored in.
* @private
*/
this._capture = {};
this._capture = [];
/**
* You can disable all Keyboard Input by setting disabled to true. While true all new input related events will be ignored.
@@ -78,6 +72,7 @@ Phaser.Keyboard.prototype = {
/**
* Add callbacks to the Keyboard handler so that each time a key is pressed down or releases the callbacks are activated.
*
* @method Phaser.Keyboard#addCallbacks
* @param {Object} context - The context under which the callbacks are run.
* @param {function} onDown - This callback is invoked every time a key is pressed down.
@@ -105,23 +100,14 @@ Phaser.Keyboard.prototype = {
*/
addKey: function (keycode) {
this._hotkeys[keycode] = new Phaser.Key(this.game, keycode);
if (!this._keys[keycode])
{
this._keys[keycode] = new Phaser.Key(this.game, keycode);
this.addKeyCapture(keycode);
this.addKeyCapture(keycode);
}
return this._hotkeys[keycode];
},
/**
* Removes a Key object from the Keyboard manager.
*
* @method Phaser.Keyboard#removeKey
* @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
*/
removeKey: function (keycode) {
delete (this._hotkeys[keycode]);
return this._keys[keycode];
},
@@ -182,8 +168,9 @@ Phaser.Keyboard.prototype = {
* There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll.
* You can use addKeyCapture to consume the keyboard event for specific keys so it doesn't bubble up to the the browser.
* Pass in either a single keycode or an array/hash of keycodes.
*
* @method Phaser.Keyboard#addKeyCapture
* @param {Any} keycode
* @param {Any} keycode - Either a single numeric keycode or an array/hash of keycodes: [65, 67, 68].
*/
addKeyCapture: function (keycode) {
@@ -202,6 +189,7 @@ Phaser.Keyboard.prototype = {
/**
* Removes an existing key capture.
*
* @method Phaser.Keyboard#removeKeyCapture
* @param {number} keycode
*/
@@ -213,6 +201,7 @@ Phaser.Keyboard.prototype = {
/**
* Clear all set key captures.
*
* @method Phaser.Keyboard#clearCaptures
*/
clearCaptures: function () {
@@ -221,8 +210,28 @@ Phaser.Keyboard.prototype = {
},
/**
* Updates all currently defined keys.
*
* @method Phaser.Keyboard#update
*/
update: function () {
var i = this._keys.length;
while (i--)
{
if (this._keys[i])
{
this._keys[i].update();
}
}
},
/**
* Process the keydown event.
*
* @method Phaser.Keyboard#processKeyDown
* @param {KeyboardEvent} event
* @protected
@@ -234,6 +243,7 @@ Phaser.Keyboard.prototype = {
return;
}
// The event is being captured but another hotkey may need it
if (this._capture[event.keyCode])
{
event.preventDefault();
@@ -244,41 +254,18 @@ Phaser.Keyboard.prototype = {
this.onDownCallback.call(this.callbackContext, event);
}
if (this._keys[event.keyCode] && this._keys[event.keyCode].isDown)
if (!this._keys[event.keyCode])
{
// Key already down and still down, so update
this._keys[event.keyCode].duration = this.game.time.now - this._keys[event.keyCode].timeDown;
}
else
{
if (!this._keys[event.keyCode])
{
// Not used this key before, so register it
this._keys[event.keyCode] = {
isDown: true,
timeDown: this.game.time.now,
timeUp: 0,
duration: 0
};
}
else
{
// Key used before but freshly down
this._keys[event.keyCode].isDown = true;
this._keys[event.keyCode].timeDown = this.game.time.now;
this._keys[event.keyCode].duration = 0;
}
}
if (this._hotkeys[event.keyCode])
{
this._hotkeys[event.keyCode].processKeyDown(event);
this._keys[event.keyCode] = new Phaser.Key(this.game, event.keyCode);
}
this._keys[event.keyCode].processKeyDown(event);
},
/**
* Process the keyup event.
*
* @method Phaser.Keyboard#processKeyUp
* @param {KeyboardEvent} event
* @protected
@@ -300,44 +287,37 @@ Phaser.Keyboard.prototype = {
this.onUpCallback.call(this.callbackContext, event);
}
if (this._hotkeys[event.keyCode])
if (!this._keys[event.keyCode])
{
this._hotkeys[event.keyCode].processKeyUp(event);
this._keys[event.keyCode] = new Phaser.Key(this.game, event.keyCode);
}
if (this._keys[event.keyCode])
{
this._keys[event.keyCode].isDown = false;
this._keys[event.keyCode].timeUp = this.game.time.now;
}
else
{
// Not used this key before, so register it
this._keys[event.keyCode] = {
isDown: false,
timeDown: this.game.time.now,
timeUp: this.game.time.now,
duration: 0
};
}
this._keys[event.keyCode].processKeyUp(event);
},
/**
* Reset the "isDown" state of all keys.
* Resets all Keys.
*
* @method Phaser.Keyboard#reset
*/
reset: function () {
for (var key in this._keys)
var i = this._keys.length;
while (i--)
{
this._keys[key].isDown = false;
if (this._keys[i])
{
this._keys[i].reset();
}
}
},
/**
* Returns the "just pressed" state of the key. Just pressed is considered true if the key was pressed down within the duration given (default 250ms)
*
* @method Phaser.Keyboard#justPressed
* @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
* @param {number} [duration=250] - The duration below which the key is considered as being just pressed.
@@ -345,19 +325,20 @@ Phaser.Keyboard.prototype = {
*/
justPressed: function (keycode, duration) {
if (typeof duration === "undefined") { duration = 250; }
if (this._keys[keycode] && this._keys[keycode].isDown && this._keys[keycode].duration < duration)
if (this._keys[keycode])
{
return true;
return this._keys[keycode].justPressed(duration);
}
else
{
return false;
}
return false;
},
/**
* Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms)
*
* @method Phaser.Keyboard#justReleased
* @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
* @param {number} [duration=250] - The duration below which the key is considered as being just released.
@@ -365,19 +346,20 @@ Phaser.Keyboard.prototype = {
*/
justReleased: function (keycode, duration) {
if (typeof duration === "undefined") { duration = 250; }
if (this._keys[keycode] && this._keys[keycode].isDown === false && (this.game.time.now - this._keys[keycode].timeUp < duration))
if (this._keys[keycode])
{
return true;
return this._keys[keycode].justReleased(duration);
}
else
{
return false;
}
return false;
},
/**
* Returns true of the key is currently pressed down. Note that it can only detect key presses on the web browser.
*
* @method Phaser.Keyboard#isDown
* @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
* @return {boolean} True if the key is currently down.
+20
View File
@@ -324,6 +324,26 @@ Phaser.Utils.Debug.prototype = {
},
renderKey: function (key, x, y, color) {
if (this.context === null)
{
return;
}
color = color || 'rgb(255,255,255)';
this.start(x, y, color, 150);
this.splitline('Key:', key.keyCode, 'isDown:', key.isDown);
this.splitline('justPressed:', key.justPressed(), 'justReleased:', key.justReleased());
this.splitline('Time Down:', key.timeDown.toFixed(0), 'duration:', key.duration.toFixed(0));
this.line('Repeats: ' + key.repeats);
this.stop();
},
/**
* Render debug information about the Input object.
* @method Phaser.Utils.Debug#renderInputInfo