mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-24 15:02:52 -05:00
Keyboard events, "key is down" reporter (#117)
* Keyboard events, "key is down" reporter * Update comment about inputs * Simplify/generalize keyMap into a keys-pressed list * Cast values passed to scratchKeyToKeyCode appropriately. * Cut unspaced key values * Fix lint from merge commit
This commit is contained in:
parent
86f136dd10
commit
e831866789
4 changed files with 94 additions and 0 deletions
|
@ -166,6 +166,31 @@ window.onload = function() {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Feed keyboard events as VM I/O events.
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
// Don't capture keys intended for Blockly inputs.
|
||||||
|
if (e.target != document && e.target != document.body) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.vm.postIOData('keyboard', {
|
||||||
|
keyCode: e.keyCode,
|
||||||
|
isDown: true
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
document.addEventListener('keyup', function(e) {
|
||||||
|
// Always capture up events,
|
||||||
|
// even those that have switched to other targets.
|
||||||
|
window.vm.postIOData('keyboard', {
|
||||||
|
keyCode: e.keyCode,
|
||||||
|
isDown: false
|
||||||
|
});
|
||||||
|
// E.g., prevent scroll.
|
||||||
|
if (e.target != document && e.target != document.body) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Run threads
|
// Run threads
|
||||||
vm.start();
|
vm.start();
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ Scratch3SensingBlocks.prototype.getPrimitives = function() {
|
||||||
'sensing_mousex': this.getMouseX,
|
'sensing_mousex': this.getMouseX,
|
||||||
'sensing_mousey': this.getMouseY,
|
'sensing_mousey': this.getMouseY,
|
||||||
'sensing_mousedown': this.getMouseDown,
|
'sensing_mousedown': this.getMouseDown,
|
||||||
|
'sensing_keyoptions': this.keyOptions,
|
||||||
|
'sensing_keypressed': this.getKeyPressed,
|
||||||
'sensing_current': this.current,
|
'sensing_current': this.current,
|
||||||
'sensing_currentmenu': this.currentMenu
|
'sensing_currentmenu': this.currentMenu
|
||||||
};
|
};
|
||||||
|
@ -59,4 +61,12 @@ Scratch3SensingBlocks.prototype.currentMenu = function (args) {
|
||||||
return args.CURRENTMENU.toLowerCase();
|
return args.CURRENTMENU.toLowerCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Scratch3SensingBlocks.prototype.keyOptions = function (args) {
|
||||||
|
return args.KEY_OPTION.toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
Scratch3SensingBlocks.prototype.getKeyPressed = function (args, util) {
|
||||||
|
return util.ioQuery('keyboard', 'getKeyIsDown', args.KEY_OPTIONS);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = Scratch3SensingBlocks;
|
module.exports = Scratch3SensingBlocks;
|
||||||
|
|
|
@ -5,6 +5,7 @@ var util = require('util');
|
||||||
|
|
||||||
// Virtual I/O devices.
|
// Virtual I/O devices.
|
||||||
var Clock = require('../io/clock');
|
var Clock = require('../io/clock');
|
||||||
|
var Keyboard = require('../io/keyboard');
|
||||||
var Mouse = require('../io/mouse');
|
var Mouse = require('../io/mouse');
|
||||||
|
|
||||||
var defaultBlockPackages = {
|
var defaultBlockPackages = {
|
||||||
|
@ -53,6 +54,7 @@ function Runtime () {
|
||||||
|
|
||||||
this.ioDevices = {
|
this.ioDevices = {
|
||||||
'clock': new Clock(),
|
'clock': new Clock(),
|
||||||
|
'keyboard': new Keyboard(),
|
||||||
'mouse': new Mouse()
|
'mouse': new Mouse()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
57
src/io/keyboard.js
Normal file
57
src/io/keyboard.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
var Cast = require('../util/cast');
|
||||||
|
|
||||||
|
function Keyboard () {
|
||||||
|
/**
|
||||||
|
* List of currently pressed keys.
|
||||||
|
* @type{Array.<number>}
|
||||||
|
*/
|
||||||
|
this._keysPressed = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Scratch key name to a DOM keyCode.
|
||||||
|
* @param {Any} keyName Scratch key argument.
|
||||||
|
* @return {number} Key code corresponding to a DOM event.
|
||||||
|
*/
|
||||||
|
Keyboard.prototype._scratchKeyToKeyCode = function (keyName) {
|
||||||
|
if (typeof keyName == 'number') {
|
||||||
|
// Key codes placed in with number blocks.
|
||||||
|
return keyName;
|
||||||
|
}
|
||||||
|
var keyString = Cast.toString(keyName);
|
||||||
|
switch (keyString) {
|
||||||
|
case 'space': return 32;
|
||||||
|
case 'left arrow': return 37;
|
||||||
|
case 'up arrow': return 38;
|
||||||
|
case 'right arrow': return 39;
|
||||||
|
case 'down arrow': return 40;
|
||||||
|
// @todo: Consider adding other special keys here.
|
||||||
|
}
|
||||||
|
// Keys reported by DOM keyCode are upper case.
|
||||||
|
return keyString.toUpperCase().charCodeAt(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
Keyboard.prototype.postData = function (data) {
|
||||||
|
if (data.keyCode) {
|
||||||
|
var index = this._keysPressed.indexOf(data.keyCode);
|
||||||
|
if (data.isDown) {
|
||||||
|
// If not already present, add to the list.
|
||||||
|
if (index < 0) {
|
||||||
|
this._keysPressed.push(data.keyCode);
|
||||||
|
}
|
||||||
|
} else if (index > -1) {
|
||||||
|
// If already present, remove from the list.
|
||||||
|
this._keysPressed.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Keyboard.prototype.getKeyIsDown = function (key) {
|
||||||
|
if (key == 'any') {
|
||||||
|
return this._keysPressed.length > 0;
|
||||||
|
}
|
||||||
|
var keyCode = this._scratchKeyToKeyCode(key);
|
||||||
|
return this._keysPressed.indexOf(keyCode) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Keyboard;
|
Loading…
Reference in a new issue