From 3ef61e22489f49b1cf277a3a835669fe1260efd9 Mon Sep 17 00:00:00 2001 From: jokebookservice1 Date: Wed, 22 Aug 2018 20:39:15 +0300 Subject: [PATCH] Make SWITCH COSTUME and SWITCH BACKDROP compatible with 2.0 --- src/blocks/scratch3_looks.js | 97 +++++++++++++++++++++------------- src/sprites/rendered-target.js | 2 + 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js index cc2f2ac4c..92f4995b5 100644 --- a/src/blocks/scratch3_looks.js +++ b/src/blocks/scratch3_looks.js @@ -344,65 +344,86 @@ class Scratch3LooksBlocks { } /** - * Utility function to set the costume or backdrop of a target. + * Utility function to set the costume of a target. * Matches the behavior of Scratch 2.0 for different types of arguments. - * @param {!Target} target Target to set costume/backdrop to. + * @param {!Target} target Target to set costume to. * @param {Any} requestedCostume Costume requested, e.g., 0, 'name', etc. * @param {boolean=} optZeroIndex Set to zero-index the requestedCostume. * @return {Array.} Any threads started by this switch. */ - _setCostumeOrBackdrop (target, - requestedCostume, optZeroIndex) { + _setCostume (target, requestedCostume, optZeroIndex) { if (typeof requestedCostume === 'number') { - target.setCostume(optZeroIndex ? - requestedCostume : requestedCostume - 1); + target.setCostume(optZeroIndex ? requestedCostume : requestedCostume - 1); } else { - const costumeIndex = target.getCostumeIndexByName(requestedCostume); - if (costumeIndex > -1) { + const costumeIndex = target.getCostumeIndexByName(requestedCostume.toString()); + + if (costumeIndex !== -1) { target.setCostume(costumeIndex); - } else if (requestedCostume === 'previous costume' || - requestedCostume === 'previous backdrop') { - target.setCostume(target.currentCostume - 1); - } else if (requestedCostume === 'next costume' || - requestedCostume === 'next backdrop') { + } else if (requestedCostume === 'next costume') { target.setCostume(target.currentCostume + 1); - } else if (requestedCostume === 'random backdrop') { - const numCostumes = target.getCostumes().length; - if (numCostumes > 1) { - let selectedIndex = Math.floor(Math.random() * (numCostumes - 1)); - if (selectedIndex === target.currentCostume) selectedIndex += 1; - target.setCostume(selectedIndex); - } - } else { - const forcedNumber = Number(requestedCostume); - if (!isNaN(forcedNumber)) { - target.setCostume(optZeroIndex ? - forcedNumber : forcedNumber - 1); - } + } else if (requestedCostume === 'previous costume') { + target.setCostume(target.currentCostume - 1); + } else if (!isNaN(requestedCostume) && + (typeof requestedCostume !== 'string' || /\d/g.test(requestedCostume))) { + target.setCostume(optZeroIndex ? Number(requestedCostume) : Number(requestedCostume) - 1); } } - if (target === this.runtime.getTargetForStage()) { - // Target is the stage - start hats. - const newName = target.getCostumes()[target.currentCostume].name; - return this.runtime.startHats('event_whenbackdropswitchesto', { - BACKDROP: newName - }); - } + + // Per 2.0, 'switch costume' can't start threads even in the Stage. return []; } + /** + * Utility function to set the backdrop of a target. + * Matches the behavior of Scratch 2.0 for different types of arguments. + * @param {!Target} stage Target to set backdrop to. + * @param {Any} requestedBackdrop Backdrop requested, e.g., 0, 'name', etc. + * @param {boolean=} optZeroIndex Set to zero-index the requestedBackdrop. + * @return {Array.} Any threads started by this switch. + */ + _setBackdrop (stage, requestedBackdrop, optZeroIndex) { + if (typeof requestedBackdrop === 'number') { + stage.setCostume(optZeroIndex ? requestedBackdrop : requestedBackdrop - 1); + } else if (requestedBackdrop === 'next backdrop') { + stage.setCostume(stage.currentCostume + 1); + } else if (requestedBackdrop === 'previous backdrop') { + stage.setCostume(stage.currentCostume - 1); + } else { + const costumeIndex = stage.getCostumeIndexByName(requestedBackdrop.toString()); + + if (costumeIndex !== -1) { + stage.setCostume(costumeIndex); + } else if (requestedBackdrop === 'random backdrop') { + const numCostumes = stage.getCostumes().length; + if (numCostumes > 1) { + let selectedIndex = Math.floor(Math.random() * (numCostumes - 1)); + if (selectedIndex === stage.currentCostume) selectedIndex += 1; + stage.setCostume(selectedIndex); + } + } else if (!isNaN(requestedBackdrop) && + (typeof requestedBackdrop !== 'string' || /\d/g.test(requestedBackdrop))) { + stage.setCostume(optZeroIndex ? Number(requestedBackdrop) : Number(requestedBackdrop) - 1); + } + } + + const newName = stage.getCostumes()[stage.currentCostume].name; + return this.runtime.startHats('event_whenbackdropswitchesto', { + BACKDROP: newName + }); + } + switchCostume (args, util) { - this._setCostumeOrBackdrop(util.target, args.COSTUME); + this._setCostume(util.target, args.COSTUME); } nextCostume (args, util) { - this._setCostumeOrBackdrop( + this._setCostume( util.target, util.target.currentCostume + 1, true ); } switchBackdrop (args) { - this._setCostumeOrBackdrop(this.runtime.getTargetForStage(), args.BACKDROP); + this._setBackdrop(this.runtime.getTargetForStage(), args.BACKDROP); } switchBackdropAndWait (args, util) { @@ -410,7 +431,7 @@ class Scratch3LooksBlocks { if (!util.stackFrame.startedThreads) { // No - switch the backdrop. util.stackFrame.startedThreads = ( - this._setCostumeOrBackdrop( + this._setBackdrop( this.runtime.getTargetForStage(), args.BACKDROP ) @@ -440,7 +461,7 @@ class Scratch3LooksBlocks { nextBackdrop () { const stage = this.runtime.getTargetForStage(); - this._setCostumeOrBackdrop( + this._setBackdrop( stage, stage.currentCostume + 1, true ); } diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index d21280831..52b9bb850 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -463,6 +463,8 @@ class RenderedTarget extends Target { setCostume (index) { // Keep the costume index within possible values. index = Math.round(index); + if ([Infinity, -Infinity, NaN].includes(index)) index = 0; + this.currentCostume = MathUtil.wrapClamp( index, 0, this.sprite.costumes.length - 1 );