2017-04-17 15:10:04 -04:00
|
|
|
const Cast = require('../util/cast');
|
2016-09-02 11:23:09 -04:00
|
|
|
|
2017-04-17 19:42:48 -04:00
|
|
|
class Keyboard {
|
|
|
|
constructor (runtime) {
|
|
|
|
/**
|
|
|
|
* List of currently pressed keys.
|
|
|
|
* @type{Array.<number>}
|
|
|
|
*/
|
|
|
|
this._keysPressed = [];
|
|
|
|
/**
|
|
|
|
* Reference to the owning Runtime.
|
|
|
|
* Can be used, for example, to activate hats.
|
|
|
|
* @type{!Runtime}
|
|
|
|
*/
|
|
|
|
this.runtime = runtime;
|
|
|
|
}
|
|
|
|
|
2016-09-03 16:33:45 -04:00
|
|
|
/**
|
2017-04-17 19:42:48 -04:00
|
|
|
* Convert a Scratch key name to a DOM keyCode.
|
|
|
|
* @param {Any} keyName Scratch key argument.
|
|
|
|
* @return {number} Key code corresponding to a DOM event.
|
|
|
|
* @private
|
2016-09-03 16:33:45 -04:00
|
|
|
*/
|
2017-04-17 19:42:48 -04:00
|
|
|
_scratchKeyToKeyCode (keyName) {
|
|
|
|
const keyString = Cast.toString(keyName);
|
|
|
|
switch (keyString) {
|
2018-04-23 17:49:01 -04:00
|
|
|
case ' ': return 'space';
|
|
|
|
case 'ArrowLeft': return 'left arrow';
|
|
|
|
case 'ArrowRight': return 'right arrow';
|
|
|
|
case 'ArrowUp': return 'up arrow';
|
|
|
|
case 'ArrowDown': return 'down arrow';
|
2017-04-17 19:42:48 -04:00
|
|
|
}
|
2018-04-23 17:49:01 -04:00
|
|
|
return keyName;
|
2016-09-02 11:23:09 -04:00
|
|
|
}
|
|
|
|
|
2017-04-17 19:42:48 -04:00
|
|
|
/**
|
|
|
|
* Convert a DOM keyCode into a Scratch key name.
|
|
|
|
* @param {number} keyCode Key code from DOM event.
|
|
|
|
* @return {Any} Scratch key argument.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_keyCodeToScratchKey (keyCode) {
|
2018-04-23 17:49:01 -04:00
|
|
|
return keyCode;
|
2016-09-03 16:33:45 -04:00
|
|
|
}
|
|
|
|
|
2017-04-17 19:42:48 -04:00
|
|
|
/**
|
|
|
|
* Keyboard DOM event handler.
|
|
|
|
* @param {object} data Data from DOM event.
|
|
|
|
*/
|
|
|
|
postData (data) {
|
2018-04-23 17:49:01 -04:00
|
|
|
const keyCode = this._scratchKeyToKeyCode(data.key);
|
|
|
|
if (keyCode) {
|
|
|
|
const index = this._keysPressed.indexOf(keyCode);
|
2017-04-17 19:42:48 -04:00
|
|
|
if (data.isDown) {
|
|
|
|
// If not already present, add to the list.
|
|
|
|
if (index < 0) {
|
2018-04-23 17:49:01 -04:00
|
|
|
this._keysPressed.push(keyCode);
|
2017-04-17 19:42:48 -04:00
|
|
|
}
|
|
|
|
// Always trigger hats, even if it was already pressed.
|
|
|
|
this.runtime.startHats('event_whenkeypressed', {
|
2018-04-23 17:49:01 -04:00
|
|
|
KEY_OPTION: this._keyCodeToScratchKey(keyCode)
|
2017-04-17 19:42:48 -04:00
|
|
|
});
|
|
|
|
this.runtime.startHats('event_whenkeypressed', {
|
|
|
|
KEY_OPTION: 'any'
|
|
|
|
});
|
|
|
|
} else if (index > -1) {
|
|
|
|
// If already present, remove from the list.
|
|
|
|
this._keysPressed.splice(index, 1);
|
2016-09-02 11:23:09 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-17 19:42:48 -04:00
|
|
|
/**
|
|
|
|
* Get key down state for a specified Scratch key name.
|
|
|
|
* @param {Any} key Scratch key argument.
|
|
|
|
* @return {boolean} Is the specified key down?
|
|
|
|
*/
|
|
|
|
getKeyIsDown (key) {
|
|
|
|
if (key === 'any') {
|
|
|
|
return this._keysPressed.length > 0;
|
|
|
|
}
|
|
|
|
const keyCode = this._scratchKeyToKeyCode(key);
|
|
|
|
return this._keysPressed.indexOf(keyCode) > -1;
|
2016-09-02 11:23:09 -04:00
|
|
|
}
|
2017-04-17 19:42:48 -04:00
|
|
|
}
|
2016-09-02 11:23:09 -04:00
|
|
|
|
|
|
|
module.exports = Keyboard;
|