scratch-vm/src/blocks/scratch3_sensing.js
Ray Schamp 548aa6dd70 Fix no-useless-call todo
The linter is correct that `devObject[func].call(devObject, args)` is unnecessary because it's equivalent to `devObject[func](args)`.

@tmickel probably either meant to allow passing an array of arguments to be applied, or to call the function with the provided argument. Since we probably want to be able to use multi-argument functions, use `apply` and fix the one place that uses `ioQuery` with an argument.
2017-05-15 21:11:38 -07:00

179 lines
5.9 KiB
JavaScript

const Cast = require('../util/cast');
class Scratch3SensingBlocks {
constructor (runtime) {
/**
* The runtime instantiating this block package.
* @type {Runtime}
*/
this.runtime = runtime;
}
/**
* Retrieve the block primitives implemented by this package.
* @return {object.<string, Function>} Mapping of opcode to Function.
*/
getPrimitives () {
return {
sensing_touchingobject: this.touchingObject,
sensing_touchingcolor: this.touchingColor,
sensing_coloristouchingcolor: this.colorTouchingColor,
sensing_distanceto: this.distanceTo,
sensing_timer: this.getTimer,
sensing_resettimer: this.resetTimer,
sensing_of: this.getAttributeOf,
sensing_mousex: this.getMouseX,
sensing_mousey: this.getMouseY,
sensing_mousedown: this.getMouseDown,
sensing_keypressed: this.getKeyPressed,
sensing_current: this.current,
sensing_dayssince2000: this.daysSince2000,
sensing_loudness: this.getLoudness
};
}
touchingObject (args, util) {
const requestedObject = args.TOUCHINGOBJECTMENU;
if (requestedObject === '_mouse_') {
const mouseX = util.ioQuery('mouse', 'getX');
const mouseY = util.ioQuery('mouse', 'getY');
return util.target.isTouchingPoint(mouseX, mouseY);
} else if (requestedObject === '_edge_') {
return util.target.isTouchingEdge();
}
return util.target.isTouchingSprite(requestedObject);
}
touchingColor (args, util) {
const color = Cast.toRgbColorList(args.COLOR);
return util.target.isTouchingColor(color);
}
colorTouchingColor (args, util) {
const maskColor = Cast.toRgbColorList(args.COLOR);
const targetColor = Cast.toRgbColorList(args.COLOR2);
return util.target.colorIsTouchingColor(targetColor, maskColor);
}
distanceTo (args, util) {
if (util.target.isStage) return 10000;
let targetX = 0;
let targetY = 0;
if (args.DISTANCETOMENU === '_mouse_') {
targetX = util.ioQuery('mouse', 'getX');
targetY = util.ioQuery('mouse', 'getY');
} else {
const distTarget = this.runtime.getSpriteTargetByName(
args.DISTANCETOMENU
);
if (!distTarget) return 10000;
targetX = distTarget.x;
targetY = distTarget.y;
}
const dx = util.target.x - targetX;
const dy = util.target.y - targetY;
return Math.sqrt((dx * dx) + (dy * dy));
}
getTimer (args, util) {
return util.ioQuery('clock', 'projectTimer');
}
resetTimer (args, util) {
util.ioQuery('clock', 'resetProjectTimer');
}
getMouseX (args, util) {
return util.ioQuery('mouse', 'getX');
}
getMouseY (args, util) {
return util.ioQuery('mouse', 'getY');
}
getMouseDown (args, util) {
return util.ioQuery('mouse', 'getIsDown');
}
current (args) {
const menuOption = Cast.toString(args.CURRENTMENU).toLowerCase();
const date = new Date();
switch (menuOption) {
case 'year': return date.getFullYear();
case 'month': return date.getMonth() + 1; // getMonth is zero-based
case 'date': return date.getDate();
case 'dayofweek': return date.getDay() + 1; // getDay is zero-based, Sun=0
case 'hour': return date.getHours();
case 'minute': return date.getMinutes();
case 'second': return date.getSeconds();
}
return 0;
}
getKeyPressed (args, util) {
return util.ioQuery('keyboard', 'getKeyIsDown', [args.KEY_OPTION]);
}
daysSince2000 () {
const msPerDay = 24 * 60 * 60 * 1000;
const start = new Date(2000, 0, 1); // Months are 0-indexed.
const today = new Date();
const dstAdjust = today.getTimezoneOffset() - start.getTimezoneOffset();
let mSecsSinceStart = today.valueOf() - start.valueOf();
mSecsSinceStart += ((today.getTimezoneOffset() - dstAdjust) * 60 * 1000);
return mSecsSinceStart / msPerDay;
}
getLoudness () {
if (typeof this.runtime.audioEngine === 'undefined') return -1;
return this.runtime.audioEngine.getLoudness();
}
getAttributeOf (args) {
let attrTarget;
if (args.OBJECT === '_stage_') {
attrTarget = this.runtime.getTargetForStage();
} else {
attrTarget = this.runtime.getSpriteTargetByName(args.OBJECT);
}
// Generic attributes
if (attrTarget.isStage) {
switch (args.PROPERTY) {
// Scratch 1.4 support
case 'background #': return attrTarget.currentCostume + 1;
case 'backdrop #': return attrTarget.currentCostume + 1;
case 'backdrop name':
return attrTarget.sprite.costumes[attrTarget.currentCostume].name;
case 'volume': return; // @todo: Keep this in mind for sound blocks!
}
} else {
switch (args.PROPERTY) {
case 'x position': return attrTarget.x;
case 'y position': return attrTarget.y;
case 'direction': return attrTarget.direction;
case 'costume #': return attrTarget.currentCostume + 1;
case 'costume name':
return attrTarget.sprite.costumes[attrTarget.currentCostume].name;
case 'size': return attrTarget.size;
case 'volume': return; // @todo: above, keep in mind for sound blocks..
}
}
// Variables
const varName = args.PROPERTY;
if (attrTarget.variables.hasOwnProperty(varName)) {
return attrTarget.variables[varName].value;
}
// Otherwise, 0
return 0;
}
}
module.exports = Scratch3SensingBlocks;