From bb82c46f8abb360f895cc88e2283996899b6aa68 Mon Sep 17 00:00:00 2001 From: Katie Broida Date: Thu, 15 Nov 2018 15:50:56 -0500 Subject: [PATCH] Handle coordinate precision the same as Scratch 2 (#1722) --- src/blocks/scratch3_motion.js | 13 +++++++++++-- src/sprites/rendered-target.js | 17 ++--------------- test/unit/blocks_motion.js | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 17 deletions(-) create mode 100644 test/unit/blocks_motion.js diff --git a/src/blocks/scratch3_motion.js b/src/blocks/scratch3_motion.js index a33a62905..9571e5ef1 100644 --- a/src/blocks/scratch3_motion.js +++ b/src/blocks/scratch3_motion.js @@ -262,16 +262,25 @@ class Scratch3MotionBlocks { } getX (args, util) { - return util.target.x; + return this.limitPrecision(util.target.x); } getY (args, util) { - return util.target.y; + return this.limitPrecision(util.target.y); } getDirection (args, util) { return util.target.direction; } + + // This corresponds to snapToInteger in Scratch 2 + limitPrecision (coordinate) { + const rounded = Math.round(coordinate); + const delta = coordinate - rounded; + const limitedCoord = (Math.abs(delta) < 1e-9) ? rounded : coordinate; + + return limitedCoord; + } } module.exports = Scratch3MotionBlocks; diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index e4ec58d84..4c14b013e 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -256,17 +256,6 @@ class RenderedTarget extends Target { }; } - /** - * Round a number to n digits - * @param {number} value The number to be rounded - * @param {number} places The number of decimal places to round to - * @return {number} The rounded number - */ - _roundCoord (value, places) { - const power = Math.pow(10, places); - return Math.round(value * power) / power; - } - /** * Set the X and Y coordinates. * @param {!number} x New X coordinate, in Scratch coordinates. @@ -280,8 +269,6 @@ class RenderedTarget extends Target { const oldY = this.y; if (this.renderer) { const position = this.renderer.getFencedPositionOfDrawable(this.drawableID, [x, y]); - position[0] = this._roundCoord(position[0], 8); - position[1] = this._roundCoord(position[1], 8); this.x = position[0]; this.y = position[1]; @@ -293,8 +280,8 @@ class RenderedTarget extends Target { this.runtime.requestRedraw(); } } else { - this.x = this._roundCoord(x, 8); - this.y = this._roundCoord(y, 8); + this.x = x; + this.y = y; } this.emit(RenderedTarget.EVENT_TARGET_MOVED, this, oldX, oldY, force); this.runtime.requestTargetsUpdate(this); diff --git a/test/unit/blocks_motion.js b/test/unit/blocks_motion.js new file mode 100644 index 000000000..09bcd22bb --- /dev/null +++ b/test/unit/blocks_motion.js @@ -0,0 +1,26 @@ +const test = require('tap').test; +const Motion = require('../../src/blocks/scratch3_motion'); +const Runtime = require('../../src/engine/runtime'); +const Sprite = require('../../src/sprites/sprite.js'); +const RenderedTarget = require('../../src/sprites/rendered-target.js'); + +test('getPrimitives', t => { + const rt = new Runtime(); + const motion = new Motion(rt); + t.type(motion.getPrimitives(), 'object'); + t.end(); +}); + +test('Coordinates have limited precision', t => { + const rt = new Runtime(); + const motion = new Motion(rt); + const sprite = new Sprite(null, rt); + const target = new RenderedTarget(sprite, rt); + const util = {target}; + + motion.goToXY({X: 0.999999999, Y: 0.999999999}, util); + + t.equals(motion.getX({}, util), 1); + t.equals(motion.getY({}, util), 1); + t.end(); +});