// color-and-keys-extension.js
(function (Scratch) {
'use strict';
class ColorAndKeyExtension {
getInfo() {
return {
id: 'colorAndKeyExtension_v2',
name: 'Color & Key Detector (v2)',
blocks: [
{
opcode: 'getColorUnderSprite',
blockType: Scratch.BlockType.REPORTER,
text: 'color under sprite'
},
{
opcode: 'getColorUnderSpriteAt',
blockType: Scratch.BlockType.REPORTER,
text: 'color under sprite at x: [X] y: [Y]',
arguments: {
X: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 },
Y: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 }
}
},
{
opcode: 'isKeyPressed',
blockType: Scratch.BlockType.BOOLEAN,
text: 'key [KEY] pressed?',
arguments: {
KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'space' }
}
},
{
opcode: 'keysPressedList',
blockType: Scratch.BlockType.REPORTER,
text: 'keys currently pressed'
}
]
};
}
_rgbToHex(r, g, b) {
const toHex = v => ('0' + Math.max(0, Math.min(255, Math.round(v))).toString(16)).slice(-2);
return '#' + toHex(r) + toHex(g) + toHex(b);
}
_getColorAtTarget(target, offsetX = 0, offsetY = 0) {
const vm = Scratch.vm;
const renderer = vm && vm.renderer;
const runtime = vm && vm.runtime;
if (!renderer || !runtime || !target) return '#000000';
const stageW = runtime.constructor.STAGE_WIDTH || 480;
const stageH = runtime.constructor.STAGE_HEIGHT || 360;
const xScratch = (target.x || 0) + Number(offsetX || 0);
const yScratch = (target.y || 0) + Number(offsetY || 0);
// Scratch→pick coords: (0,0) is center
const pickX = Math.round(xScratch + stageW / 2);
const pickY = Math.round(-yScratch + stageH / 2);
let pickResult;
try {
pickResult = renderer.pick(pickX, pickY, null, null);
} catch (e) {
return '#000000';
}
if (!pickResult) return '#000000';
let r, g, b;
if (Array.isArray(pickResult)) {
[ , r, g, b ] = pickResult;
} else if (typeof pickResult === 'object') {
({ r, g, b } = pickResult);
}
if (typeof r !== 'number') return '#000000';
return this._rgbToHex(r, g, b);
}
getColorUnderSprite(args, util) {
return this._getColorAtTarget(util.target, 0, 0);
}
getColorUnderSpriteAt(args, util) {
return this._getColorAtTarget(util.target, Number(args.X), Number(args.Y));
}
isKeyPressed(args) {
const key = String(args.KEY || '').toLowerCase();
const kbd = Scratch.vm.runtime.ioDevices.keyboard;
return kbd && kbd.getKeyIsDown(key);
}
keysPressedList() {
const kbd = Scratch.vm.runtime.ioDevices.keyboard;
if (!kbd || !kbd.getKeyIsDown) return '';
const keys = [];
for (le










0 comments