From 2226fda19e32ef19f26e858ed71b51f6a9e66066 Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Wed, 28 Sep 2016 17:09:04 -0400 Subject: [PATCH] Implement rotation style (#223) --- src/blocks/scratch3_motion.js | 5 +++ src/import/sb2import.js | 10 +++++ src/sprites/clone.js | 79 +++++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/blocks/scratch3_motion.js b/src/blocks/scratch3_motion.js index 10679750d..8b8e7356e 100644 --- a/src/blocks/scratch3_motion.js +++ b/src/blocks/scratch3_motion.js @@ -22,6 +22,7 @@ Scratch3MotionBlocks.prototype.getPrimitives = function() { 'motion_turnleft': this.turnLeft, 'motion_pointindirection': this.pointInDirection, 'motion_glidesecstoxy': this.glide, + 'motion_setrotationstyle': this.setRotationStyle, 'motion_changexby': this.changeX, 'motion_setx': this.setX, 'motion_changeyby': this.changeY, @@ -96,6 +97,10 @@ Scratch3MotionBlocks.prototype.glide = function (args, util) { } }; +Scratch3MotionBlocks.prototype.setRotationStyle = function (args, util) { + util.target.setRotationStyle(args.STYLE); +}; + Scratch3MotionBlocks.prototype.changeX = function (args, util) { var dx = Cast.toNumber(args.DX); util.target.setXY(util.target.x + dx, util.target.y); diff --git a/src/import/sb2import.js b/src/import/sb2import.js index dfa6d25e2..79e135a7b 100644 --- a/src/import/sb2import.js +++ b/src/import/sb2import.js @@ -6,6 +6,7 @@ */ var Blocks = require('../engine/blocks'); +var Clone = require('../sprites/clone'); var Sprite = require('../sprites/sprite'); var Color = require('../util/color.js'); var uid = require('../util/uid'); @@ -110,6 +111,15 @@ function parseScratchObject (object, runtime, topLevel) { if (object.hasOwnProperty('currentCostumeIndex')) { target.currentCostume = Math.round(object.currentCostumeIndex); } + if (object.hasOwnProperty('rotationStyle')) { + if (object.rotationStyle == 'none') { + target.rotationStyle = Clone.ROTATION_STYLE_NONE; + } else if (object.rotationStyle == 'leftRight') { + target.rotationStyle = Clone.ROTATION_STYLE_LEFT_RIGHT; + } else if (object.rotationStyle == 'normal') { + target.rotationStyle = Clone.ROTATION_STYLE_ALL_AROUND; + } + } target.isStage = topLevel; target.updateAllDrawableProperties(); // The stage will have child objects; recursively process them. diff --git a/src/sprites/clone.js b/src/sprites/clone.js index f94015c64..14d7b366c 100644 --- a/src/sprites/clone.js +++ b/src/sprites/clone.js @@ -97,6 +97,30 @@ Clone.prototype.size = 100; */ Clone.prototype.currentCostume = 0; +/** + * Rotation style for "all around"/spinning. + * @enum + */ +Clone.ROTATION_STYLE_ALL_AROUND = 'all around'; + +/** + * Rotation style for "left-right"/flipping. + * @enum + */ +Clone.ROTATION_STYLE_LEFT_RIGHT = 'left-right'; + +/** + * Rotation style for "no rotation." + * @enum + */ +Clone.ROTATION_STYLE_NONE = 'don\'t rotate'; + +/** + * Current rotation style. + * @type {!string} + */ +Clone.prototype.rotationStyle = Clone.ROTATION_STYLE_ALL_AROUND; + /** * Map of current graphic effect values. * @type {!Object.} @@ -130,6 +154,26 @@ Clone.prototype.setXY = function (x, y) { } }; +/** + * Get the rendered direction and scale, after applying rotation style. + * @return {Object} Direction and scale to render. + */ +Clone.prototype._getRenderedDirectionAndScale = function () { + // Default: no changes to `this.direction` or `this.scale`. + var finalDirection = this.direction; + var finalScale = [this.size, this.size]; + if (this.rotationStyle == Clone.ROTATION_STYLE_NONE) { + // Force rendered direction to be 90. + finalDirection = 90; + } else if (this.rotationStyle === Clone.ROTATION_STYLE_LEFT_RIGHT) { + // Force rendered direction to be 90, and flip drawable if needed. + finalDirection = 90; + var scaleFlip = (this.direction < 0) ? -1 : 1; + finalScale = [scaleFlip * this.size, this.size]; + } + return {direction: finalDirection, scale: finalScale}; +}; + /** * Set the direction of a clone. * @param {!number} direction New direction of clone. @@ -141,8 +185,10 @@ Clone.prototype.setDirection = function (direction) { // Keep direction between -179 and +180. this.direction = MathUtil.wrapClamp(direction, -179, 180); if (this.renderer) { + var renderedDirectionScale = this._getRenderedDirectionAndScale(); this.renderer.updateDrawableProperties(this.drawableID, { - direction: this.direction + direction: renderedDirectionScale.direction, + scale: renderedDirectionScale.scale }); } }; @@ -191,8 +237,10 @@ Clone.prototype.setSize = function (size) { // Keep size between 5% and 535%. this.size = MathUtil.clamp(size, 5, 535); if (this.renderer) { + var renderedDirectionScale = this._getRenderedDirectionAndScale(); this.renderer.updateDrawableProperties(this.drawableID, { - scale: [this.size, this.size] + direction: renderedDirectionScale.direction, + scale: renderedDirectionScale.scale }); } }; @@ -241,6 +289,27 @@ Clone.prototype.setCostume = function (index) { } }; +/** + * Update the rotation style for this clone. + * @param {!string} rotationStyle New rotation style. + */ +Clone.prototype.setRotationStyle = function (rotationStyle) { + if (rotationStyle == Clone.ROTATION_STYLE_NONE) { + this.rotationStyle = Clone.ROTATION_STYLE_NONE; + } else if (rotationStyle == Clone.ROTATION_STYLE_ALL_AROUND) { + this.rotationStyle = Clone.ROTATION_STYLE_ALL_AROUND; + } else if (rotationStyle == Clone.ROTATION_STYLE_LEFT_RIGHT) { + this.rotationStyle = Clone.ROTATION_STYLE_LEFT_RIGHT; + } + if (this.renderer) { + var renderedDirectionScale = this._getRenderedDirectionAndScale(); + this.renderer.updateDrawableProperties(this.drawableID, { + direction: renderedDirectionScale.direction, + scale: renderedDirectionScale.scale + }); + } +}; + /** * Get a costume index of this clone, by name of the costume. * @param {?string} costumeName Name of a costume. @@ -261,10 +330,11 @@ Clone.prototype.getCostumeIndexByName = function (costumeName) { */ Clone.prototype.updateAllDrawableProperties = function () { if (this.renderer) { + var renderedDirectionScale = this._getRenderedDirectionAndScale(); this.renderer.updateDrawableProperties(this.drawableID, { position: [this.x, this.y], - direction: this.direction, - scale: [this.size, this.size], + direction: renderedDirectionScale.direction, + scale: renderedDirectionScale.scale, visible: this.visible, skin: this.sprite.costumes[this.currentCostume].skin }); @@ -326,6 +396,7 @@ Clone.prototype.makeClone = function () { newClone.visible = this.visible; newClone.size = this.size; newClone.currentCostume = this.currentCostume; + newClone.rotationStyle = this.rotationStyle; newClone.effects = JSON.parse(JSON.stringify(this.effects)); newClone.variables = JSON.parse(JSON.stringify(this.variables)); newClone.lists = JSON.parse(JSON.stringify(this.lists));