wow thats a lot of changes

This commit is contained in:
2026-01-20 16:50:04 -06:00
parent b0f26c4c6c
commit 9c9c6b99b3
12 changed files with 1679 additions and 112 deletions

View File

@@ -117,7 +117,7 @@ Blockly.Blocks["every_seconds"] = {
init: function () {
this.appendDummyInput()
.appendField("every")
.appendField(new Blockly.FieldNumber(2, 0.1), "SECONDS")
.appendField(new Blockly.FieldNumber(2, 0.01), "SECONDS")
.appendField("seconds");
this.appendStatementInput("DO").setCheck("default");
this.setStyle("events_blocks");

View File

@@ -1,5 +1,6 @@
import * as Blockly from "blockly";
import * as BlocklyJS from "blockly/javascript";
import {FieldColourHsvSliders} from '@blockly/field-colour-hsv-sliders';
function getAvailableCostumes() {
if (window.projectCostumes && window.projectCostumes.length > 0) {
@@ -216,3 +217,95 @@ BlocklyJS.javascriptGenerator.forBlock["switch_backdrop"] = function (block) {
const name = block.getFieldValue("BACKDROP_NAME");
return `setBackdropByName('${name}');\n`;
};
// Color/Tint effect block - with HSV color picker
Blockly.Blocks["set_color_effect"] = {
init: function () {
this.appendDummyInput()
.appendField("set color effect to")
.appendField(new FieldColourHsvSliders("#ff0000"), "COLOR");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setInputsInline(true);
this.setStyle("looks_blocks");
},
};
BlocklyJS.javascriptGenerator.forBlock["set_color_effect"] = function (block, generator) {
const color = block.getFieldValue("COLOR") || "#000000";
return `setSpriteEffect('tint', '${color}');\n`;
};
// Set effect by amount
Blockly.Blocks["set_effect"] = {
init: function () {
this.appendDummyInput()
.appendField("set")
.appendField(new Blockly.FieldDropdown([
["color", "color"],
["brightness", "brightness"],
["ghost", "ghost"],
["pixelate", "pixelate"],
["mosaic (WIP)", "mosaic"],
["whirl", "whirl"],
["fisheye", "fisheye"],
]), "EFFECT")
.appendField("effect to");
this.appendValueInput("VALUE")
.setCheck("Number");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setInputsInline(true);
this.setStyle("looks_blocks");
},
};
BlocklyJS.javascriptGenerator.forBlock["set_effect"] = function (block, generator) {
const effect = block.getFieldValue("EFFECT");
const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC) || "0";
return `setSpriteEffect('${effect}', ${value});\n`;
};
// Change effect by amount
Blockly.Blocks["change_effect"] = {
init: function () {
this.appendDummyInput()
.appendField("change")
.appendField(new Blockly.FieldDropdown([
["color", "color"],
["brightness", "brightness"],
["ghost", "ghost"],
["pixelate", "pixelate"],
["mosaic (WIP)", "mosaic"],
["whirl", "whirl"],
["fisheye", "fisheye"],
]), "EFFECT")
.appendField("effect by");
this.appendValueInput("VALUE")
.setCheck("Number");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setInputsInline(true);
this.setStyle("looks_blocks");
},
};
BlocklyJS.javascriptGenerator.forBlock["change_effect"] = function (block, generator) {
const effect = block.getFieldValue("EFFECT");
const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC) || "0";
return `changeSpriteEffect('${effect}', ${value});\n`;
};
// Clear all effects
Blockly.Blocks["clear_effects"] = {
init: function () {
this.appendDummyInput().appendField("clear graphic effects");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setStyle("looks_blocks");
},
};
BlocklyJS.javascriptGenerator.forBlock["clear_effects"] = function () {
return `clearSpriteEffects();\n`;
};

90
src/blocks/monitors.js Normal file
View File

@@ -0,0 +1,90 @@
import * as Blockly from "blockly";
import * as BlocklyJS from "blockly/javascript";
Blockly.Blocks["show_variable"] = {
init: function () {
this.appendDummyInput()
.appendField("show variable")
.appendField(new Blockly.FieldDropdown(this.getVariables), "VAR");
this.appendDummyInput()
.appendField("at x:")
.appendField(new Blockly.FieldNumber(10), "X")
.appendField("y:")
.appendField(new Blockly.FieldNumber(10), "Y");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setColour("#FF8C1A");
this.setInputsInline(true);
},
getVariables: function() {
const variables = window.projectVariables || {};
const varNames = Object.keys(variables);
if (varNames.length === 0) {
return [["no variables", ""]];
}
return varNames.map(name => [name, name]);
}
};
BlocklyJS.javascriptGenerator.forBlock["show_variable"] = function (block) {
const varName = block.getFieldValue("VAR");
const x = block.getFieldValue("X") || 10;
const y = block.getFieldValue("Y") || 10;
return `showVariableMonitor("${varName}", ${x}, ${y});\n`;
};
Blockly.Blocks["hide_variable"] = {
init: function () {
this.appendDummyInput()
.appendField("hide variable")
.appendField(new Blockly.FieldDropdown(this.getVariables), "VAR");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setColour("#FF8C1A");
},
getVariables: function() {
const variables = window.projectVariables || {};
const varNames = Object.keys(variables);
if (varNames.length === 0) {
return [["no variables", ""]];
}
return varNames.map(name => [name, name]);
}
};
BlocklyJS.javascriptGenerator.forBlock["hide_variable"] = function (block) {
const varName = block.getFieldValue("VAR");
return `hideVariableMonitor("${varName}");\n`;
};
// Block to MOVE the variable monitor to a position
Blockly.Blocks["move_variable_to"] = {
init: function () {
this.appendDummyInput()
.appendField("move variable")
.appendField(new Blockly.FieldDropdown(this.getVariables), "VAR")
.appendField("to x:")
.appendField(new Blockly.FieldNumber(10), "X")
.appendField("y:")
.appendField(new Blockly.FieldNumber(10), "Y");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setColour("#FF8C1A");
},
getVariables: function() {
const variables = window.projectVariables || {};
const varNames = Object.keys(variables);
if (varNames.length === 0) {
return [["no variables", ""]];
}
return varNames.map(name => [name, name]);
}
};
BlocklyJS.javascriptGenerator.forBlock["move_variable_to"] = function (block) {
const varName = block.getFieldValue("VAR");
const x = block.getFieldValue("X") || 10;
const y = block.getFieldValue("Y") || 10;
console.log('Generating move_variable_to code:', varName, x, y);
return `moveVariableMonitor("${varName}", ${x}, ${y});\n`;
};

278
src/blocks/sensing.js Normal file
View File

@@ -0,0 +1,278 @@
import * as Blockly from "blockly";
import * as BlocklyJS from "blockly/javascript";
import {FieldColourHsvSliders} from '@blockly/field-colour-hsv-sliders';
// Function to get available sprites for dropdown
function getAvailableSprites() {
if (window.sprites && window.sprites.length > 0) {
return window.sprites.map(sprite => [sprite.id, sprite.id]);
}
return [["no sprites", ""]];
}
// Touching block
Blockly.Blocks["touching"] = {
init: function () {
this.appendDummyInput("MAIN")
.appendField("touching")
.appendField(
new Blockly.FieldDropdown([
["mouse pointer", "mouse"],
["edge", "edge"],
["sprite", "sprite"],
]),
"TARGET"
);
this.setOutput(true, "Boolean");
this.setColour("#4CBFE6");
this.setTooltip("Check if sprite is touching something");
},
onchange: function(e) {
if (e.type === Blockly.Events.BLOCK_FIELD_INTERMEDIATE_CHANGE) return;
if (!this.workspace) return;
const target = this.getFieldValue('TARGET');
const spriteDropdown = this.getField('SPRITE_ID');
const mainInput = this.getInput('MAIN');
if (target === 'sprite') {
if (!spriteDropdown) {
mainInput.appendField("named");
mainInput.appendField(new Blockly.FieldDropdown(
function() {
return getAvailableSprites();
}
), "SPRITE_ID");
}
} else {
if (spriteDropdown) {
// Remove the dropdown first
mainInput.removeField('SPRITE_ID');
// Find and remove the "named" label
const fields = mainInput.fieldRow;
for (let i = fields.length - 1; i >= 0; i--) {
const field = fields[i];
if (field.getText && field.getText() === "named") {
mainInput.removeField(fields[i].name, true);
break;
}
}
}
}
}
};
BlocklyJS.javascriptGenerator.forBlock["touching"] = function (block, generator) {
const target = block.getFieldValue("TARGET");
if (target === "mouse") {
return [`isTouchingMouse()`, BlocklyJS.Order.FUNCTION_CALL];
} else if (target === "edge") {
return [`isTouchingEdge()`, BlocklyJS.Order.FUNCTION_CALL];
} else if (target === "sprite") {
const spriteId = block.getFieldValue("SPRITE_ID") || "";
return [`isTouchingSprite("${spriteId}")`, BlocklyJS.Order.FUNCTION_CALL];
}
return ["false", BlocklyJS.Order.ATOMIC];
};
// Mouse down block
Blockly.Blocks["mouse_down"] = {
init: function () {
this.appendDummyInput().appendField("mouse down?");
this.setOutput(true, "Boolean");
this.setColour("#4CBFE6");
this.setTooltip("Check if mouse button is pressed");
},
};
BlocklyJS.javascriptGenerator.forBlock["mouse_down"] = function () {
return [`isMouseDown()`, BlocklyJS.Order.FUNCTION_CALL];
};
// Touching color block with full slider control
Blockly.Blocks["touching_color"] = {
init: function () {
this.appendDummyInput()
.appendField("touching color")
.appendField(new FieldColourHsvSliders("#ff0000"), "COLOR");
this.setOutput(true, "Boolean");
this.setColour("#4CBFE6");
this.setTooltip("Check if sprite is touching a specific color");
},
};
BlocklyJS.javascriptGenerator.forBlock["touching_color"] = function (block) {
const color = block.getFieldValue("COLOR");
return [`isTouchingColor("${color}")`, BlocklyJS.Order.FUNCTION_CALL];
};
// Distance to block - FIXED VERSION
Blockly.Blocks["distance_to"] = {
init: function () {
this.appendDummyInput("MAIN")
.appendField("distance to")
.appendField(
new Blockly.FieldDropdown([
["mouse pointer", "mouse"],
["sprite", "sprite"],
]),
"TARGET"
);
this.setOutput(true, "Number");
this.setColour("#4CBFE6");
this.setTooltip("Get distance to target");
},
onchange: function(e) {
if (e.type === Blockly.Events.BLOCK_FIELD_INTERMEDIATE_CHANGE) return;
if (!this.workspace) return;
const target = this.getFieldValue('TARGET');
const spriteDropdown = this.getField('SPRITE_ID');
const mainInput = this.getInput('MAIN');
if (target === 'sprite') {
if (!spriteDropdown) {
mainInput.appendField("named");
mainInput.appendField(new Blockly.FieldDropdown(
function() {
return getAvailableSprites();
}
), "SPRITE_ID");
}
} else {
if (spriteDropdown) {
// Remove the dropdown first
mainInput.removeField('SPRITE_ID');
// Find and remove the "named" label
const fields = mainInput.fieldRow;
for (let i = fields.length - 1; i >= 0; i--) {
const field = fields[i];
if (field.getText && field.getText() === "named") {
mainInput.removeField(fields[i].name, true);
break;
}
}
}
}
}
};
BlocklyJS.javascriptGenerator.forBlock["distance_to"] = function (block, generator) {
const target = block.getFieldValue("TARGET");
if (target === "mouse") {
return [`distanceToMouse()`, BlocklyJS.Order.FUNCTION_CALL];
} else if (target === "sprite") {
const spriteId = block.getFieldValue("SPRITE_ID") || "";
return [`distanceToSprite("${spriteId}")`, BlocklyJS.Order.FUNCTION_CALL];
}
return ["0", BlocklyJS.Order.ATOMIC];
};
// Answer (for ask and wait)
Blockly.Blocks["answer"] = {
init: function () {
this.appendDummyInput().appendField("answer");
this.setOutput(true, "String");
this.setColour("#4CBFE6");
this.setTooltip("The answer from the last 'ask and wait' prompt");
},
};
BlocklyJS.javascriptGenerator.forBlock["answer"] = function () {
return [`getAnswer()`, BlocklyJS.Order.FUNCTION_CALL];
};
// Ask and wait
Blockly.Blocks["ask_and_wait"] = {
init: function () {
this.appendValueInput("QUESTION")
.setCheck("String")
.appendField("ask")
.appendField("and wait");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setColour("#4CBFE6");
this.setTooltip("Ask a question and wait for user input");
},
};
BlocklyJS.javascriptGenerator.forBlock["ask_and_wait"] = function (block, generator) {
const question = generator.valueToCode(block, "QUESTION", BlocklyJS.Order.ATOMIC) || '"What\'s your name?"';
return `await askAndWait(${question});\n`;
};
// Username
Blockly.Blocks["username"] = {
init: function () {
this.appendDummyInput().appendField("username");
this.setOutput(true, "String");
this.setColour("#4CBFE6");
this.setTooltip("Get the current username");
},
};
BlocklyJS.javascriptGenerator.forBlock["username"] = function () {
return [`getUsername()`, BlocklyJS.Order.FUNCTION_CALL];
};
// Loudness
Blockly.Blocks["loudness"] = {
init: function () {
this.appendDummyInput().appendField("loudness");
this.setOutput(true, "Number");
this.setColour("#4CBFE6");
this.setTooltip("Microphone loudness (0-100)");
},
};
BlocklyJS.javascriptGenerator.forBlock["loudness"] = function () {
return [`getLoudness()`, BlocklyJS.Order.FUNCTION_CALL];
};
// Current date/time
Blockly.Blocks["current"] = {
init: function () {
this.appendDummyInput()
.appendField("current")
.appendField(
new Blockly.FieldDropdown([
["year", "year"],
["month", "month"],
["date", "date"],
["day of week", "dayofweek"],
["hour", "hour"],
["minute", "minute"],
["second", "second"],
]),
"UNIT"
);
this.setOutput(true, "Number");
this.setColour("#4CBFE6");
this.setTooltip("Get current date/time value");
},
};
BlocklyJS.javascriptGenerator.forBlock["current"] = function (block) {
const unit = block.getFieldValue("UNIT");
return [`getCurrent("${unit}")`, BlocklyJS.Order.FUNCTION_CALL];
};
// Days since 2000
Blockly.Blocks["days_since_2000"] = {
init: function () {
this.appendDummyInput().appendField("days since 2000");
this.setOutput(true, "Number");
this.setColour("#4CBFE6");
this.setTooltip("Number of days since January 1, 2000");
},
};
BlocklyJS.javascriptGenerator.forBlock["days_since_2000"] = function () {
return [`getDaysSince2000()`, BlocklyJS.Order.FUNCTION_CALL];
};

View File

@@ -0,0 +1,77 @@
import * as Blockly from "blockly";
import * as BlocklyJS from "blockly/javascript";
Blockly.Blocks["display_text_as_sprite"] = {
init: function () {
this.appendValueInput("TEXT")
.setCheck("String")
.appendField("display text");
this.appendDummyInput()
.appendField("font size")
.appendField(new Blockly.FieldNumber(32, 1, 500), "SIZE");
this.appendDummyInput()
.appendField("color")
.appendField(new Blockly.FieldTextInput("#ffffff"), "COLOR"); // CHANGED: Use FieldTextInput instead
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setStyle("looks_blocks");
this.setTooltip("Display text as the sprite");
},
};
BlocklyJS.javascriptGenerator.forBlock["display_text_as_sprite"] = function (
block,
generator
) {
const text = generator.valueToCode(block, "TEXT", BlocklyJS.Order.ATOMIC) || '""';
const size = block.getFieldValue("SIZE");
const color = block.getFieldValue("COLOR");
return `displayTextAsSprite(${text}, ${size}, "${color}");\n`;
};
Blockly.Blocks["clear_text_sprite"] = {
init: function () {
this.appendDummyInput().appendField("clear text sprite");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setStyle("looks_blocks");
this.setTooltip("Remove text and restore original sprite");
},
};
BlocklyJS.javascriptGenerator.forBlock["clear_text_sprite"] = function () {
return `clearTextSprite();\n`;
};
Blockly.Blocks["set_text_property"] = {
init: function () {
this.appendValueInput("VALUE")
.appendField("set text")
.appendField(
new Blockly.FieldDropdown([
["font", "font"],
["alignment", "align"],
["bold", "bold"],
["italic", "italic"],
["outline color", "stroke"],
["outline thickness", "strokeThickness"],
]),
"PROPERTY"
)
.appendField("to");
this.setPreviousStatement(true, "default");
this.setNextStatement(true, "default");
this.setStyle("looks_blocks");
},
};
BlocklyJS.javascriptGenerator.forBlock["set_text_property"] = function (
block,
generator
) {
const property = block.getFieldValue("PROPERTY");
const value = generator.valueToCode(block, "VALUE", BlocklyJS.Order.ATOMIC) || '""';
return `setTextProperty("${property}", ${value});\n`;
};