2017-06-30 14:47:51 +00:00
|
|
|
var Class = require('../../utils/Class');
|
2017-02-21 01:04:11 +00:00
|
|
|
var Event = require('./events');
|
2017-02-21 16:05:36 +00:00
|
|
|
var Key = require('./keys/Key');
|
2017-06-30 14:47:51 +00:00
|
|
|
var KeyCodes = require('./keys/KeyCodes');
|
2017-02-21 16:52:40 +00:00
|
|
|
var KeyCombo = require('./combo/KeyCombo');
|
|
|
|
var ProcessKeyCombo = require('./combo/ProcessKeyCombo');
|
2017-02-21 16:05:36 +00:00
|
|
|
var ProcessKeyDown = require('./keys/ProcessKeyDown');
|
|
|
|
var ProcessKeyUp = require('./keys/ProcessKeyUp');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Keyboard class monitors keyboard input and dispatches keyboard events.
|
|
|
|
*
|
|
|
|
* _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.
|
|
|
|
*/
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
var KeyboardManager = new Class({
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
initialize:
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
function KeyboardManager (inputManager)
|
|
|
|
{
|
|
|
|
this.manager = inputManager;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-09-27 16:04:39 +00:00
|
|
|
this.events = inputManager.events;
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
this.enabled = false;
|
2017-02-21 16:52:40 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
this.target;
|
2017-02-24 01:45:15 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
this.keys = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
this.combos = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
this.captures = [];
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
// Standard FIFO queue
|
|
|
|
this.queue = [];
|
|
|
|
|
|
|
|
this.handler;
|
|
|
|
},
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The Boot handler is called by Phaser.Game when it first starts up.
|
|
|
|
* The renderer is available by now.
|
|
|
|
*/
|
|
|
|
boot: function ()
|
|
|
|
{
|
2017-06-30 14:47:51 +00:00
|
|
|
var config = this.manager.config;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
this.enabled = config.inputKeyboard;
|
|
|
|
this.target = config.inputKeyboardEventTarget;
|
|
|
|
|
|
|
|
if (this.enabled)
|
|
|
|
{
|
|
|
|
this.startListeners();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
startListeners: function ()
|
|
|
|
{
|
|
|
|
var queue = this.queue;
|
2017-02-24 01:45:15 +00:00
|
|
|
var captures = this.captures;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
var handler = function (event)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
|
|
|
if (event.preventDefaulted)
|
|
|
|
{
|
|
|
|
// Do nothing if event already handled
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
queue.push(event);
|
2017-02-24 01:45:15 +00:00
|
|
|
|
|
|
|
if (captures[event.keyCode])
|
|
|
|
{
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
2017-02-21 01:04:11 +00:00
|
|
|
};
|
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
this.handler = handler;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-06-14 00:20:01 +00:00
|
|
|
this.target.addEventListener('keydown', handler, false);
|
|
|
|
this.target.addEventListener('keyup', handler, false);
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
stopListeners: function ()
|
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.target.removeEventListener('keydown', this.handler);
|
|
|
|
this.target.removeEventListener('keyup', this.handler);
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
2017-02-21 16:05:36 +00:00
|
|
|
/**
|
2017-09-16 02:08:09 +00:00
|
|
|
* Creates and returns an object containing 4 hotkeys for Up, Down, Left and Right and also space and shift.
|
2017-02-21 16:05:36 +00:00
|
|
|
*/
|
|
|
|
createCursorKeys: function ()
|
|
|
|
{
|
|
|
|
return this.addKeys({
|
|
|
|
up: KeyCodes.UP,
|
|
|
|
down: KeyCodes.DOWN,
|
|
|
|
left: KeyCodes.LEFT,
|
2017-09-16 02:08:09 +00:00
|
|
|
right: KeyCodes.RIGHT,
|
|
|
|
space: KeyCodes.SPACE,
|
|
|
|
shift: KeyCodes.SHIFT
|
2017-02-21 16:05:36 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A practical way to create an object containing user selected hotkeys.
|
|
|
|
*
|
|
|
|
* For example,
|
|
|
|
*
|
|
|
|
* addKeys( { 'up': Phaser.KeyCode.W, 'down': Phaser.KeyCode.S, 'left': Phaser.KeyCode.A, 'right': Phaser.KeyCode.D } );
|
|
|
|
*
|
|
|
|
* would return an object containing properties (`up`, `down`, `left` and `right`) referring to {@link Phaser.Key} object.
|
|
|
|
*/
|
|
|
|
addKeys: function (keys)
|
|
|
|
{
|
|
|
|
var output = {};
|
|
|
|
|
|
|
|
for (var key in keys)
|
|
|
|
{
|
|
|
|
output[key] = this.addKey(keys[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
},
|
|
|
|
|
2017-02-21 01:04:11 +00:00
|
|
|
/**
|
|
|
|
* If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method.
|
|
|
|
* The Key object can then be polled, have events attached to it, etc.
|
|
|
|
*/
|
2017-02-21 16:52:40 +00:00
|
|
|
addKey: function (keyCode)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-21 16:52:40 +00:00
|
|
|
var keys = this.keys;
|
|
|
|
|
|
|
|
if (!keys[keyCode])
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-21 16:52:40 +00:00
|
|
|
keys[keyCode] = new Key(keyCode);
|
2017-02-24 01:45:15 +00:00
|
|
|
this.captures[keyCode] = true;
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 16:52:40 +00:00
|
|
|
return keys[keyCode];
|
2017-02-21 01:04:11 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes a Key object from the Keyboard manager.
|
|
|
|
*/
|
2017-02-24 01:45:15 +00:00
|
|
|
removeKey: function (keyCode)
|
|
|
|
{
|
|
|
|
if (this.keys[keyCode])
|
|
|
|
{
|
|
|
|
this.keys[keyCode] = undefined;
|
|
|
|
this.captures[keyCode] = false;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
addKeyCapture: function (keyCodes)
|
|
|
|
{
|
|
|
|
if (!Array.isArray(keyCodes))
|
|
|
|
{
|
|
|
|
keyCodes = [ keyCodes ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < keyCodes.length; i++)
|
|
|
|
{
|
|
|
|
this.captures[keyCodes[i]] = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
removeKeyCapture: function (keyCodes)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-24 01:45:15 +00:00
|
|
|
if (!Array.isArray(keyCodes))
|
|
|
|
{
|
|
|
|
keyCodes = [ keyCodes ];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < keyCodes.length; i++)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
2017-02-24 01:45:15 +00:00
|
|
|
this.captures[keyCodes[i]] = false;
|
2017-02-21 01:04:11 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-02-21 23:01:05 +00:00
|
|
|
createCombo: function (keys, config)
|
2017-02-21 16:52:40 +00:00
|
|
|
{
|
2017-02-21 23:01:05 +00:00
|
|
|
return new KeyCombo(this, keys, config);
|
2017-02-21 16:52:40 +00:00
|
|
|
},
|
|
|
|
|
2017-02-21 01:04:11 +00:00
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent
|
|
|
|
// type = 'keydown', 'keyup'
|
|
|
|
// keyCode = integer
|
|
|
|
|
|
|
|
update: function ()
|
|
|
|
{
|
2017-06-12 23:38:48 +00:00
|
|
|
var len = this.queue.length;
|
|
|
|
|
|
|
|
if (!this.enabled || len === 0)
|
2017-02-21 16:05:36 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clears the queue array, and also means we don't work on array data that could potentially
|
|
|
|
// be modified during the processing phase
|
2017-06-12 23:38:48 +00:00
|
|
|
var queue = this.queue.splice(0, len);
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
var keys = this.keys;
|
2017-02-21 16:52:40 +00:00
|
|
|
var singleKey;
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-02-21 16:05:36 +00:00
|
|
|
// Process the event queue, dispatching all of the events that have stored up
|
2017-06-12 23:38:48 +00:00
|
|
|
for (var i = 0; i < len; i++)
|
2017-02-21 01:04:11 +00:00
|
|
|
{
|
|
|
|
var event = queue[i];
|
|
|
|
|
|
|
|
if (event.type === 'keydown')
|
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.manager.events.dispatch(new Event.KEY_DOWN_EVENT(event));
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-02-21 16:52:40 +00:00
|
|
|
singleKey = Event._DOWN[event.keyCode];
|
|
|
|
|
|
|
|
if (singleKey)
|
2017-02-21 16:05:36 +00:00
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.manager.events.dispatch(new singleKey(event));
|
2017-02-21 16:05:36 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 01:04:11 +00:00
|
|
|
if (keys[event.keyCode])
|
|
|
|
{
|
|
|
|
ProcessKeyDown(keys[event.keyCode], event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.manager.events.dispatch(new Event.KEY_UP_EVENT(event));
|
2017-02-21 01:04:11 +00:00
|
|
|
|
2017-02-21 16:52:40 +00:00
|
|
|
singleKey = Event._UP[event.keyCode];
|
|
|
|
|
|
|
|
if (singleKey)
|
2017-02-21 16:05:36 +00:00
|
|
|
{
|
2017-06-14 00:20:01 +00:00
|
|
|
this.manager.events.dispatch(new singleKey(event));
|
2017-02-21 16:05:36 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 01:04:11 +00:00
|
|
|
if (keys[event.keyCode])
|
|
|
|
{
|
|
|
|
ProcessKeyUp(keys[event.keyCode], event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
});
|
2017-02-21 01:04:11 +00:00
|
|
|
|
|
|
|
module.exports = KeyboardManager;
|