diff --git a/package-lock.json b/package-lock.json index 1a6be5e..36ccb2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rarry", - "version": "0.0.0", + "version": "1.6.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rarry", - "version": "0.0.0", + "version": "1.6.4", "dependencies": { "@blockly/field-colour-hsv-sliders": "^6.0.11", "@blockly/plugin-strict-connection-checker": "^6.0.1", @@ -175,7 +175,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -198,7 +197,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -680,7 +678,6 @@ "resolved": "https://registry.npmjs.org/@pixi/assets/-/assets-7.4.3.tgz", "integrity": "sha512-StvjiJBSp/j9hHkGu8AFHNvwYUazXq64WhyhytztyDMRkg/l/cL7EcttY5T0qZNWlIpccdr60LUKrWDOuMpkiw==", "license": "MIT", - "peer": true, "dependencies": { "@types/css-font-loading-module": "^0.0.12" }, @@ -693,7 +690,6 @@ "resolved": "https://registry.npmjs.org/@pixi/canvas-display/-/canvas-display-7.4.3.tgz", "integrity": "sha512-Y33a6DL2s6RFIPKfC1tCw8eimVnaQVrzhOUgSZ03jE5B2pC7FwcOIZ64sDi2VpVToXMl2f5EgkgtEXYkWjTYHg==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/display": "7.4.3" } @@ -760,7 +756,6 @@ "resolved": "https://registry.npmjs.org/@pixi/canvas-renderer/-/canvas-renderer-7.4.3.tgz", "integrity": "sha512-mZnx/tUaNlREh6Yn/z54g0NRvLEdlWIgA5qioeZbJA2HeG+zKEio7hUEOsNIu2o6xzliUoFGzFr7jaS+m7onfg==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3" } @@ -770,7 +765,6 @@ "resolved": "https://registry.npmjs.org/@pixi/canvas-sprite/-/canvas-sprite-7.4.3.tgz", "integrity": "sha512-Qr17o6AgDihXJGg+lZr8HV5mhvWW46v/+15AY7TFQhJytPv32Y6tJMfojVWquOpzREczMqryun1K5vJpAuinQA==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/canvas-display": "7.4.3", "@pixi/canvas-renderer": "7.4.3", @@ -837,7 +831,6 @@ "resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.4.3.tgz", "integrity": "sha512-5YDs11faWgVVTL8VZtLU05/Fl47vaP5Tnsbf+y/WRR0VSW3KhRRGTBU1J3Gdc2xEWbJhUK07KGP7eSZpvtPVgA==", "license": "MIT", - "peer": true, "dependencies": { "@pixi/color": "7.4.3", "@pixi/constants": "7.4.3", @@ -858,7 +851,6 @@ "resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.4.3.tgz", "integrity": "sha512-b5m2dAaoNAVdxz1oDaxl3XZ059NEOcNtGkxTOZ4EYCw/jcp9sZXkgSROHRzsGn4k+NugH7+9MP4Id2Z0kkdUhw==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3" } @@ -868,7 +860,6 @@ "resolved": "https://registry.npmjs.org/@pixi/events/-/events-7.4.3.tgz", "integrity": "sha512-o3j/5Dxq6WDVS6eHfURB/cf/MP+NcsF/eC5PnbSHjXxJmDE7PoTVwLvxexm5uuvNRpFh/6/Fn0V8Vl4gV8sc8w==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3" @@ -885,7 +876,6 @@ "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.4.3.tgz", "integrity": "sha512-HNvGNrEVaeVsbcnIO1MsHpjZbTwo9nIlaOEBzDGcL6JWwzuB1RnzUke7WUCndCUt91sGUdvPnvgCvy9/NNFg3w==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3" } @@ -949,7 +939,6 @@ "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.4.3.tgz", "integrity": "sha512-wWLivD8/URb8A7X4TqCZGG39C91IE+aOuWY/z9NCz5Z6WvA/VWnsc5fLTlO+ggjGHgKF0cSucCXZfUe1wm0AOQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3", @@ -967,7 +956,6 @@ "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.4.3.tgz", "integrity": "sha512-CikqFPtKvU3Zj986/MSoC8X39CWv5CEpiEW/tYp47p4tgQNDSkNWYnDiNYgb+4VX6pNsBrgX4DALLdTR17SlSA==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3" @@ -978,7 +966,6 @@ "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.4.3.tgz", "integrity": "sha512-EqpxpVZoTObyupxMSzuUsCGmWPQioW84n9EO9Ajawkk/HYA+qKFZ5viKiEThIUBYgv4Apn/7c0U3Feg7Ez4uQQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/mesh": "7.4.3" @@ -1019,7 +1006,6 @@ "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.4.3.tgz", "integrity": "sha512-0DfJF5C0XTfuI2FsLYvMKCOtqWjXWGOWfA6m4l0W/Ke/qw5zKIOEhgjPLw4qNRtOhmEfkVKJUGp66Ap/ya2YzA==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3", @@ -1031,7 +1017,6 @@ "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.4.3.tgz", "integrity": "sha512-OjJHGKXPzwP5OLKxBnTBnKMOktHynLvO0TQPqTYgNtmGQzY109mypCqM4M+s/V+uYmBo/T+sXvBahj98q/f1tA==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3", @@ -1061,7 +1046,6 @@ "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.4.3.tgz", "integrity": "sha512-iNBrpOFF9nXDT6m2jcyYy6l/sRzklLDDck1eFHprHZwvNquY2nzRfh+RGBCecxhBcijiLJ3fsZN33fP0LDXkvw==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3" @@ -1082,7 +1066,6 @@ "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.4.3.tgz", "integrity": "sha512-kUa9cEcMsGXSIZoXA7LhW4oo0eWa30w0KYd7mZ0bqalBMfOcvsGZMN701Lc5lpE8URw+8yu5bnyGLbrxhWBTuw==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/display": "7.4.3", @@ -1104,7 +1087,6 @@ "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.4.3.tgz", "integrity": "sha512-IAF0iu04rPg3oiL0HZsEZI44fpJxq3UZ4xTmx8l1RyhhSXiElLvvSlSH57vt/BKMQZtCs+AqEit7yn8heK2+nQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@pixi/core": "7.4.3", "@pixi/sprite": "7.4.3" @@ -1795,7 +1777,6 @@ "resolved": "https://registry.npmjs.org/blockly/-/blockly-12.2.0.tgz", "integrity": "sha512-s4QL9ogEMzc4Pxfe8Oi3Kmu6SQ0ts2thzmRYjdnMSEIVZFpBZ4OUuNKvpFICqujO0yfAo99zON8KzxAFw8hA1w==", "license": "Apache-2.0", - "peer": true, "dependencies": { "jsdom": "26.1.0" }, @@ -2390,7 +2371,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, diff --git a/src/blocks/control.js b/src/blocks/control.js index 4af5ea1..64bf703 100644 --- a/src/blocks/control.js +++ b/src/blocks/control.js @@ -1,10 +1,12 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; import { spriteManager } from "../scripts/editor"; +import { quickBlockMaker } from "./quickblockmaker"; const xmlUtils = Blockly.utils.xml; -Blockly.Blocks["controls_switch"] = { - init: function () { +quickBlockMaker( + "controls_switch", + function () { this.appendValueInput("VALUE").appendField("switch"); this.appendStatementInput("DO").setCheck("switchcase"); this.setPreviousStatement(true, "default"); @@ -12,14 +14,13 @@ Blockly.Blocks["controls_switch"] = { this.setStyle("control_blocks"); this.setTooltip("Make the input be used to be matched inside of cases."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_switch"] = function (block, generator) { - const branch = generator.statementToCode(block, "DO"); - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC) || "''"; - return `switch (${value}) { + function (block, generator) { + const branch = generator.statementToCode(block, "DO"); + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC) || "''"; + return `switch (${value}) { ${branch}}\n`; -}; + } +); Blockly.Blocks["controls_switch_case"] = { init: function () { @@ -145,17 +146,22 @@ BlocklyJS.javascriptGenerator.forBlock["controls_switch_case"] = function ( return `${parts.join(" ")} {\n ${branch}break;\n}`; }; -Blockly.Blocks["wait_one_frame"] = { - init: function () { +quickBlockMaker( + "wait_one_frame", + function () { this.appendDummyInput().appendField("wait one frame"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("control_blocks"); }, -}; + function () { + return `yield* waitOneFrame();\n`; + } +); -Blockly.Blocks["wait_block"] = { - init: function () { +quickBlockMaker( + "wait_block", + function () { this.appendValueInput("AMOUNT").setCheck("Number").appendField("wait"); this.appendDummyInput().appendField( new Blockly.FieldDropdown([ @@ -168,20 +174,16 @@ Blockly.Blocks["wait_block"] = { this.setNextStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["wait_one_frame"] = function (block) { - return `yield* waitOneFrame();\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["wait_block"] = function (block, generator) { - const duration = generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; - const menu = block.getFieldValue("MENU") || 0; - return `yield* wait(${duration} * ${+menu});\n`; -}; + function (block, generator) { + const duration = generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; + const menu = block.getFieldValue("MENU") || 0; + return `yield* wait(${duration} * ${+menu});\n`; + } +); -Blockly.Blocks["controls_thread_create"] = { - init: function () { +quickBlockMaker( + "controls_thread_create", + function () { this.appendDummyInput().appendField("run in new thread"); this.appendStatementInput("code").setCheck("default"); this.setTooltip("Create and run the code specified in a new thread"); @@ -189,32 +191,29 @@ Blockly.Blocks["controls_thread_create"] = { this.setNextStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_thread_create"] = function ( - block, - generator, -) { - const code = generator.statementToCode(block, "code"); - return `vm.execute(function* (sprite) {\n${code}}, getTargetData());\n`; -}; + function (block, generator) { + const code = generator.statementToCode(block, "code"); + return `vm.execute(function* (sprite) {\n${code}}, getTargetData());\n`; + } +); -Blockly.Blocks["controls_thread_current"] = { - init: function () { +quickBlockMaker( + "controls_thread_current", + function () { this.appendDummyInput().appendField("current thread"); this.setOutput(true, "ThreadID"); this.setStyle("control_blocks"); this.setTooltip("Return the ID of the currently running thread"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_thread_current"] = () => [ - `/* Thread.getCurrentContext().id */`, - BlocklyJS.Order.MEMBER, -]; + () => [ + `/* Thread.getCurrentContext().id */`, + BlocklyJS.Order.MEMBER, + ] +); -Blockly.Blocks["controls_thread_set_var"] = { - init: function () { +quickBlockMaker( + "controls_thread_set_var", + function () { this.appendValueInput("NAME").setCheck("String").appendField("set variable"); this.appendValueInput("VALUE").appendField("to"); this.appendValueInput("THREAD").setCheck("ThreadID").appendField("in thread"); @@ -224,21 +223,18 @@ Blockly.Blocks["controls_thread_set_var"] = { this.setStyle("control_blocks"); this.setTooltip("Set a variable inside the given thread"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_thread_set_var"] = function ( - block, - generator, -) { - const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; - const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; - const value = - generator.valueToCode(block, "VALUE", BlocklyJS.Order.NONE) || "undefined"; - return `/* Thread.set(${threadId}, ${name}, ${value}); */\n`; -}; + function (block, generator) { + const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; + const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; + const value = + generator.valueToCode(block, "VALUE", BlocklyJS.Order.NONE) || "undefined"; + return `/* Thread.set(${threadId}, ${name}, ${value}); */\n`; + } +); -Blockly.Blocks["controls_thread_get_var"] = { - init: function () { +quickBlockMaker( + "controls_thread_get_var", + function () { this.appendValueInput("NAME").setCheck("String").appendField("get variable"); this.appendValueInput("THREAD").setCheck("ThreadID").appendField("from thread"); this.setInputsInline(true); @@ -246,20 +242,17 @@ Blockly.Blocks["controls_thread_get_var"] = { this.setStyle("control_blocks"); this.setTooltip("Get a variable from the given thread"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_thread_get_var"] = function ( - block, - generator, -) { - const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; - const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; - const code = `/* Thread.get(${threadId}, ${name}) */`; - return [code, BlocklyJS.Order.FUNCTION_CALL]; -}; + function (block, generator) { + const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; + const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; + const code = `/* Thread.get(${threadId}, ${name}) */`; + return [code, BlocklyJS.Order.FUNCTION_CALL]; + } +); -Blockly.Blocks["controls_thread_has_var"] = { - init: function () { +quickBlockMaker( + "controls_thread_has_var", + function () { this.appendValueInput("NAME").setCheck("String").appendField("variable"); this.appendValueInput("THREAD").setCheck("ThreadID").appendField("exists in thread"); this.setInputsInline(true); @@ -267,20 +260,17 @@ Blockly.Blocks["controls_thread_has_var"] = { this.setStyle("control_blocks"); this.setTooltip("Checks if a variable exists in the given thread"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_thread_has_var"] = function ( - block, - generator, -) { - const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; - const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; - const code = `/* Thread.has(${threadId}, ${name}) */`; - return [code, BlocklyJS.Order.FUNCTION_CALL]; -}; + function (block, generator) { + const threadId = generator.valueToCode(block, "THREAD", BlocklyJS.Order.NONE) || "null"; + const name = generator.valueToCode(block, "NAME", BlocklyJS.Order.NONE) || '""'; + const code = `/* Thread.has(${threadId}, ${name}) */`; + return [code, BlocklyJS.Order.FUNCTION_CALL]; + } +); -Blockly.Blocks["controls_run_instantly"] = { - init: function () { +quickBlockMaker( + "controls_run_instantly", + function () { this.appendDummyInput().appendField("run instantly"); this.appendStatementInput("do"); this.setPreviousStatement(true, "default"); @@ -288,22 +278,21 @@ Blockly.Blocks["controls_run_instantly"] = { this.setStyle("control_blocks"); this.setTooltip("Run inside code without frame delay."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_run_instantly"] = function (block) { - const branch = BlocklyJS.javascriptGenerator.statementToCode(block, "do"); - return `const __prevFast = thread.fastExecution;\nthread.fastExecution = true;\n${branch}thread.fastExecution = __prevFast;\n`; -}; + function (block) { + const branch = BlocklyJS.javascriptGenerator.statementToCode(block, "do"); + return `const __prevFast = thread.fastExecution;\nthread.fastExecution = true;\n${branch}thread.fastExecution = __prevFast;\n`; + } +); -Blockly.Blocks["controls_stopscript"] = { - init: function () { +quickBlockMaker( + "controls_stopscript", + function () { this.appendDummyInput().appendField("stop this script"); this.setPreviousStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_stopscript"] = () => "return;\n"; + () => "return;\n" +); Blockly.Blocks["controls_stopblock"] = { init: function () { @@ -367,26 +356,24 @@ BlocklyJS.javascriptGenerator.forBlock["controls_stopblock"] = block => { return ""; }; -Blockly.Blocks["controls_stop_sprite"] = { - init: function () { +quickBlockMaker( + "controls_stop_sprite", + function () { this.appendValueInput("ID").setCheck("String").appendField("stop sprite"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("control_blocks"); this.setTooltip("Stops all scripts for the specified sprite."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_stop_sprite"] = function ( - block, - generator, -) { - const spriteId = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC) || "''"; - return `vm.stopForTarget(vm.runtime.getTargetById(${spriteId}));\n`; -}; + function (block, generator) { + const spriteId = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC) || "''"; + return `vm.stopForTarget(vm.runtime.getTargetById(${spriteId}));\n`; + } +); -Blockly.Blocks["controls_sprites_menu"] = { - init: function () { +quickBlockMaker( + "controls_sprites_menu", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown(() => { const sprites = spriteManager.getOriginals(); @@ -399,94 +386,82 @@ Blockly.Blocks["controls_sprites_menu"] = { this.setOutput(true, "String"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_sprites_menu"] = function ( - block, - generator, -) { - return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; -}; + function (block, generator) { + return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; + } +); -Blockly.Blocks["controls_createclone"] = { - init: function () { +quickBlockMaker( + "controls_createclone", + function () { this.appendValueInput("ID").setCheck("String").appendField("create clone of"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_createclone"] = function ( - block, - generator, -) { - const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); - return `spriteManager.clone(spriteManager.get(${ID}));\n`; -}; + function (block, generator) { + const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); + return `spriteManager.clone(spriteManager.get(${ID}));\n`; + } +); -Blockly.Blocks["controls_delete_this_clone"] = { - init: function () { +quickBlockMaker( + "controls_delete_this_clone", + function () { this.appendDummyInput().appendField("delete this clone"); this.setPreviousStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_delete_this_clone"] = function () { - return `if (getTargetData().clone) { + function () { + return `if (getTargetData().clone) { spriteManager.remove(getTargetData()); return; }\n`; -}; + } +); -Blockly.Blocks["controls_delete_all_clones"] = { - init: function () { +quickBlockMaker( + "controls_delete_all_clones", + function () { this.appendValueInput("ID").setCheck("String").appendField("delete all clones of"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_delete_all_clones"] = function ( - block, - generator, -) { - const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); - return `spriteManager.removeClones(spriteManager.get(${ID}));\n`; -}; + function (block, generator) { + const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); + return `spriteManager.removeClones(spriteManager.get(${ID}));\n`; + } +); -Blockly.Blocks["controls_is_clone"] = { - init: function () { +quickBlockMaker( + "controls_is_clone", + function () { this.appendDummyInput().appendField("is clone?"); this.setOutput(true, "Boolean"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_is_clone"] = function () { - return ["getTargetData().clone", BlocklyJS.Order.ATOMIC]; -}; + function () { + return ["getTargetData().clone", BlocklyJS.Order.ATOMIC]; + } +); -Blockly.Blocks["controls_whenstartasclone"] = { - init: function () { +quickBlockMaker( + "controls_whenstartasclone", + function () { this.appendDummyInput().appendField("when I start as a clone"); this.appendStatementInput("DO").setCheck("default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_whenstartasclone"] = function ( - block, - generator, -) { - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("clone", null, function* (sprite) {\n${branch}});\n`; -}; + function (block, generator) { + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("clone", null, function* (sprite) {\n${branch}});\n`; + } +); -Blockly.Blocks["controls_as_sprite"] = { - init() { +quickBlockMaker( + "controls_as_sprite", + function () { this.appendValueInput("ID").setCheck("String").appendField("as sprite"); this.appendStatementInput("DO").setCheck("default"); this.setPreviousStatement(true, "default"); @@ -494,50 +469,47 @@ Blockly.Blocks["controls_as_sprite"] = { this.setStyle("control_blocks"); this.setTooltip("Run the code as another sprite or clone."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_as_sprite"] = function ( - block, - generator, -) { - const target = generator.valueToCode(block, "ID", BlocklyJS.Order.NONE) || '""'; - const code = generator.statementToCode(block, "DO"); + function (block, generator) { + const target = generator.valueToCode(block, "ID", BlocklyJS.Order.NONE) || '""'; + const code = generator.statementToCode(block, "DO"); - return `vm.execute(function* () {\n${code}}, spriteManager.get(${target}));\n`; -}; + return `vm.execute(function* () {\n${code}}, spriteManager.get(${target}));\n`; + } +); -Blockly.Blocks["controls_forever"] = { - init: function () { +quickBlockMaker( + "controls_forever", + function () { this.appendDummyInput().appendField("forever"); this.appendStatementInput("DO").setCheck("default"); this.setPreviousStatement(true, "default"); this.setStyle("control_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_forever"] = function (block, generator) { - const branch = generator.statementToCode(block, "DO"); - const loopTrap = generator.addLoopTrap(branch, block); - return `while (true) {\n${loopTrap}}\n`; -}; + function (block, generator) { + const branch = generator.statementToCode(block, "DO"); + const loopTrap = generator.addLoopTrap(branch, block); + return `while (true) {\n${loopTrap}}\n`; + } +); -Blockly.Blocks["controls_forLoop_var"] = { - init() { +quickBlockMaker( + "controls_forLoop_var", + function () { this.appendDummyInput().appendField("i"); this.setOutput(true, "Number"); this.setDuplicateOnDrag(true); this.setStyle("control_blocks"); this.setTooltip("The current value of i in the for loop."); }, -}; + () => [ + `__controlsForLoopVar`, + BlocklyJS.Order.ATOMIC, + ] +); -BlocklyJS.javascriptGenerator.forBlock["controls_forLoop_var"] = () => [ - `__controlsForLoopVar`, - BlocklyJS.Order.ATOMIC, -]; - -Blockly.Blocks["controls_forLoop"] = { - init() { +quickBlockMaker( + "controls_forLoop", + function () { this.appendValueInput("VAR").appendField("for each"); this.appendValueInput("START").setCheck("Number").appendField("in range"); this.appendValueInput("END").setCheck("Number").appendField("to"); @@ -548,16 +520,15 @@ Blockly.Blocks["controls_forLoop"] = { this.setStyle("control_blocks"); this.setTooltip("Runs the code for each value of i from start to end (inclusive)."); }, -}; + function (block, generator) { + const start = generator.valueToCode(block, "START", BlocklyJS.Order.NONE) || "0"; + const end = generator.valueToCode(block, "END", BlocklyJS.Order.NONE) || "0"; + const branch = generator.statementToCode(block, "DO"); + const loopTrap = generator.addLoopTrap(branch, block); -BlocklyJS.javascriptGenerator.forBlock["controls_forLoop"] = function (block, generator) { - const start = generator.valueToCode(block, "START", BlocklyJS.Order.NONE) || "0"; - const end = generator.valueToCode(block, "END", BlocklyJS.Order.NONE) || "0"; - const branch = generator.statementToCode(block, "DO"); - const loopTrap = generator.addLoopTrap(branch, block); - - const code = `for (let __controlsForLoopVar = ${start}; __controlsForLoopVar <= ${end}; __controlsForLoopVar++) { + const code = `for (let __controlsForLoopVar = ${start}; __controlsForLoopVar <= ${end}; __controlsForLoopVar++) { ${loopTrap}}\n`; - return code; -}; + return code; + } +); diff --git a/src/blocks/event.js b/src/blocks/event.js index 4e1cd24..c44ac27 100644 --- a/src/blocks/event.js +++ b/src/blocks/event.js @@ -1,8 +1,10 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["when_flag_clicked"] = { - init: function () { +quickBlockMaker( + "when_flag_clicked", + function () { this.appendDummyInput() .appendField("when") .appendField( @@ -12,23 +14,20 @@ Blockly.Blocks["when_flag_clicked"] = { this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["when_flag_clicked"] = function ( - block, - generator -) { - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("flag", null, function* (sprite) {\n${branch}});\n`; -}; + function (block, generator) { + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("flag", null, function* (sprite) {\n${branch}});\n`; + } +); const normalKeys = [ ..."abcdefghijklmnopqrstuvwxyz", ..."abcdefghijklmnopqrstuvwxyz0123456789".toUpperCase(), ]; -Blockly.Blocks["when_key_clicked"] = { - init: function () { +quickBlockMaker( + "when_key_clicked", + function () { this.appendDummyInput() .appendField("when") .appendField( @@ -49,49 +48,43 @@ Blockly.Blocks["when_key_clicked"] = { this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["when_key_clicked"] = function ( - block, - generator -) { - const key = block.getFieldValue("KEY"); - const safeKey = generator.quote_(key); - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("key", ${safeKey}, function* (sprite) {\n${branch}});\n`; -}; - -Blockly.Blocks["when_stage_clicked"] = { - init: function () { + function (block, generator) { + const key = block.getFieldValue("KEY"); + const safeKey = generator.quote_(key); + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("key", ${safeKey}, function* (sprite) {\n${branch}});\n`; + } +); + +quickBlockMaker( + "when_stage_clicked", + function () { this.appendDummyInput() .appendField("when stage clicked"); this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["when_stage_clicked"] = function ( - block, - generator -) { - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("stageClick", null, function* (sprite) {\n${branch}});\n`; -}; - -Blockly.Blocks["project_timer"] = { - init: function () { + function (block, generator) { + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("stageClick", null, function* (sprite) {\n${branch}});\n`; + } +); + +quickBlockMaker( + "project_timer", + function () { this.appendDummyInput().appendField("project timer"); this.setOutput(true, "Number"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["project_timer"] = function (block) { - return ["projectTime()", BlocklyJS.Order.NONE]; -}; - -Blockly.Blocks["when_timer_reaches"] = { - init: function () { + function () { + return ["projectTime()", BlocklyJS.Order.NONE]; + } +); + +quickBlockMaker( + "when_timer_reaches", + function () { this.appendDummyInput() .appendField("when timer reaches") .appendField(new Blockly.FieldNumber(2, 0), "VALUE") @@ -99,19 +92,16 @@ Blockly.Blocks["when_timer_reaches"] = { this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["when_timer_reaches"] = function ( - block, - generator -) { - const value = block.getFieldValue("VALUE"); - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("timer", ${value}, function* (sprite) {\n${branch}});\n`; -}; - -Blockly.Blocks["every_seconds"] = { - init: function () { + function (block, generator) { + const value = block.getFieldValue("VALUE"); + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("timer", ${value}, function* (sprite) {\n${branch}});\n`; + } +); + +quickBlockMaker( + "every_seconds", + function () { this.appendDummyInput() .appendField("every") .appendField(new Blockly.FieldNumber(2, 0.1), "SECONDS") @@ -119,19 +109,16 @@ Blockly.Blocks["every_seconds"] = { this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["every_seconds"] = function ( - block, - generator -) { - const seconds = block.getFieldValue("SECONDS"); - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("interval", ${seconds}, function* (sprite) {\n${branch}});\n`; -}; - -Blockly.Blocks["when_custom_event_triggered"] = { - init: function () { + function (block, generator) { + const seconds = block.getFieldValue("SECONDS"); + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("interval", ${seconds}, function* (sprite) {\n${branch}});\n`; + } +); + +quickBlockMaker( + "when_custom_event_triggered", + function () { this.appendDummyInput() .appendField("when") .appendField(new Blockly.FieldTextInput("event_name"), "EVENT") @@ -139,19 +126,16 @@ Blockly.Blocks["when_custom_event_triggered"] = { this.appendStatementInput("DO").setCheck("default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["when_custom_event_triggered"] = function ( - block, - generator -) { - const event = generator.quote_(block.getFieldValue("EVENT")); - const branch = generator.statementToCode(block, "DO"); - return `registerEvent("custom", ${event}, function* (sprite) {\n${branch}});\n`; -}; - -Blockly.Blocks["trigger_custom_event"] = { - init: function () { + function (block, generator) { + const event = generator.quote_(block.getFieldValue("EVENT")); + const branch = generator.statementToCode(block, "DO"); + return `registerEvent("custom", ${event}, function* (sprite) {\n${branch}});\n`; + } +); + +quickBlockMaker( + "trigger_custom_event", + function () { this.appendDummyInput() .appendField("trigger") .appendField(new Blockly.FieldTextInput("event_name"), "EVENT"); @@ -159,11 +143,8 @@ Blockly.Blocks["trigger_custom_event"] = { this.setNextStatement(true, "default"); this.setStyle("events_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["trigger_custom_event"] = function ( - block -) { - const event = BlocklyJS.javascriptGenerator.quote_(block.getFieldValue("EVENT")); - return `triggerCustomEvent(${event});\n`; -}; + function (block) { + const event = BlocklyJS.javascriptGenerator.quote_(block.getFieldValue("EVENT")); + return `triggerCustomEvent(${event});\n`; + } +); diff --git a/src/blocks/json.js b/src/blocks/json.js index 64edd2b..ee29b0e 100644 --- a/src/blocks/json.js +++ b/src/blocks/json.js @@ -1,5 +1,6 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; const xmlUtils = Blockly.utils.xml; function assure(generator, code) { @@ -12,33 +13,31 @@ function assure(generator, code) { return `${fn}(${code})`; } -Blockly.Blocks["json_length"] = { - init: function () { +quickBlockMaker( + "json_length", + function () { this.appendValueInput("OBJECT").setCheck("Object").appendField("length of"); this.setOutput(true, "Number"); this.setInputsInline(true); this.setStyle("json_category"); this.setTooltip("Returns the length of an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_length"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - - const safe = assure(generator, obj); - return [`Object.keys(${safe}).length`, BlocklyJS.Order.MEMBER]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + + const safe = assure(generator, obj); + return [`Object.keys(${safe}).length`, BlocklyJS.Order.MEMBER]; + } +); -Blockly.Blocks["json_isEmpty"] = { - init: function () { +quickBlockMaker( + "json_isEmpty", + function () { this.appendValueInput("OBJECT").setCheck("Object"); this.appendDummyInput().appendField("is empty"); this.setOutput(true, "Boolean"); @@ -46,25 +45,22 @@ Blockly.Blocks["json_isEmpty"] = { this.setStyle("json_category"); this.setTooltip("Returns true if the object is empty."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_isEmpty"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - - const safe = assure(generator, obj); - return [`Object.keys(${safe}).length === 0`, BlocklyJS.Order.EQUALITY]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + + const safe = assure(generator, obj); + return [`Object.keys(${safe}).length === 0`, BlocklyJS.Order.EQUALITY]; + } +); -Blockly.Blocks["json_get"] = { - init: function () { +quickBlockMaker( + "json_get", + function () { this.appendValueInput("KEY").setCheck("String").appendField("value of"); this.appendValueInput("OBJECT").setCheck("Object").appendField("in object"); this.setOutput(true); @@ -72,32 +68,29 @@ Blockly.Blocks["json_get"] = { this.setStyle("json_category"); this.setTooltip("Returns the value of a key from an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_get"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - - const safe = assure(generator, obj); - return [`${safe}[${key}]`, BlocklyJS.Order.MEMBER]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + + const safe = assure(generator, obj); + return [`${safe}[${key}]`, BlocklyJS.Order.MEMBER]; + } +); /* --- start deprecated */ -Blockly.Blocks["json_set"] = { - init: function () { +quickBlockMaker( + "json_set", + function () { this.appendValueInput("OBJECT").setCheck("Object").appendField("in object"); this.appendValueInput("KEY").setCheck("String").appendField("set"); this.appendValueInput("VALUE").appendField("to"); @@ -107,32 +100,32 @@ Blockly.Blocks["json_set"] = { this.setStyle("json_category"); this.setTooltip("Sets a value to a key in an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_set"] = function (block) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.MEMBER, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - const value = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.ASSIGNMENT, - ) || "null"; - return `${obj}[${key}] = ${value};\n`; -}; + function (block) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.MEMBER, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + const value = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.ASSIGNMENT, + ) || "null"; + return `${obj}[${key}] = ${value};\n`; + } +); -Blockly.Blocks["json_delete"] = { - init: function () { +quickBlockMaker( + "json_delete", + function () { this.appendValueInput("OBJECT").setCheck("Object").appendField("in object"); this.appendValueInput("KEY").setCheck("String").appendField("remove"); this.setPreviousStatement(true); @@ -141,27 +134,27 @@ Blockly.Blocks["json_delete"] = { this.setStyle("json_category"); this.setTooltip("Deletes a key from an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_delete"] = function (block) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.MEMBER, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - return `delete ${obj}[${key}];\n`; -}; + function (block) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.MEMBER, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + return `delete ${obj}[${key}];\n`; + } +); /* --- end deprecated --- */ -Blockly.Blocks["json_set_return"] = { - init: function () { +quickBlockMaker( + "json_set_return", + function () { this.appendValueInput("OBJECT").setCheck("Object").appendField("in object"); this.appendValueInput("KEY").setCheck("String").appendField("set"); this.appendValueInput("VALUE").appendField("to"); @@ -172,38 +165,35 @@ Blockly.Blocks["json_set_return"] = { "Sets a value to a key in an object and returns the object.", ); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_set_return"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - const value = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.NONE, - ) || "null"; - - const safe = assure(generator, obj); - const code = `(() => { const _ = ${safe}; _[${key}] = ${value}; return _; })()`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + const value = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.NONE, + ) || "null"; + + const safe = assure(generator, obj); + const code = `(() => { const _ = ${safe}; _[${key}] = ${value}; return _; })()`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["json_delete_return"] = { - init: function () { +quickBlockMaker( + "json_delete_return", + function () { this.appendValueInput("OBJECT").setCheck("Object").appendField("in object"); this.appendValueInput("KEY").setCheck("String").appendField("remove"); this.setInputsInline(true); @@ -211,29 +201,25 @@ Blockly.Blocks["json_delete_return"] = { this.setStyle("json_category"); this.setTooltip("Deletes a key from an object and returns the object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_delete_return"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - - const safe = assure(generator, obj); - const code = `(() => { const _ = ${safe}; delete _[${key}]; return _; })()`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + + const safe = assure(generator, obj); + const code = `(() => { const _ = ${safe}; delete _[${key}]; return _; })()`; + return [code, BlocklyJS.Order.NONE]; + } +); Blockly.Blocks["json_create_item"] = { init: function () { @@ -247,8 +233,9 @@ Blockly.Blocks["json_create_item"] = { }; /* --- start deprecated --- */ -Blockly.Blocks["json_key_value"] = { - init: function () { +quickBlockMaker( + "json_key_value", + function () { this.appendValueInput("KEY").setCheck("String").appendField("key"); this.appendValueInput("VALUE").setCheck(null).appendField("value"); this.setInputsInline(true); @@ -257,24 +244,23 @@ Blockly.Blocks["json_key_value"] = { this.setOutput(true, "ObjectItem"); this.setInputsInline(true); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_key_value"] = function (block) { - const keyCode = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - const valCode = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.ATOMIC, - ) || "null"; - const code = `${keyCode}: ${valCode}`; - return [code, BlocklyJS.Order.ATOMIC]; -}; + function (block) { + const keyCode = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + const valCode = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.ATOMIC, + ) || "null"; + const code = `${keyCode}: ${valCode}`; + return [code, BlocklyJS.Order.ATOMIC]; + } +); Blockly.Blocks["json_create"] = { init: function () { @@ -420,28 +406,27 @@ BlocklyJS.javascriptGenerator.forBlock["json_create"] = function (block) { }; /* --- end deprecated --- */ -Blockly.Blocks["json_create_statement"] = { - init: function () { +quickBlockMaker( + "json_create_statement", + function () { this.appendDummyInput().appendField("create object"); this.appendStatementInput("STACK").setCheck("json_key_value"); this.setOutput(true, "Object"); this.setStyle("json_category"); this.setTooltip("Create an object using stacked key/value pairs."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_create_statement"] = function ( - block, -) { - const statements = BlocklyJS.javascriptGenerator.statementToCode( - block, - "STACK", - ); - return [`{\n${statements}}`, BlocklyJS.Order.ATOMIC]; -}; + function (block) { + const statements = BlocklyJS.javascriptGenerator.statementToCode( + block, + "STACK", + ); + return [`{\n${statements}}`, BlocklyJS.Order.ATOMIC]; + } +); -Blockly.Blocks["json_key_value_statement"] = { - init: function () { +quickBlockMaker( + "json_key_value_statement", + function () { this.appendValueInput("KEY").setCheck("String").appendField("key"); this.appendValueInput("VALUE").appendField("value"); this.setPreviousStatement(true, "json_key_value"); @@ -450,31 +435,28 @@ Blockly.Blocks["json_key_value_statement"] = { this.setStyle("json_category"); this.setTooltip("A single key/value pair for an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_key_value_statement"] = function ( - block, - generator, -) { - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.ATOMIC, - ) || ""; - const value = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.ATOMIC, - ) || "null"; - - if (key) return `[${key}]: ${value},\n`; - else return ""; -}; + function (block) { + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.ATOMIC, + ) || ""; + const value = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.ATOMIC, + ) || "null"; + + if (key) return `[${key}]: ${value},\n`; + return ""; + } +); -Blockly.Blocks["json_has_key"] = { - init: function () { +quickBlockMaker( + "json_has_key", + function () { this.appendValueInput("OBJECT") .setCheck("Object") .appendField("does object"); @@ -484,31 +466,28 @@ Blockly.Blocks["json_has_key"] = { this.setStyle("json_category"); this.setTooltip("Returns true if the key exists in the object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_has_key"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - const key = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "KEY", - BlocklyJS.Order.NONE, - ) || '""'; - - const safe = assure(generator, obj); - return [`(${key} in ${safe})`, BlocklyJS.Order.RELATIONAL]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + const key = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "KEY", + BlocklyJS.Order.NONE, + ) || '""'; + + const safe = assure(generator, obj); + return [`(${key} in ${safe})`, BlocklyJS.Order.RELATIONAL]; + } +); -Blockly.Blocks["json_property_list"] = { - init: function () { +quickBlockMaker( + "json_property_list", + function () { this.appendValueInput("OBJECT") .setCheck("Object") .appendField( @@ -524,30 +503,26 @@ Blockly.Blocks["json_property_list"] = { this.setStyle("json_category"); this.setTooltip("Returns the keys, values, or entries of the object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_property_list"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - const mode = block.getFieldValue("MODE"); - - const safe = assure(generator, obj); - - let code; - if (mode === "KEYS") code = `Object.keys(${safe})`; - else if (mode === "VALUES") code = `Object.values(${safe})`; - else if (mode === "ENTRIES") code = `Object.entries(${safe})`; - else code = "[]"; - - return [code, BlocklyJS.Order.FUNCTION_CALL]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + const mode = block.getFieldValue("MODE"); + + const safe = assure(generator, obj); + + let code; + if (mode === "KEYS") code = `Object.keys(${safe})`; + else if (mode === "VALUES") code = `Object.values(${safe})`; + else if (mode === "ENTRIES") code = `Object.entries(${safe})`; + else code = "[]"; + + return [code, BlocklyJS.Order.FUNCTION_CALL]; + } +); Blockly.Blocks["json_parse"] = { init: function () { @@ -633,8 +608,9 @@ BlocklyJS.javascriptGenerator.forBlock["json_parse"] = function (block) { return [code, BlocklyJS.Order.NONE]; }; -Blockly.Blocks["json_clone"] = { - init: function () { +quickBlockMaker( + "json_clone", + function () { this.appendValueInput("OBJECT") .setCheck("Object") .appendField("clone object"); @@ -642,19 +618,15 @@ Blockly.Blocks["json_clone"] = { this.setStyle("json_category"); this.setTooltip("Creates a duplicate of an object."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["json_clone"] = function ( - block, - generator, -) { - const obj = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "OBJECT", - BlocklyJS.Order.NONE, - ) || "{}"; - - const safe = assure(generator, obj); - return [`JSON.parse(JSON.stringify(${safe}))`, BlocklyJS.Order.FUNCTION_CALL]; -}; + function (block, generator) { + const obj = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "OBJECT", + BlocklyJS.Order.NONE, + ) || "{}"; + + const safe = assure(generator, obj); + return [`JSON.parse(JSON.stringify(${safe}))`, BlocklyJS.Order.FUNCTION_CALL]; + } +); diff --git a/src/blocks/list.js b/src/blocks/list.js index 3a8c92a..e53bd16 100644 --- a/src/blocks/list.js +++ b/src/blocks/list.js @@ -1,9 +1,11 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; const xmlUtils = Blockly.utils.xml; -Blockly.Blocks["lists_has"] = { - init: function () { +quickBlockMaker( + "lists_has", + function () { this.appendValueInput("LIST").setCheck("Array").appendField("does list"); this.appendValueInput("VALUE").setCheck(null).appendField("have"); this.setOutput(true, "Boolean"); @@ -11,16 +13,13 @@ Blockly.Blocks["lists_has"] = { this.setStyle("list_blocks"); this.setTooltip("Returns true if the list contains the value."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_has"] = function ( - block, - generator -) { - const list = generator.valueToCode(block, "LIST", BlocklyJS.Order.ATOMIC) || "new Array()"; - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - return [`${list}.includes(${value})`, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const list = + generator.valueToCode(block, "LIST", BlocklyJS.Order.ATOMIC) || "new Array()"; + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); + return [`${list}.includes(${value})`, BlocklyJS.Order.NONE]; + } +); Blockly.Blocks["lists_extendable"] = { init: function () { @@ -126,8 +125,9 @@ BlocklyJS.javascriptGenerator.forBlock["lists_extendable"] = function (block, ge return [`[${parts.join(", ")}]`, BlocklyJS.Order.NONE]; }; -Blockly.Blocks["lists_filter"] = { - init: function () { +quickBlockMaker( + "lists_filter", + function () { this.appendValueInput("list").setCheck("Array").appendField("filter list"); this.appendValueInput("item").appendField("by"); this.appendValueInput("method").setCheck("Boolean").appendField("⇒"); @@ -138,24 +138,21 @@ Blockly.Blocks["lists_filter"] = { "Remove all items in a list which doesn't match the boolean" ); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_filter"] = function ( - block, - generator -) { - const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); - const method = generator.valueToCode( - block, - "method", - BlocklyJS.Order.ATOMIC - ); - const code = `${list}.filter(async (findOrFilterItem) => ${method})`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); + const method = generator.valueToCode( + block, + "method", + BlocklyJS.Order.ATOMIC + ); + const code = `${list}.filter(async (findOrFilterItem) => ${method})`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["lists_find"] = { - init: function () { +quickBlockMaker( + "lists_find", + function () { this.appendValueInput("list").setCheck("Array").appendField("in list"); this.appendValueInput("item").appendField("find first"); this.appendValueInput("method") @@ -168,24 +165,21 @@ Blockly.Blocks["lists_find"] = { "Returns the first item in a list that matches the boolean" ); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_find"] = function ( - block, - generator -) { - const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); - const method = generator.valueToCode( - block, - "method", - BlocklyJS.Order.ATOMIC - ); - const code = `${list}.find(findOrFilterItem => ${method})`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); + const method = generator.valueToCode( + block, + "method", + BlocklyJS.Order.ATOMIC + ); + const code = `${list}.find(findOrFilterItem => ${method})`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["lists_map"] = { - init: function () { +quickBlockMaker( + "lists_map", + function () { this.appendValueInput("list").setCheck("Array").appendField("map list"); this.appendValueInput("item").appendField("by"); this.appendValueInput("method").setCheck(null).appendField("⇒"); @@ -193,59 +187,50 @@ Blockly.Blocks["lists_map"] = { this.setInputsInline(true); this.setStyle("list_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_map"] = function ( - block, - generator -) { - const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); - const method = generator.valueToCode(block, "method", BlocklyJS.Order.ATOMIC); - const code = `${list}.map(findOrFilterItem => ${method})`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); + const method = generator.valueToCode(block, "method", BlocklyJS.Order.ATOMIC); + const code = `${list}.map(findOrFilterItem => ${method})`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["lists_filter_item"] = { - init: function () { +quickBlockMaker( + "lists_filter_item", + function () { this.appendDummyInput("name").appendField("item"); this.setInputsInline(true); this.setOutput(true, null); this.setDuplicateOnDrag(true); this.setStyle("list_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_filter_item"] = () => [ - "findOrFilterItem", - BlocklyJS.Order.NONE, -]; + () => ["findOrFilterItem", BlocklyJS.Order.NONE] +); -Blockly.Blocks["lists_merge"] = { - init: function () { +quickBlockMaker( + "lists_merge", + function () { this.appendValueInput("list").setCheck("Array").appendField("merge list"); this.appendValueInput("list2").setCheck("Array").appendField("with"); this.setInputsInline(true); this.setOutput(true, "Array"); this.setStyle("list_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_merge"] = function ( - block, - generator -) { - const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); - const list2 = generator.valueToCode( - block, - "list2", - BlocklyJS.Order.ATOMIC - ); - const code = `${list}.concat(${list2})`; - return [code, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const list = generator.valueToCode(block, "list", BlocklyJS.Order.ATOMIC); + const list2 = generator.valueToCode( + block, + "list2", + BlocklyJS.Order.ATOMIC + ); + const code = `${list}.concat(${list2})`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["lists_foreach"] = { - init: function () { +quickBlockMaker( + "lists_foreach", + function () { this.appendValueInput("ITEM").appendField("for each"); this.appendValueInput("INDEX"); this.appendValueInput("LIST") @@ -260,33 +245,26 @@ Blockly.Blocks["lists_foreach"] = { "Loops through every item in a list and runs the code inside for each one." ); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_foreach"] = function ( - block, - generator -) { - const list = - generator.valueToCode(block, "LIST", BlocklyJS.Order.NONE) || "[]"; - const branch = generator.statementToCode(block, "DO"); - const code = `${list}.forEach(async (findOrFilterItem, indexForEach) => {\n${branch}});\n`; - return code; -}; + function (block, generator) { + const list = + generator.valueToCode(block, "LIST", BlocklyJS.Order.NONE) || "[]"; + const branch = generator.statementToCode(block, "DO"); + const code = `${list}.forEach(async (findOrFilterItem, indexForEach) => {\n${branch}});\n`; + return code; + } +); -Blockly.Blocks["lists_foreach_index"] = { - init: function () { +quickBlockMaker( + "lists_foreach_index", + function () { this.appendDummyInput("name").appendField("index"); this.setInputsInline(true); this.setOutput(true, "Number"); this.setDuplicateOnDrag(true); this.setStyle("list_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["lists_foreach_index"] = () => [ - "indexForEach", - BlocklyJS.Order.NONE, -]; + () => ["indexForEach", BlocklyJS.Order.NONE] +); Blockly.Blocks["lists_getIndex_modified"] = { init: function () { diff --git a/src/blocks/logic.js b/src/blocks/logic.js index 6ec16e8..6fa0f84 100644 --- a/src/blocks/logic.js +++ b/src/blocks/logic.js @@ -1,8 +1,10 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["logic_operation_extra"] = { - init: function () { +quickBlockMaker( + "logic_operation_extra", + function () { this.appendValueInput("A").setCheck("Boolean"); this.appendValueInput("B") .setCheck("Boolean") @@ -21,40 +23,36 @@ Blockly.Blocks["logic_operation_extra"] = { this.setOutput(true, "Boolean"); this.setStyle("text_blocks"); }, -}; + function (block, generator) { + const A = generator.valueToCode(block, "A", BlocklyJS.Order.LOGICAL_AND) || "false"; + const B = generator.valueToCode(block, "B", BlocklyJS.Order.LOGICAL_AND) || "false"; + const OP = block.getFieldValue("OP"); -BlocklyJS.javascriptGenerator.forBlock["logic_operation_extra"] = function ( - block, - generator, -) { - const A = generator.valueToCode(block, "A", BlocklyJS.Order.LOGICAL_AND) || "false"; - const B = generator.valueToCode(block, "B", BlocklyJS.Order.LOGICAL_AND) || "false"; - const OP = block.getFieldValue("OP"); + let code; - let code; + switch (OP) { + case "and": + code = `${A} && ${B}`; + break; + case "or": + code = `${A} || ${B}`; + break; + case "xor": + code = `(${A} !== ${B})`; + break; + case "nand": + code = `!(${A} && ${B})`; + break; + case "nor": + code = `!(${A} || ${B})`; + break; + case "xnor": + code = `(${A} === ${B})`; + break; + default: + code = "false"; + } - switch (OP) { - case "and": - code = `${A} && ${B}`; - break; - case "or": - code = `${A} || ${B}`; - break; - case "xor": - code = `(${A} !== ${B})`; - break; - case "nand": - code = `!(${A} && ${B})`; - break; - case "nor": - code = `!(${A} || ${B})`; - break; - case "xnor": - code = `(${A} === ${B})`; - break; - default: - code = "false"; - } - - return [code, BlocklyJS.Order.LOGICAL_OR]; -}; + return [code, BlocklyJS.Order.LOGICAL_OR]; + }, +); diff --git a/src/blocks/looks.js b/src/blocks/looks.js index a904ef1..63d39ba 100644 --- a/src/blocks/looks.js +++ b/src/blocks/looks.js @@ -1,19 +1,28 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; import { activeSprite } from "../scripts/editor"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["say_message"] = { - init: function () { +quickBlockMaker( + "say_message", + function () { this.appendValueInput("MESSAGE").appendField("say"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setInputsInline(true); this.setStyle("looks_blocks"); }, -}; + function (block, generator) { + const message = + generator.valueToCode(block, "MESSAGE", BlocklyJS.Order.NONE) || ""; -Blockly.Blocks["say_message_duration"] = { - init: function () { + return `sayMessage(${message});\nyield;\n`; + } +); + +quickBlockMaker( + "say_message_duration", + function () { this.appendValueInput("MESSAGE").appendField("say"); this.appendValueInput("DURATION").setCheck("Number").appendField("for"); this.appendDummyInput().appendField("seconds"); @@ -22,10 +31,19 @@ Blockly.Blocks["say_message_duration"] = { this.setInputsInline(true); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["switch_costume"] = { - init: function () { + function (block, generator) { + const message = + generator.valueToCode(block, "MESSAGE", BlocklyJS.Order.NONE) || ""; + const duration = + generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || 2; + + return `sayMessage(${message}, ${duration});\nyield;\n`; + } +); + +quickBlockMaker( + "switch_costume", + function () { this.appendValueInput("COSTUME") .setCheck("String") .appendField("switch costume to"); @@ -33,10 +51,15 @@ Blockly.Blocks["switch_costume"] = { this.setNextStatement(true); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["set_size"] = { - init: function () { + function (block, generator) { + const costume = generator.valueToCode(block, "COSTUME", BlocklyJS.Order.ATOMIC); + return `switchCostume(${costume});\nyield;\n`; + } +); + +quickBlockMaker( + "set_size", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("set size to"); @@ -45,10 +68,16 @@ Blockly.Blocks["set_size"] = { this.setNextStatement(true); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["change_size"] = { - init: function () { + function (block, generator) { + const amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 100; + return `setSize(${amount}, false);\nyield;\n`; + } +); + +quickBlockMaker( + "change_size", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("change size by"); @@ -57,10 +86,16 @@ Blockly.Blocks["change_size"] = { this.setNextStatement(true); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["get_costume_size"] = { - init: function () { + function (block, generator) { + const amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 100; + return `setSize(${amount}, true);\nyield;\n`; + } +); + +quickBlockMaker( + "get_costume_size", + function () { this.appendDummyInput() .appendField("costume") .appendField( @@ -73,133 +108,79 @@ Blockly.Blocks["get_costume_size"] = { this.setOutput(true, "Number"); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["get_sprite_scale"] = { - init: function () { + function (block) { + const menu = block.getFieldValue("MENU"); + return [`getCostumeSize("${menu}")`, BlocklyJS.Order.NONE]; + } +); + +quickBlockMaker( + "get_sprite_scale", + function () { this.appendDummyInput().appendField("size"); this.setOutput(true, "Number"); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["looks_hide_sprite"] = { - init: function () { + function () { + return [`getSpriteScale()`, BlocklyJS.Order.NONE]; + } +); + +quickBlockMaker( + "looks_hide_sprite", + function () { this.appendDummyInput().appendField("hide sprite"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["looks_show_sprite"] = { - init: function () { + function () { + return "toggleVisibility(false);\nyield;\n"; + } +); + +quickBlockMaker( + "looks_show_sprite", + function () { this.appendDummyInput().appendField("show sprite"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("looks_blocks"); }, -}; - -Blockly.Blocks["looks_setVisibility_sprite"] = { - init: function () { + function () { + return "toggleVisibility(true);\nyield;\n"; + } +); + +quickBlockMaker( + "looks_setVisibility_sprite", + function () { this.appendValueInput("VISIBLE").setCheck("Boolean").appendField("set visibility to"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("looks_blocks"); }, -}; + function (block, generator) { + const visible = + generator.valueToCode(block, "VISIBLE", BlocklyJS.Order.ATOMIC) ?? "false"; + + return `toggleVisibility(${visible});\nyield;\n`; + } +); -Blockly.Blocks["looks_isVisible"] = { - init: function () { +quickBlockMaker( + "looks_isVisible", + function () { this.appendDummyInput().appendField("is visible"); this.setOutput(true, "Boolean"); this.setStyle("looks_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["say_message"] = function ( - block, - generator -) { - const message = - generator.valueToCode(block, "MESSAGE", BlocklyJS.Order.NONE) || ""; - - return `sayMessage(${message});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["say_message_duration"] = function ( - block, - generator -) { - const message = - generator.valueToCode(block, "MESSAGE", BlocklyJS.Order.NONE) || ""; - const duration = - generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || 2; + () => ["getTarget().visible", BlocklyJS.Order.NONE] +); - return `sayMessage(${message}, ${duration});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["switch_costume"] = function ( - block, - generator -) { - var costume = generator.valueToCode(block, "COSTUME", BlocklyJS.Order.ATOMIC); - return `switchCostume(${costume});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["set_size"] = function ( - block, - generator -) { - const amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 100; - return `setSize(${amount}, false);\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["change_size"] = function ( - block, - generator -) { - const amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 100; - return `setSize(${amount}, true);\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["get_costume_size"] = function (block) { - const menu = block.getFieldValue("MENU"); - return [`getCostumeSize("${menu}")`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["get_sprite_scale"] = function () { - return [`getSpriteScale()`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["looks_hide_sprite"] = function () { - return "toggleVisibility(false);\nyield;\n"; -}; - -BlocklyJS.javascriptGenerator.forBlock["looks_show_sprite"] = function () { - return "toggleVisibility(true);\nyield;\n"; -}; - -BlocklyJS.javascriptGenerator.forBlock["looks_setVisibility_sprite"] = function ( - block, - generator -) { - const visible = - generator.valueToCode(block, "VISIBLE", BlocklyJS.Order.ATOMIC) ?? "false"; - - return `toggleVisibility(${visible});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["looks_isVisible"] = () => [ - "getTarget().visible", - BlocklyJS.Order.NONE, -]; - -Blockly.Blocks["looks_costumes_menu"] = { - init: function () { +quickBlockMaker( + "looks_costumes_menu", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown(() => { const costumes = activeSprite.costumes; @@ -212,11 +193,7 @@ Blockly.Blocks["looks_costumes_menu"] = { this.setOutput(true, "String"); this.setStyle("looks_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["looks_costumes_menu"] = function ( - block, - generator, -) { - return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; -}; \ No newline at end of file + function (block, generator) { + return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; + } +); diff --git a/src/blocks/motion.js b/src/blocks/motion.js index e6eb34c..651ed6e 100644 --- a/src/blocks/motion.js +++ b/src/blocks/motion.js @@ -1,18 +1,26 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["move_steps"] = { - init: function () { +quickBlockMaker( + "move_steps", + function () { this.appendValueInput("STEPS").setCheck("Number").appendField("step"); this.appendDummyInput().appendField("times"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["change_position"] = { - init: function () { + function (block, generator) { + const steps = + generator.valueToCode(block, "STEPS", BlocklyJS.Order.ATOMIC) || 0; + return `moveSteps(${steps});\nyield;\n`; + } +); + +quickBlockMaker( + "change_position", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("change") @@ -28,10 +36,19 @@ Blockly.Blocks["change_position"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["set_position"] = { - init: function () { + function (block, generator) { + const amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; + const menu = block.getFieldValue("MENU"); + if (menu === "x") return `getTarget().${menu} += ${amount};\nyield;\n`; + if (menu === "y") return `getTarget().${menu} -= ${amount};\nyield;\n`; + return ""; + } +); + +quickBlockMaker( + "set_position", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("set") @@ -47,10 +64,18 @@ Blockly.Blocks["set_position"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["goto_position"] = { - init: function () { + function (block, generator) { + const amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; + const menu = block.getFieldValue("MENU"); + if (menu === "y") return `getTarget().${menu} = -${amount};\n`; + return `getTarget().${menu} = ${amount};\nyield;\n`; + } +); + +quickBlockMaker( + "goto_position", + function () { this.appendValueInput("x").setCheck("Number").appendField("go to x"); this.appendValueInput("y").setCheck("Number").appendField("y"); this.setInputsInline(true); @@ -58,10 +83,16 @@ Blockly.Blocks["goto_position"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["get_position"] = { - init: function () { + function (block, generator) { + const x = generator.valueToCode(block, "x", BlocklyJS.Order.ATOMIC) || 0; + const y = generator.valueToCode(block, "y", BlocklyJS.Order.ATOMIC) || 0; + return `getTarget().x = ${x};\ngetTarget().y = -${y};\nyield;\n`; + } +); + +quickBlockMaker( + "get_position", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown([ ["x", "x"], @@ -72,10 +103,15 @@ Blockly.Blocks["get_position"] = { this.setOutput(true, "Number"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["angle_turn"] = { - init: function () { + function (block) { + const menu = block.getFieldValue("MENU"); + return [`getTarget()["${menu}"]`, BlocklyJS.Order.NONE]; + } +); + +quickBlockMaker( + "angle_turn", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("turn") @@ -107,10 +143,18 @@ Blockly.Blocks["angle_turn"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["angle_set"] = { - init: function () { + function (block, generator) { + const direction = block.getFieldValue("DIRECTION"); + let amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; + if (direction === "left") amount = `-(${amount})`; + return `setAngle(${amount}, true);\nyield;\n`; + } +); + +quickBlockMaker( + "angle_set", + function () { this.appendValueInput("AMOUNT") .setCheck("Number") .appendField("set angle to"); @@ -120,10 +164,16 @@ Blockly.Blocks["angle_set"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["point_towards"] = { - init: function () { + function (block, generator) { + const amount = + generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; + return `setAngle(${amount}, false);\nyield;\n`; + } +); + +quickBlockMaker( + "point_towards", + function () { this.appendValueInput("x") .setCheck("Number") .appendField("point towards x"); @@ -133,91 +183,19 @@ Blockly.Blocks["point_towards"] = { this.setNextStatement(true, "default"); this.setStyle("motion_blocks"); }, -}; - -Blockly.Blocks["get_angle"] = { - init: function () { + function (block, generator) { + const x = generator.valueToCode(block, "x", BlocklyJS.Order.ATOMIC) || 0; + const y = generator.valueToCode(block, "y", BlocklyJS.Order.ATOMIC) || 0; + return `pointsTowards(${x}, ${y});\nyield;\n`; + } +); + +quickBlockMaker( + "get_angle", + function () { this.appendDummyInput().appendField("angle"); this.setOutput(true, "Number"); this.setStyle("motion_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["move_steps"] = function ( - block, - generator -) { - const steps = - generator.valueToCode(block, "STEPS", BlocklyJS.Order.ATOMIC) || 0; - return `moveSteps(${steps});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["change_position"] = function ( - block, - generator -) { - const amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; - const menu = block.getFieldValue("MENU"); - if (menu === "x") return `getTarget().${menu} += ${amount};\nyield;\n`; - else if (menu === "y") return `getTarget().${menu} -= ${amount};\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["set_position"] = function ( - block, - generator -) { - const amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; - const menu = block.getFieldValue("MENU"); - if (menu === "y") return `getTarget().${menu} = -${amount};\n`; - else return `getTarget().${menu} = ${amount};\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["goto_position"] = function ( - block, - generator -) { - const x = generator.valueToCode(block, "x", BlocklyJS.Order.ATOMIC) || 0; - const y = generator.valueToCode(block, "y", BlocklyJS.Order.ATOMIC) || 0; - return `getTarget().x = ${x};\ngetTarget().y = -${y};\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["point_towards"] = function ( - block, - generator -) { - const x = generator.valueToCode(block, "x", BlocklyJS.Order.ATOMIC) || 0; - const y = generator.valueToCode(block, "y", BlocklyJS.Order.ATOMIC) || 0; - return `pointsTowards(${x}, ${y});\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["get_position"] = function (block) { - const menu = block.getFieldValue("MENU"); - return [`getTarget()["${menu}"]`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["angle_turn"] = function ( - block, - generator -) { - const direction = block.getFieldValue("DIRECTION"); - let amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; - if (direction === "left") amount = `-(${amount})`; - return `setAngle(${amount}, true);\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["angle_set"] = function ( - block, - generator -) { - const amount = - generator.valueToCode(block, "AMOUNT", BlocklyJS.Order.ATOMIC) || 0; - return `setAngle(${amount}, false);\nyield;\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["get_angle"] = () => [ - "getTarget().angle", - BlocklyJS.Order.NONE, -]; + () => ["getTarget().angle", BlocklyJS.Order.NONE] +); diff --git a/src/blocks/pen.js b/src/blocks/pen.js index c185cb1..48a12ad 100644 --- a/src/blocks/pen.js +++ b/src/blocks/pen.js @@ -1,34 +1,38 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["pen_down"] = { - init: function () { +quickBlockMaker( + "pen_down", + function () { this.appendDummyInput().appendField("pen down"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setColour("#0fbd8c"); this.setTooltip("Put the pen down to draw"); }, -}; -BlocklyJS.javascriptGenerator.forBlock["pen_down"] = function () { - return "setPenStatus(true);\n"; -}; + function () { + return "setPenStatus(true);\n"; + } +); -Blockly.Blocks["pen_up"] = { - init: function () { +quickBlockMaker( + "pen_up", + function () { this.appendDummyInput().appendField("pen up"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setColour("#0fbd8c"); this.setTooltip("Lift the pen up"); }, -}; -BlocklyJS.javascriptGenerator.forBlock["pen_up"] = function () { - return "setPenStatus(false);\n"; -}; + function () { + return "setPenStatus(false);\n"; + } +); -Blockly.Blocks["set_pen_color"] = { - init: function () { +quickBlockMaker( + "set_pen_color", + function () { this.appendDummyInput().appendField("set pen color"); this.appendValueInput("R").setCheck("Number").appendField("R"); this.appendValueInput("G").setCheck("Number").appendField("G"); @@ -39,19 +43,17 @@ Blockly.Blocks["set_pen_color"] = { this.setColour("#0fbd8c"); this.setTooltip("Set the pen color to a RGB value"); }, -}; -BlocklyJS.javascriptGenerator.forBlock["set_pen_color"] = function ( - block, - generator -) { - const r = generator.valueToCode(block, "R", BlocklyJS.Order.ATOMIC) || 0; - const g = generator.valueToCode(block, "G", BlocklyJS.Order.ATOMIC) || 0; - const b = generator.valueToCode(block, "B", BlocklyJS.Order.ATOMIC) || 0; - return `setPenColor(${r}, ${g}, ${b});\n`; -}; + function (block, generator) { + const r = generator.valueToCode(block, "R", BlocklyJS.Order.ATOMIC) || 0; + const g = generator.valueToCode(block, "G", BlocklyJS.Order.ATOMIC) || 0; + const b = generator.valueToCode(block, "B", BlocklyJS.Order.ATOMIC) || 0; + return `setPenColor(${r}, ${g}, ${b});\n`; + } +); -Blockly.Blocks["set_pen_color_combined"] = { - init: function () { +quickBlockMaker( + "set_pen_color_combined", + function () { this.appendDummyInput("MODE") .appendField("set pen color to") .appendField( @@ -68,20 +70,17 @@ Blockly.Blocks["set_pen_color_combined"] = { this.setColour("#0fbd8c"); this.setTooltip("Set the pen color to a RGB or HEX value."); }, -}; + function (block, generator) { + const mode = block.getFieldValue("MODE"); + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); + if (mode === "HEX") return `setPenColorHex(${value});\n`; + return `setPenColor(${value});\n`; + } +); -BlocklyJS.javascriptGenerator.forBlock["set_pen_color_combined"] = function ( - block, - generator -) { - const mode = block.getFieldValue("MODE"); - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - if (mode === "HEX") return `setPenColorHex(${value});\n`; - else return `setPenColor(${value});\n`; -}; - -Blockly.Blocks["set_pen_size"] = { - init: function () { +quickBlockMaker( + "set_pen_size", + function () { this.appendValueInput("SIZE") .setCheck("Number") .appendField("set pen size to"); @@ -91,25 +90,23 @@ Blockly.Blocks["set_pen_size"] = { this.setColour("#0fbd8c"); this.setTooltip("Set the pen thickness to a specific value in pixels"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["set_pen_size"] = function ( - block, - generator -) { - const size = - generator.valueToCode(block, "SIZE", BlocklyJS.Order.ATOMIC) || 1; - return `setPenSize("${size}");\n`; -}; + function (block, generator) { + const size = + generator.valueToCode(block, "SIZE", BlocklyJS.Order.ATOMIC) || 1; + return `setPenSize("${size}");\n`; + } +); -Blockly.Blocks["clear_pen"] = { - init: function () { +quickBlockMaker( + "clear_pen", + function () { this.appendDummyInput().appendField("clear pen"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); this.setColour("#0fbd8c"); this.setTooltip("Clear all pen drawings"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["clear_pen"] = () => "clearPen();\n"; + function() { + return "clearPen();\n"; + } +); diff --git a/src/blocks/quickblockmaker.js b/src/blocks/quickblockmaker.js new file mode 100644 index 0000000..8ec80d1 --- /dev/null +++ b/src/blocks/quickblockmaker.js @@ -0,0 +1,8 @@ +import * as Blockly from "blockly"; +import * as BlocklyJS from "blockly/javascript"; + +// this is genuinely just a helper to make block definitions cleaner +export function quickBlockMaker(id, init, code) { + Blockly.Blocks[id] = { init }; + BlocklyJS.javascriptGenerator.forBlock[id] = code; +} diff --git a/src/blocks/set.js b/src/blocks/set.js index 625aeeb..8201057 100644 --- a/src/blocks/set.js +++ b/src/blocks/set.js @@ -1,5 +1,6 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; const xmlUtils = Blockly.utils.xml; Blockly.Blocks["sets_create_extendable"] = { @@ -357,8 +358,9 @@ BlocklyJS.javascriptGenerator.forBlock["sets_convert"] = function (block) { }; /* --- start deprecated --- */ -Blockly.Blocks["sets_add"] = { - init: function () { +quickBlockMaker( + "sets_add", + function () { this.appendValueInput("SET").setCheck("Set").appendField("in set"); this.appendValueInput("VALUE").setCheck(null).appendField("add"); this.setPreviousStatement(true, null); @@ -367,19 +369,16 @@ Blockly.Blocks["sets_add"] = { this.setStyle("set_blocks"); this.setTooltip("Adds a value to the set."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_add"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC); - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - return `${set}.add(${value});\n`; -}; + function (block, generator) { + const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC); + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); + return `${set}.add(${value});\n`; + } +); -Blockly.Blocks["sets_delete"] = { - init: function () { +quickBlockMaker( + "sets_delete", + function () { this.appendValueInput("SET").setCheck("Set").appendField("in set"); this.appendValueInput("VALUE").setCheck(null).appendField("delete"); this.setPreviousStatement(true, null); @@ -388,20 +387,17 @@ Blockly.Blocks["sets_delete"] = { this.setStyle("set_blocks"); this.setTooltip("Deletes a value from the set."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_delete"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC); - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - return `${set}.delete(${value});\n`; -}; + function (block, generator) { + const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC); + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); + return `${set}.delete(${value});\n`; + } +); /* --- end deprecated --- */ -Blockly.Blocks["sets_add_return"] = { - init: function () { +quickBlockMaker( + "sets_add_return", + function () { this.appendValueInput("SET").setCheck("Set").appendField("in set"); this.appendValueInput("VALUE").setCheck(null).appendField("add"); this.setOutput(true, "Set"); @@ -409,21 +405,19 @@ Blockly.Blocks["sets_add_return"] = { this.setStyle("set_blocks"); this.setTooltip("Adds a value to the set."); }, -}; + function (block, generator) { + const set = + generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); -BlocklyJS.javascriptGenerator.forBlock["sets_add_return"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - - const code = `(() => { const _ = ${set}; _.add(${value}); return _; })()`; - return [code, BlocklyJS.Order.NONE]; -}; + const code = `(() => { const _ = ${set}; _.add(${value}); return _; })()`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["sets_delete_return"] = { - init: function () { +quickBlockMaker( + "sets_delete_return", + function () { this.appendValueInput("SET").setCheck("Set").appendField("in set"); this.appendValueInput("VALUE").setCheck(null).appendField("delete"); this.setOutput(true, "Set"); @@ -431,21 +425,19 @@ Blockly.Blocks["sets_delete_return"] = { this.setStyle("set_blocks"); this.setTooltip("Deletes a value from the set."); }, -}; + function (block, generator) { + const set = + generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); -BlocklyJS.javascriptGenerator.forBlock["sets_delete_return"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - - const code = `(() => { const _ = ${set}; _.delete(${value}); return _; })()`; - return [code, BlocklyJS.Order.NONE]; -}; + const code = `(() => { const _ = ${set}; _.delete(${value}); return _; })()`; + return [code, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["sets_has"] = { - init: function () { +quickBlockMaker( + "sets_has", + function () { this.appendValueInput("SET").setCheck("Set").appendField("does set"); this.appendValueInput("VALUE").setCheck(null).appendField("have"); this.setOutput(true, "Boolean"); @@ -453,37 +445,33 @@ Blockly.Blocks["sets_has"] = { this.setStyle("set_blocks"); this.setTooltip("Returns true if the set contains the value."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_has"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; - const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); - return [`${set}.has(${value})`, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const set = + generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; + const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC); + return [`${set}.has(${value})`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["sets_size"] = { - init: function () { +quickBlockMaker( + "sets_size", + function () { this.appendValueInput("SET").setCheck("Set").appendField("length of set"); this.setOutput(true, "Number"); this.setInputsInline(true); this.setStyle("set_blocks"); this.setTooltip("Returns the length of a set."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_size"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; - return [`${set}.size`, BlocklyJS.Order.MEMBER]; -}; + function (block, generator) { + const set = + generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; + return [`${set}.size`, BlocklyJS.Order.MEMBER]; + } +); -Blockly.Blocks["sets_isEmpty"] = { - init: function () { +quickBlockMaker( + "sets_isEmpty", + function () { this.appendValueInput("SET").setCheck("Set"); this.appendDummyInput().appendField("is empty"); this.setOutput(true, "Boolean"); @@ -491,18 +479,16 @@ Blockly.Blocks["sets_isEmpty"] = { this.setStyle("set_blocks"); this.setTooltip("Returns true if the set is empty."); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_isEmpty"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; - return [`${set}.size === 0`, BlocklyJS.Order.EQUALITY]; -}; + function (block, generator) { + const set = + generator.valueToCode(block, "SET", BlocklyJS.Order.ATOMIC) || "new Set()"; + return [`${set}.size === 0`, BlocklyJS.Order.EQUALITY]; + } +); -Blockly.Blocks["sets_merge"] = { - init: function () { +quickBlockMaker( + "sets_merge", + function () { this.appendValueInput("SET1").setCheck("Set").appendField("merge set"); this.appendValueInput("SET2").setCheck("Set").appendField("with"); this.setOutput(true, "Set"); @@ -510,19 +496,18 @@ Blockly.Blocks["sets_merge"] = { this.setStyle("set_blocks"); this.setTooltip("Creates a new set combining all values from two sets"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_merge"] = function ( - block, - generator -) { - const set1 = generator.valueToCode(block, "SET1", BlocklyJS.Order.ATOMIC) || "new Set()"; - const set2 = generator.valueToCode(block, "SET2", BlocklyJS.Order.ATOMIC) || "new Set()"; - return [`new Set([...${set1}, ...${set2}])`, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const set1 = + generator.valueToCode(block, "SET1", BlocklyJS.Order.ATOMIC) || "new Set()"; + const set2 = + generator.valueToCode(block, "SET2", BlocklyJS.Order.ATOMIC) || "new Set()"; + return [`new Set([...${set1}, ...${set2}])`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["sets_foreach"] = { - init: function () { +quickBlockMaker( + "sets_foreach", + function () { this.appendValueInput("ITEM").appendField("for each"); this.appendValueInput("SET") .setCheck("Set") @@ -536,29 +521,22 @@ Blockly.Blocks["sets_foreach"] = { "Loops through every item in a set and runs the code inside for each one." ); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_foreach"] = function ( - block, - generator -) { - const set = generator.valueToCode(block, "SET", BlocklyJS.Order.NONE) || "[]"; - const branch = generator.statementToCode(block, "DO"); - const code = `${set}.forEach(function* (setsForEachItem) => {\n${branch}});\n`; - return code; -}; + function (block, generator) { + const set = generator.valueToCode(block, "SET", BlocklyJS.Order.NONE) || "[]"; + const branch = generator.statementToCode(block, "DO"); + const code = `${set}.forEach(function* (setsForEachItem) => {\n${branch}});\n`; + return code; + } +); -Blockly.Blocks["sets_foreach_item"] = { - init: function () { +quickBlockMaker( + "sets_foreach_item", + function () { this.appendDummyInput("name").appendField("item"); this.setInputsInline(true); this.setOutput(true, "Number"); this.setDuplicateOnDrag(true); this.setStyle("set_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["sets_foreach_item"] = () => [ - "setsForEachItem", - BlocklyJS.Order.NONE, -]; \ No newline at end of file + () => ["setsForEachItem", BlocklyJS.Order.NONE] +); diff --git a/src/blocks/sound.js b/src/blocks/sound.js index 5df1dc2..e093543 100644 --- a/src/blocks/sound.js +++ b/src/blocks/sound.js @@ -1,9 +1,11 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; import { activeSprite } from "../scripts/editor"; +import { quickBlockMaker } from "./quickblockmaker"; -Blockly.Blocks["sound_sounds_menu"] = { - init: function () { +quickBlockMaker( + "sound_sounds_menu", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown(() => { const sounds = activeSprite.sounds; @@ -16,17 +18,14 @@ Blockly.Blocks["sound_sounds_menu"] = { this.setOutput(true, "String"); this.setStyle("sound_blocks"); }, -}; + function (block, generator) { + return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; + } +); -BlocklyJS.javascriptGenerator.forBlock["sound_sounds_menu"] = function ( - block, - generator, -) { - return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; -}; - -Blockly.Blocks["play_sound"] = { - init: function () { +quickBlockMaker( + "play_sound", + function () { this.appendValueInput("name").setCheck("String").appendField("play sound"); this.appendDummyInput().appendField( new Blockly.FieldDropdown([ @@ -39,38 +38,30 @@ Blockly.Blocks["play_sound"] = { this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["play_sound"] = function (block, generator) { - var name = generator.valueToCode( - block, - "name", - BlocklyJS.Order.ATOMIC - ); - var wait = block.getFieldValue("wait"); - return `yield* playSound(${name}, ${wait});\n`; -}; + function (block, generator) { + const name = generator.valueToCode(block, "name", BlocklyJS.Order.ATOMIC); + const wait = block.getFieldValue("wait"); + return `yield* playSound(${name}, ${wait});\n`; + } +); -Blockly.Blocks["stop_sound"] = { - init: function () { +quickBlockMaker( + "stop_sound", + function () { this.appendValueInput("name").setCheck("String").appendField("stop sound"); this.setStyle("sound_blocks"); this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["stop_sound"] = function (block, generator) { - var name = generator.valueToCode( - block, - "name", - BlocklyJS.Order.ATOMIC - ); - return `stopSound(${name});\n`; -}; + function (block, generator) { + const name = generator.valueToCode(block, "name", BlocklyJS.Order.ATOMIC); + return `stopSound(${name});\n`; + } +); -Blockly.Blocks["stop_all_sounds"] = { - init: function () { +quickBlockMaker( + "stop_all_sounds", + function () { this.appendDummyInput() .appendField("stop") .appendField( @@ -85,16 +76,15 @@ Blockly.Blocks["stop_all_sounds"] = { this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); }, -}; + function (block) { + const who = block.getFieldValue("who"); + return `stopAllSounds(${who});\n`; + } +); -BlocklyJS.javascriptGenerator.forBlock["stop_all_sounds"] = function (block) { - var who = block.getFieldValue("who"); - var code = `stopAllSounds(${who});\n`; - return code; -}; - -Blockly.Blocks["set_sound_property"] = { - init: function () { +quickBlockMaker( + "set_sound_property", + function () { this.appendValueInput("value") .setCheck("Number") .appendField("set") @@ -111,23 +101,16 @@ Blockly.Blocks["set_sound_property"] = { this.setPreviousStatement(true, "default"); this.setNextStatement(true, "default"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["set_sound_property"] = function ( - block, - generator -) { - var value = generator.valueToCode( - block, - "value", - BlocklyJS.Order.ATOMIC - ); - var property = block.getFieldValue("property"); - return `setSoundProperty("${property}", ${value});\n`; -}; + function (block, generator) { + const value = generator.valueToCode(block, "value", BlocklyJS.Order.ATOMIC); + const property = block.getFieldValue("property"); + return `setSoundProperty("${property}", ${value});\n`; + } +); -Blockly.Blocks["get_sound_property"] = { - init: function () { +quickBlockMaker( + "get_sound_property", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown([ ["volume", "volume"], @@ -138,9 +121,8 @@ Blockly.Blocks["get_sound_property"] = { this.setStyle("sound_blocks"); this.setOutput(true, "Number"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["get_sound_property"] = function (block) { - var property = block.getFieldValue("property"); - return [`soundProperties["${property}"]`, BlocklyJS.Order.NONE]; -}; + function (block) { + const property = block.getFieldValue("property"); + return [`soundProperties["${property}"]`, BlocklyJS.Order.NONE]; + } +); diff --git a/src/blocks/system.js b/src/blocks/system.js index 6eb6126..b69d43f 100644 --- a/src/blocks/system.js +++ b/src/blocks/system.js @@ -1,14 +1,16 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; import { spriteManager } from "../scripts/editor"; +import { quickBlockMaker } from "./quickblockmaker"; const normalKeys = [ ..."abcdefghijklmnopqrstuvwxyz", ..."abcdefghijklmnopqrstuvwxyz0123456789".toUpperCase(), ]; -Blockly.Blocks["system_sprites_menu"] = { - init: function () { +quickBlockMaker( + "system_sprites_menu", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown(() => { const sprites = spriteManager.getOriginals(); @@ -21,17 +23,14 @@ Blockly.Blocks["system_sprites_menu"] = { this.setOutput(true, "String"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["system_sprites_menu"] = function ( - block, - generator, -) { - return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; -}; + function (block, generator) { + return [generator.quote_(block.getFieldValue("MENU")), BlocklyJS.Order.ATOMIC]; + } +); -Blockly.Blocks["key_pressed"] = { - init: function () { +quickBlockMaker( + "key_pressed", + function () { this.appendDummyInput() .appendField("is") .appendField( @@ -52,10 +51,16 @@ Blockly.Blocks["key_pressed"] = { this.setOutput(true, "Boolean"); this.setStyle("system_blocks"); }, -}; + function (block, generator) { + const key = block.getFieldValue("KEY"); + const safeKey = generator.quote_(key); + return [`isKeyPressed(${safeKey})`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["get_mouse_position"] = { - init: function () { +quickBlockMaker( + "get_mouse_position", + function () { this.appendDummyInput() .appendField("mouse") .appendField( @@ -68,10 +73,15 @@ Blockly.Blocks["get_mouse_position"] = { this.setOutput(true, "Number"); this.setStyle("system_blocks"); }, -}; + function (block) { + const menu = block.getFieldValue("MENU"); + return [`getMousePosition("${menu}")`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["mouse_button_pressed"] = { - init: function () { +quickBlockMaker( + "mouse_button_pressed", + function () { this.appendDummyInput() .appendField("is") .appendField( @@ -89,56 +99,42 @@ Blockly.Blocks["mouse_button_pressed"] = { this.setOutput(true, "Boolean"); this.setStyle("system_blocks"); }, -}; + function (block, generator) { + const button = block.getFieldValue("BUTTON"); + const safeButton = generator.quote_(button); + return [`isMouseButtonPressed(${safeButton})`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["all_keys_pressed"] = { - init: function () { +quickBlockMaker( + "all_keys_pressed", + function () { this.appendDummyInput().appendField("keys currently down"); this.setOutput(true, "Array"); this.setStyle("system_blocks"); }, -}; + () => [ + "Object.keys(keysPressed).filter(k => keysPressed[k])", + BlocklyJS.Order.NONE, + ] +); -Blockly.Blocks["mouse_over"] = { - init: function () { +quickBlockMaker( + "mouse_over", + function () { this.appendDummyInput().appendField("is cursor over me"); this.setOutput(true, "Boolean"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["key_pressed"] = function (block, generator) { - const key = block.getFieldValue("KEY"); - const safeKey = generator.quote_(key); - return [`isKeyPressed(${safeKey})`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["get_mouse_position"] = function (block) { - const menu = block.getFieldValue("MENU"); - return [`getMousePosition("${menu}")`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["mouse_button_pressed"] = function ( - block, - generator, -) { - const button = block.getFieldValue("BUTTON"); - const safeButton = generator.quote_(button); - return [`isMouseButtonPressed(${safeButton})`, BlocklyJS.Order.NONE]; -}; - -BlocklyJS.javascriptGenerator.forBlock["all_keys_pressed"] = () => [ - "Object.keys(keysPressed).filter(k => keysPressed[k])", - BlocklyJS.Order.NONE, -]; - -BlocklyJS.javascriptGenerator.forBlock["mouse_over"] = () => [ - "isMouseTouchingSprite()", - BlocklyJS.Order.NONE, -]; + () => [ + "isMouseTouchingSprite()", + BlocklyJS.Order.NONE, + ] +); -Blockly.Blocks["window_size"] = { - init: function () { +quickBlockMaker( + "window_size", + function () { this.appendDummyInput() .appendField("window") .appendField( @@ -151,17 +147,17 @@ Blockly.Blocks["window_size"] = { this.setOutput(true, "Number"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["window_size"] = function (block) { - return [ - `window.inner${block.getFieldValue("MENU") === "width" ? "Width" : "Height"}`, - BlocklyJS.Order.NONE, - ]; -}; + function (block) { + return [ + `window.inner${block.getFieldValue("MENU") === "width" ? "Width" : "Height"}`, + BlocklyJS.Order.NONE, + ]; + } +); -Blockly.Blocks["system_current_time"] = { - init: function () { +quickBlockMaker( + "system_current_time", + function () { this.appendDummyInput() .appendField("current") .appendField( @@ -181,39 +177,39 @@ Blockly.Blocks["system_current_time"] = { this.setOutput(true, "Number"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["system_current_time"] = function (block) { - const getResult = () => { - const unit = block.getFieldValue("UNIT"); - switch (unit) { - case "year": - return "new Date().getFullYear()"; - case "month": - return "new Date().getMonth() + 1"; - case "date": - return "new Date().getDate()"; - case "day": - return "new Date().getDay()"; - case "hour": - return "new Date().getHours()"; - case "minute": - return "new Date().getMinutes()"; - case "second": - return "new Date().getSeconds()"; - case "millisecond": - return "new Date().getMilliseconds()"; - case "timestamp": - return "Date.now()"; - default: - return "0"; - } - }; - return [getResult(), BlocklyJS.Order.NONE]; -}; + function (block) { + const getResult = () => { + const unit = block.getFieldValue("UNIT"); + switch (unit) { + case "year": + return "new Date().getFullYear()"; + case "month": + return "new Date().getMonth() + 1"; + case "date": + return "new Date().getDate()"; + case "day": + return "new Date().getDay()"; + case "hour": + return "new Date().getHours()"; + case "minute": + return "new Date().getMinutes()"; + case "second": + return "new Date().getSeconds()"; + case "millisecond": + return "new Date().getMilliseconds()"; + case "timestamp": + return "Date.now()"; + default: + return "0"; + } + }; + return [getResult(), BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["system_distance_direction"] = { - init: function () { +quickBlockMaker( + "system_distance_direction", + function () { this.appendDummyInput().appendField( new Blockly.FieldDropdown([ ["distance", "distance"], @@ -229,50 +225,43 @@ Blockly.Blocks["system_distance_direction"] = { this.setOutput(true, "Number"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["system_distance_direction"] = function ( - block, - generator, -) { - const mode = block.getFieldValue("MODE"); - const x1 = generator.valueToCode(block, "X1", BlocklyJS.Order.NONE) || "0"; - const y1 = generator.valueToCode(block, "Y1", BlocklyJS.Order.NONE) || "0"; - const x2 = generator.valueToCode(block, "X2", BlocklyJS.Order.NONE) || "0"; - const y2 = generator.valueToCode(block, "Y2", BlocklyJS.Order.NONE) || "0"; + function (block, generator) { + const mode = block.getFieldValue("MODE"); + const x1 = generator.valueToCode(block, "X1", BlocklyJS.Order.NONE) || "0"; + const y1 = generator.valueToCode(block, "Y1", BlocklyJS.Order.NONE) || "0"; + const x2 = generator.valueToCode(block, "X2", BlocklyJS.Order.NONE) || "0"; + const y2 = generator.valueToCode(block, "Y2", BlocklyJS.Order.NONE) || "0"; - if (mode === "distance") { - return [ - `Math.sqrt(Math.pow(${x2} - ${x1}, 2) + Math.pow(${y2} - ${y1}, 2))`, - BlocklyJS.Order.NONE, - ]; - } else { + if (mode === "distance") { + return [ + `Math.sqrt(Math.pow(${x2} - ${x1}, 2) + Math.pow(${y2} - ${y1}, 2))`, + BlocklyJS.Order.NONE, + ]; + } return [ `((Math.atan2(${x2} - ${x1}, ${y2} - ${y1}) * 180 / Math.PI + 360) % 360)`, BlocklyJS.Order.NONE, ]; } -}; +); // Used to be in controls -Blockly.Blocks["controls_clones_list"] = { - init: function () { +quickBlockMaker( + "controls_clones_list", + function () { this.appendValueInput("ID").setCheck("String").appendField("list clones of"); this.setOutput(true, "Array"); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["controls_clones_list"] = function ( - block, - generator, -) { - const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); - return [`spriteManager.get(${ID})?.getAllClones()`, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.ATOMIC); + return [`spriteManager.get(${ID})?.getAllClones()`, BlocklyJS.Order.NONE]; + } +); -Blockly.Blocks["system_sprites_list"] = { - init: function () { +quickBlockMaker( + "system_sprites_list", + function () { this.appendDummyInput() .appendField("list all") .appendField( @@ -285,23 +274,23 @@ Blockly.Blocks["system_sprites_list"] = { this.setOutput(true, "Array"); this.setStyle("system_blocks"); }, -}; + function (block) { + const TYPE = block.getFieldValue("TYPE"); -BlocklyJS.javascriptGenerator.forBlock["system_sprites_list"] = function (block) { - const TYPE = block.getFieldValue("TYPE"); + let code = "new Array()"; + if (TYPE === "SPRITES") { + code = "spriteManager.getOriginals()"; + } else { + code = "spriteManager.getAll()"; + } - let code = "new Array()"; - if (TYPE === "SPRITES") { - code = "spriteManager.getOriginals()"; - } else { - code = "spriteManager.getAll()"; + return [code, BlocklyJS.Order.NONE]; } +); - return [code, BlocklyJS.Order.NONE]; -}; - -Blockly.Blocks["system_sprite_property"] = { - init: function () { +quickBlockMaker( + "system_sprite_property", + function () { this.appendValueInput("ID") .setCheck("String") .appendField( @@ -324,13 +313,9 @@ Blockly.Blocks["system_sprite_property"] = { this.setOutput(true, null); this.setStyle("system_blocks"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["system_sprite_property"] = function ( - block, - generator, -) { - const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.NONE); - const PROP = block.getFieldValue("PROP"); - return [`spriteManager.get(${ID})?.${PROP}`, BlocklyJS.Order.NONE]; -}; + function (block, generator) { + const ID = generator.valueToCode(block, "ID", BlocklyJS.Order.NONE); + const PROP = block.getFieldValue("PROP"); + return [`spriteManager.get(${ID})?.${PROP}`, BlocklyJS.Order.NONE]; + } +); diff --git a/src/blocks/text.js b/src/blocks/text.js index a9993b2..1981533 100644 --- a/src/blocks/text.js +++ b/src/blocks/text.js @@ -1,5 +1,6 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; const xmlUtils = Blockly.utils.xml; function shadow(type, fieldName, value) { @@ -119,8 +120,9 @@ BlocklyJS.javascriptGenerator.forBlock["text_join_extendable"] = function ( return [code, BlocklyJS.Order.NONE]; }; -Blockly.Blocks["text_indexOf"] = { - init: function () { +quickBlockMaker( + "text_indexOf", + function () { this.setStyle("text_blocks"); this.setInputsInline(true); this.setOutput(true, "Number"); @@ -151,18 +153,17 @@ Blockly.Blocks["text_indexOf"] = { .setCheck("String") .connection.setShadowDom(shadow("text", "TEXT", "")); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["text_indexOf"] = function (block, generator) { - const operator = block.getFieldValue("END") === "FIRST" ? "indexOf" : "lastIndexOf"; - const substring = generator.valueToCode(block, "FIND", BlocklyJS.Order.NONE) || "''"; - const text = generator.valueToCode(block, "VALUE", BlocklyJS.Order.MEMBER) || "''"; - const code = `${text}.${operator}(${substring})`; - if (block.workspace.options.oneBasedIndex) { - return [`${code} + 1`, BlocklyJS.Order.ADDITION]; + function (block, generator) { + const operator = block.getFieldValue("END") === "FIRST" ? "indexOf" : "lastIndexOf"; + const substring = generator.valueToCode(block, "FIND", BlocklyJS.Order.NONE) || "''"; + const text = generator.valueToCode(block, "VALUE", BlocklyJS.Order.MEMBER) || "''"; + const code = `${text}.${operator}(${substring})`; + if (block.workspace.options.oneBasedIndex) { + return [`${code} + 1`, BlocklyJS.Order.ADDITION]; + } + return [code, BlocklyJS.Order.MEMBER]; } - return [code, BlocklyJS.Order.MEMBER]; -}; +); Blockly.Blocks["text_charAt"] = { isAt_: false, diff --git a/src/blocks/tween.js b/src/blocks/tween.js index 9ee7649..9336157 100644 --- a/src/blocks/tween.js +++ b/src/blocks/tween.js @@ -1,5 +1,6 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; +import { quickBlockMaker } from "./quickblockmaker"; const tweensList = [ ["linear", "Linear"], @@ -15,8 +16,9 @@ const tweensList = [ ["bounce", "Bounce"], ]; -Blockly.Blocks["tween_block"] = { - init: function () { +quickBlockMaker( + "tween_block", + function () { this.appendValueInput("FROM").setCheck("Number").appendField("tween from"); this.appendValueInput("TO").setCheck("Number").appendField("to"); this.appendDummyInput().appendField("in"); @@ -55,23 +57,19 @@ Blockly.Blocks["tween_block"] = { "Tween a value from one number to another over time using easing" ); }, -}; + function (block, generator) { + const easingType = block.getFieldValue("EASING_TYPE"); + const easingMode = block.getFieldValue("EASING_MODE"); + const from = + generator.valueToCode(block, "FROM", BlocklyJS.Order.ATOMIC) || "0"; + const to = + generator.valueToCode(block, "TO", BlocklyJS.Order.ATOMIC) || "0"; + const duration = + generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || "1"; + const waitMode = block.getFieldValue("WAIT_MODE"); + const branch = BlocklyJS.javascriptGenerator.statementToCode(block, "DO"); -BlocklyJS.javascriptGenerator.forBlock["tween_block"] = function (block, generator) { - const easingType = block.getFieldValue("EASING_TYPE"); - const easingMode = block.getFieldValue("EASING_MODE"); - const from = - generator.valueToCode(block, "FROM", BlocklyJS.Order.ATOMIC) || - "0"; - const to = - generator.valueToCode(block, "TO", BlocklyJS.Order.ATOMIC) || "0"; - const duration = - generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || - "1"; - const waitMode = block.getFieldValue("WAIT_MODE"); - const branch = BlocklyJS.javascriptGenerator.statementToCode(block, "DO"); - - const code = `yield* startTween({ + const code = `yield* startTween({ from: ${from}, to: ${to}, duration: ${duration}, @@ -81,25 +79,27 @@ BlocklyJS.javascriptGenerator.forBlock["tween_block"] = function (block, generat ${branch} } });\n`; - return code; -}; + return code; + } +); -Blockly.Blocks["tween_block_value"] = { - init: function () { +quickBlockMaker( + "tween_block_value", + function () { this.appendDummyInput("name").appendField("current tween value"); this.setInputsInline(true); this.setColour("#32a2c0"); this.setOutput(true, "Number"); }, -}; - -BlocklyJS.javascriptGenerator.forBlock["tween_block_value"] = () => [ - "tweenValue", - BlocklyJS.Order.NONE, -]; + () => [ + "tweenValue", + BlocklyJS.Order.NONE, + ] +); -Blockly.Blocks["tween_sprite_property"] = { - init: function () { +quickBlockMaker( + "tween_sprite_property", + function () { this.appendValueInput("TO") .setCheck("Number") .appendField("tween") @@ -136,34 +136,29 @@ Blockly.Blocks["tween_sprite_property"] = { "Tween a sprite property to a target value over time using easing" ); }, -}; + function (block, generator) { + const prop = block.getFieldValue("PROPERTY"); + const to = + generator.valueToCode(block, "TO", BlocklyJS.Order.ATOMIC) || "0"; + const duration = + generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || "1"; + const easingType = block.getFieldValue("EASING_TYPE"); + const easingMode = block.getFieldValue("EASING_MODE"); -BlocklyJS.javascriptGenerator.forBlock["tween_sprite_property"] = function ( - block, - generator -) { - const prop = block.getFieldValue("PROPERTY"); - const to = - generator.valueToCode(block, "TO", BlocklyJS.Order.ATOMIC) || "0"; - const duration = - generator.valueToCode(block, "DURATION", BlocklyJS.Order.ATOMIC) || - "1"; - const easingType = block.getFieldValue("EASING_TYPE"); - const easingMode = block.getFieldValue("EASING_MODE"); + let fromGetter; + let setter; + if (prop === "size") { + fromGetter = "getSpriteScale()"; + setter = `setSize(tweenValue, false)`; + } else if (prop === "angle") { + fromGetter = `getTarget().angle`; + setter = `setAngle(tweenValue, false)`; + } else { + fromGetter = `getTarget().${prop}`; + setter = `getTarget().${prop} = tweenValue`; + } - let fromGetter, setter; - if (prop === "size") { - fromGetter = "getSpriteScale()"; - setter = `setSize(tweenValue, false)`; - } else if (prop === "angle") { - fromGetter = `getTarget().angle`; - setter = `setAngle(tweenValue, false)`; - } else { - fromGetter = `getTarget().${prop}`; - setter = `getTarget().${prop} = tweenValue`; - } - - const code = `yield* startTween({ + const code = `yield* startTween({ from: ${fromGetter}, to: ${to}, duration: ${duration}, @@ -173,5 +168,6 @@ BlocklyJS.javascriptGenerator.forBlock["tween_sprite_property"] = function ( } });\n`; - return code; -}; + return code; + } +); diff --git a/src/blocks/variable.js b/src/blocks/variable.js index 3879a31..1aca205 100644 --- a/src/blocks/variable.js +++ b/src/blocks/variable.js @@ -1,6 +1,7 @@ import * as Blockly from "blockly"; import * as BlocklyJS from "blockly/javascript"; import { deleteVariable, projectVariables } from "../scripts/editor"; +import { quickBlockMaker } from "./quickblockmaker"; function getVariables() { if (Object.keys(projectVariables).length === 0) @@ -30,8 +31,9 @@ Blockly.Blocks["get_global_var"] = { }, }; -Blockly.Blocks["set_global_var"] = { - init: function () { +quickBlockMaker( + "set_global_var", + function () { this.appendValueInput("VALUE") .setCheck(null) .appendField("set") @@ -41,10 +43,21 @@ Blockly.Blocks["set_global_var"] = { this.setNextStatement(true, "default"); this.setStyle("variable_blocks"); }, -}; + function (block) { + const name = block.getFieldValue("VAR"); + const value = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.ASSIGNMENT + ) || "0"; + return `projectVariables["${name}"] = ${value};\n`; + } +); -Blockly.Blocks["change_global_var"] = { - init: function () { +quickBlockMaker( + "change_global_var", + function () { this.appendValueInput("VALUE") .setCheck("Number") .appendField("change") @@ -54,31 +67,20 @@ Blockly.Blocks["change_global_var"] = { this.setNextStatement(true, "default"); this.setStyle("variable_blocks"); }, -}; + function (block) { + const name = block.getFieldValue("VAR"); + const value = + BlocklyJS.javascriptGenerator.valueToCode( + block, + "VALUE", + BlocklyJS.Order.ATOMIC + ) || "0"; + return `projectVariables["${name}"] += ${value};\n`; + } +); BlocklyJS.javascriptGenerator.forBlock["get_global_var"] = function (block) { const name = block.getFieldValue("VAR"); return [`projectVariables["${name}"]`, BlocklyJS.Order.ATOMIC]; }; -BlocklyJS.javascriptGenerator.forBlock["set_global_var"] = function (block) { - const name = block.getFieldValue("VAR"); - const value = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.ASSIGNMENT - ) || "0"; - return `projectVariables["${name}"] = ${value};\n`; -}; - -BlocklyJS.javascriptGenerator.forBlock["change_global_var"] = function (block) { - const name = block.getFieldValue("VAR"); - const value = - BlocklyJS.javascriptGenerator.valueToCode( - block, - "VALUE", - BlocklyJS.Order.ATOMIC - ) || "0"; - return `projectVariables["${name}"] += ${value};\n`; -};