跳到主要内容

各种 API

既然你熟悉编写自定义扩展,我们将分享更多 API。这些 API 在沙盒化和非沙盒化扩展中都可用。它们都可以一起使用。

color1, color2, color3

这三个属性分别决定每个扩展的积木颜色、积木输入颜色和积木菜单颜色。一般建议是 color1 应该最亮,color2 稍暗,color3 最暗。它们应该设置为十六进制颜色代码。

color.js - 尝试此扩展
class ColorExample {
getInfo() {
return {
id: 'colorexample',
name: 'Color Example',
// intentionally bad colors so that the effect is more clear
color1: '#ff0000', // pure red
color2: '#00ff00', // pure green
color3: '#0000ff', // pure blue
blocks: [
{
opcode: 'reporter',
blockType: Scratch.BlockType.REPORTER,
text: 'string [STRING] boolean [BOOLEAN] menu [MENU] field [FIELD]',
arguments: {
STRING: {
type: Scratch.ArgumentType.STRING,
defaultValue: '1'
},
BOOLEAN: {
type: Scratch.ArgumentType.BOOLEAN
},
MENU: {
type: Scratch.ArgumentType.STRING,
menu: 'MENU'
},
FIELD: {
type: Scratch.ArgumentType.STRING,
menu: 'FIELD'
}
}
},
],
menus: {
MENU: {
acceptReporters: true,
items: ['item 1', 'item 2']
},
// We're just including a field example for completion.
// Please do not use acceptReporters: false!
FIELD: {
acceptReporters: false,
items: ['item 1', 'item 2']
}
}
};
}

reporter() {
return 'This block does nothing';
}
}

Scratch.extensions.register(new ColorExample());

不同的积木颜色模式(如 High ContrastDark 和任何 "Addons" 预设)会根据这些值自动生成。

docsURI

docsURI 在积木列表的开头添加一个按钮,用于打开页面让人们了解你的扩展如何工作。

hello-docs.js - 尝试此扩展
class HelloDocs {
getInfo() {
return {
id: 'hellodocs',
name: 'Hello Docs!',
docsURI: 'https://docs.bilup.org/development/extensions/docsURI-demo',
blocks: [
{
opcode: 'hello',
blockType: Scratch.BlockType.REPORTER,
text: 'Hello!'
}
]
};
}

hello() {
return Math.random();
}
}

Scratch.extensions.register(new HelloDocs());

disableMonitor

Scratch 会自动显示一个复选框,用于显示没有输入的 REPORTER 积木的变量监视器。请注意,在 Bilup 中,这也适用于 BOOLEAN 积木。要禁用此功能,请在积木上设置 disableMonitor 为 true。

请注意,即使设置了 disableMonitor,人们仍然可以使用修改版(或旧版)扩展或其他工具手动创建监视器。

unmonitorable.js - 尝试此扩展
class DisableMonitorExample {
getInfo() {
return {
id: 'disablemonitorexample',
name: 'disableMonitor Example',
blocks: [
{
opcode: 'monitorable',
blockType: Scratch.BlockType.REPORTER,
text: 'this block can be monitored'
},
{
opcode: 'unmonitorable',
blockType: Scratch.BlockType.REPORTER,
text: 'but this one can not',
disableMonitor: true
},
]
};
}

monitorable() {
return Math.random();
}

unmonitorable() {
return Math.random();
}
}

Scratch.extensions.register(new DisableMonitorExample());

Scratch.Cast

Scratch 处理类型转换或比较等操作的方式有很多奇特的方式。与其尝试自己编写它们,你可以使用 Scratch.Cast.* API。

cast.js - 尝试此扩展
class CastingExample {
getInfo() {
return {
id: 'castexample',
name: 'Casting Example',
blocks: [
{
opcode: 'toNumber',
blockType: Scratch.BlockType.REPORTER,
text: 'convert [INPUT] to number',
arguments: {
INPUT: {
type: Scratch.ArgumentType.STRING,
defaultValue: '3.0'
}
}
},
{
// The opcode "toString" should work but given it's special
// treatment in JS, it seems a bit dangerous to use
opcode: 'castToString',
blockType: Scratch.BlockType.REPORTER,
text: 'convert [INPUT] to string',
arguments: {
INPUT: {
type: Scratch.ArgumentType.STRING,
defaultValue: 'Hello'
}
}
},
{
opcode: 'toBoolean',
blockType: Scratch.BlockType.BOOLEAN,
text: 'convert [INPUT] to boolean',
arguments: {
INPUT: {
type: Scratch.ArgumentType.STRING,
defaultValue: '1'
}
}
},
{
opcode: 'compare',
blockType: Scratch.BlockType.REPORTER,
text: 'compare [A] to [B]',
arguments: {
A: {
type: Scratch.ArgumentType.STRING,
defaultValue: '3'
},
B: {
type: Scratch.ArgumentType.STRING,
defaultValue: '5'
}
}
}
]
};
}

toNumber({INPUT}) {
return Scratch.Cast.toNumber(INPUT);
}

castToString({INPUT}) {
return Scratch.Cast.toString(INPUT);
}

toBoolean({INPUT}) {
return Scratch.Cast.toBoolean(INPUT);
}

compare({A, B}) {
const comparison = Scratch.Cast.compare(A, B);
// You need to use < 0, > 0, or === 0 here.
// Do not use === 1 or === -1! That will not work in some cases.
if (comparison === 0) {
return 'Equal';
} else if (comparison > 0) {
return 'A is greater';
} else if (comparison < 0) {
return 'B is greater';
}
}
}

Scratch.extensions.register(new CastingExample());

hideFromPalette

有时你可能希望从工具箱中隐藏一个积木,但不想删除它。这对于确保你的更改向后兼容很有用。具有 hideFromPalette 属性的积木将从工具箱中隐藏,但项目中已有的任何副本将继续正常工作。

例如,在这里加载第一个扩展,并使用其积木保存项目:

hidden-1.js - 尝试此扩展
class HideFromPaletteExample {
getInfo() {
return {
id: 'hidefrompaletteexample',
name: 'hideFromPalette Example',
blocks: [
{
opcode: 'hidden',
blockType: Scratch.BlockType.REPORTER,
text: 'example block (visible)'
},
]
};
}

hidden() {
return 'The block is still visible';
}
}

Scratch.extensions.register(new HideFromPaletteExample());

然后改用此扩展,并加载之前的项目:

hidden-2.js - 尝试此扩展
class HideFromPaletteExample {
getInfo() {
return {
id: 'hidefrompaletteexample',
name: 'hideFromPalette Example',
blocks: [
{
opcode: 'hidden',
blockType: Scratch.BlockType.REPORTER,
text: 'example block (hidden)',
hideFromPalette: true
},
]
};
}

hidden() {
return 'The block is hidden from the palette but still works';
}
}

Scratch.extensions.register(new HideFromPaletteExample());

可以看到已存在的积木副本继续工作,但它没有在工具箱中列出。

filter

你的一些积木可能只在角色中工作或只在舞台中工作。对于这些积木,你可以使用 filter 属性设置为包含 Scratch.TargetType.STAGEScratch.TargetType.SPRITE 的数组,使其仅在该类型的目标中可见。

请注意,仍然可以通过例如拖放或背包获取违反 filter 属性的积木。因此,你的积木必须仍然使用 util.target.isStage 检查目标是舞台还是角色。

filter.js - 尝试此扩展
class FilterExample {
getInfo() {
return {
id: 'filterexample',
name: 'Filter Example',
blocks: [
{
opcode: 'all',
blockType: Scratch.BlockType.COMMAND,
text: 'available in ALL targets',
},
{
opcode: 'sprites',
blockType: Scratch.BlockType.COMMAND,
text: 'available in ONLY sprites',
filter: [Scratch.TargetType.SPRITE]
},
{
opcode: 'stage',
blockType: Scratch.BlockType.COMMAND,
text: 'available in ONLY the stage',
filter: [Scratch.TargetType.STAGE]
},
{
opcode: 'none',
blockType: Scratch.BlockType.COMMAND,
text: 'available in NEITHER sprites or the stage',
// NOTE: Use hideFromPalette instead of filter: []
filter: []
}
]
};
}

all() {
return 0;
}
sprites() {
return 0;
}
stage() {
return 0;
}
none() {
return 0;
}
}

Scratch.extensions.register(new FilterExample());

Icons

有三种不同的方式可以向你的扩展添加图像:

  • menuIconURI 用于整个扩展。这设置出现在积木面板中的图像。如果未设置,默认为 blockIconURI。如果也未设置,则默认为扩展颜色的圆形。
  • blockIconURI 用于整个扩展。这将是所有未覆盖它的积木的默认值。
  • blockIconURI 用于每个积木。这会覆盖整个扩展上设置的 blockIconURI。

这些属性中的每一个都应该是内联的 data: URLs。首选 SVG,但至少 64x64 大小的 PNG 或 JPG 也能很好地工作。图标应该是方形的。

icons.js - 尝试此扩展
// From the Box2D extension: https://github.com/TurboWarp/extensions/blob/master/extensions/box2d.js
const blocksIcon = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOmE9Imh0dHA6Ly9ucy5hZG9iZS5jb20vQWRvYmVTVkdWaWV3ZXJFeHRlbnNpb25zLzMuMC8iDQoJIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSItMy43IC0zLjcgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgLTMuNyAtMy43IDQwIDQwIg0KCSB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxkZWZzPg0KPC9kZWZzPg0KPHJlY3QgeD0iOC45IiB5PSIxLjUiIGZpbGw9IiNGRkZGRkYiIHN0cm9rZT0iIzE2OUZCMCIgc3Ryb2tlLXdpZHRoPSIzIiB3aWR0aD0iMTQuOCIgaGVpZ2h0PSIxNC44Ii8+DQo8cmVjdCB4PSIxLjUiIHk9IjE2LjMiIGZpbGw9IiNGRkZGRkYiIHN0cm9rZT0iIzE2OUZCMCIgc3Ryb2tlLXdpZHRoPSIzIiB3aWR0aD0iMTQuOCIgaGVpZ2h0PSIxNC44Ii8+DQo8cmVjdCB4PSIxNi4zIiB5PSIxNi4zIiBmaWxsPSIjRkZGRkZGIiBzdHJva2U9IiMxNjlGQjAiIHN0cm9rZS13aWR0aD0iMyIgd2lkdGg9IjE0LjgiIGhlaWdodD0iMTQuOCIvPg0KPC9zdmc+";

// From the Pen Plus extension: https://github.com/TurboWarp/extensions/blob/master/extensions/penplus.js
const dangoIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABeCAYAAADc6BHlAAAAAXNSR0IArs4c6QAABItJREFUeF7tncuN2zAQhu0SctmCAuSQDnLZAlLCAjkG2BJSwF62gxwWSEG5pIQEFJYKRQ5f8+BzfLSoMfV/8yIl2/db+PrrvXUHxti3/LGJobeUndR5Sx9zRUmJWTquVCyF8a4UKOzj89Pt5em5VMxj3Idf34Pxfz5+y9nYHoQV4PR+I777ioGABM+pHQGyNYRqABjhfTAAiG0hRAH4ns8hvIIIc0RRcZUQ307Fi4btIiELQFJ8hXALevNLK9pC/N0h+CF/Amgp/s4QFECudxY+DtaAHt6/axQoAGEPz5kP1gE9vR+IguXb0tEBGCZLQ7gAGMH7jeI7Lc6GBOBB0AjIFRKJ404UKAAJgXM2dwLQdfUbA7ETAKPBAWGUIgwUYpfTUilpmCJccPsyFixTA+kOgCC8D2RKEN0AQMI//n7L1ebz+MvDpyUiostK2Be/RnhIdQDGNNHQFAC38C6MSEQMDyLYDZXqhCTFT4CYD4BUO+oCoKacXKHwomFoCOAdMe4oaCm+hTMLBPFbkj3EnwkCFJ5sWxM9xTcQZoiCWH5kgdAbwAwQsgAoRdkCkC66FUV5uIKcmhDpIa0RvH+GWpDzCDSEUbx/9DSUA3BuVbthnmtTR/J+IApKrjmX1diO10wG/ApT7psxvfP/SgDstdR8Me82IABzHTWOx+btkCHKRIpAKIA0PwoAyHIARQG0BXBJU6OIP3InxB0BQZ3oDSFx54w7JaNqxZIAKkXvemtzKQAp4b/8/BH10NfPX1PeK6XR8ZmSxo+C3CoFQeKnRI8pHoEhppOYYfuwlzQAX3iM6BAMAISIViJG3y/o/88fVDxuUlPJpMR35yANYloALcS3IDwIrJqxGgO8VywKXABcaScVfVIQpgTQWnzJSJAGYObOGgW9xJeC0AIAKwQLoEXaKeiOyPqRDRR2LZdNOmxr2tv7JaKgFYBLFGAXaL29f3YAJAijeD8AgeTEpJML048/DHXPYGAApC2dHgCCLWv7Rqo2jJJ+uNNQTwBBSoIiykJRAMh8U3ha0f1lY6tX+5lpSdGOjD6xUFjMsCQMBYCRlH7OCUUB0MXEWFAAGNWYzzkgaAQwq1phbigAXNvTIxbhGJNmAFxxYxG3LQDJNBR7OgKCoAAqclfJ0MyjKUHtccaTsgjp5JILYx4jloasoKn/T7CRwOX9pE0kZmFLzYm0o66gPgAzMfen/A2EnQGc+0ec7WgOgA/B8RZyBiEbKHVdxnFdoiACgawf2QCjsDWm2CH4RRhKRQAEsn5kAzWqMY69bNhxpaMeEGYFcNYCC3VWCDMDWALC7ACmh7ACAJuFWOpCakUsUZhXAhBEQ019yG1FWFvcEFYDAEYDsvtytbk+2ef93aO17/35XZG2RYOQFzDCacU3+wtWtyIQVgcQcwIjJuba2SFgJjGCZ/ecAysEBYBDyQZBAeAABB0XtjtSAHgALBAUAA0AGYICoAMgQVAAPADQEBQAHwAMhLsC4AVQBMHdslAA/ACyEBwAGgEy+h9WwcWav2GnESBIwIcAfJRGgKz+YST4u67/APKrBHxjStmdAAAAAElFTkSuQmCC";
const colorIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF4AAABeCAYAAACq0qNuAAAAAXNSR0IArs4c6QAABTFJREFUeF7t3b2KFEEUBeAecBVkk8nERBSMBEGMTDcxN/IhfATDRdinMDSaV5gn8REEo40MlBqoobrmVtWtqvtzWnYzd3tmer46ffrOr7tlOz9/mbu6Y27nuhniTnKBe+Gg7ivKzmhhlxbH/X577UAT+smnD81EP3r9vLnN/d2huc2yLOYO1jdYBOdA54Ic+PwyjYUw87C6IRJ8BDuFHIFPL19ZBHUX9RtYluUCfRY84s3Cx+spLICqjeaVq4FLw3ssgAa8OrgWvOUCSMOv0KUqpTSWSFVN6fqJChLzEruivMu10QOWNny4DS18CXjTlEtONZwBv1I/U3ZTF/ZIuRe8dPpn4N2Srn1yrR0JUtUzCu+ObtXx1CJI4I/AQ6B7wkvUTi88DLo3/Cz+MLzFuNiaOizGydY+ZLXD9mRvmE4wCOgIiS+MmixT1kaI6EjwRO00XZsboKKjwffiP8C3Srzj7z1934I/TzEove75yJWzBlx8FjwiOmLVECfbom8N/pz26xfPlj/vX3IW3HQbhHGS8ciWNC7Br9DTK0daAET4xx/fnbh+33xN2S6cu+HDtaHgI8FH8Kg9Al9Me35YeS8AAnwOnhrV8KnEs+HjjXgtgCf8/d1htz/eVt+Y1QPfje6J7wVfS3neCiX8PPHD8B4LYA3fA97qehI+jI+zPxb1YwU/Al7o+rO3GrzF9GMBP4uejZYk/HTNlI4SrfRrwkuA1+omTfwJXqJmrBZAA14SvFY3pvDS9SMJrwVOpP5kHuHVakYz/VLw2ujUUwhu8BLj5yy8BXip51fwmv3eGk9HTsCj8JbgpZ6HgR/p/154L3Cq56Hge+unB94bPZ/nIeG5C8CBRwAvJd58omn1ffr3WvfX4JHAqRNsSDw0fC39FDwi+KbhqQXI4ZHR81l+M4mn6ifCo4P/F4lPF+Dq+5ee04X7tumLIptMfBC8un663Pz4dsI8/vrpjsrZgU3DB/D4E+Hjv9EXYJPwKXgJHj39m4On0ANynvj0cEdM/2bgS+C1xOddi7QAOXzYV/VXnzgnn9XEknR56bK1xCOmP4HfwT1X00p5CsqFRzn5QsL3gPdUDXW0eNUPHPwIeuvk2qo2D/wifNhZy1ehRsFnE+/R//lb+Vxec50Fl4S36v8SvNlkI4U+WzXW3Z/WTLhts/fVSIJrJF67fprw0j2vAa4NL10/1Fu1Vd+0qomuUTVa9ZOnPa8asZ7XBrdKvFT9sOFH68YK3AN+tH7UPxFijW5VNbP1w4U/1w039R7gnonvqZ+eD5+x4T3BUeBb9dML38RHQPesGqp+wu/S539S9P3xNnzSezVBdn2yGwUcLfFU/Yx8sjtez+odZmjoiImPcIe3n89rQaWdmuPzo+iEv3/zqnR0uf6+94UQq51N4E+f/s5rhg2Pio8In6a99n+PtL4oaHWiRUs+GjwXnZP4B/iOfpKGh8VHSnwPOjfxF1MOSuWgwPei98LDJR8BfgR9Ch5h0vGGz9C7PDlTDTnbx1961o4n/Ax61wpl+quvhPLC94KfRZ+BX/W9V+14wEugz8K741vDS6FLwLviW8JLokvBX8z5VtVjAS8NHrFGpprag2jTk642vBa6dOLJ5GumXwueABe3kk58ejRcfAup9NgpDW8BrlU1VA2pLYAUvCW4JfzF5CP1qHcWvgAuXitUGjWrhpX+mUUYga9gm4BbJ776fA+1QpzzAQe+Ae3mYJ340iha/Trw2vw6+Df3++2+AwSc1iJA3VeonWmkl7sgm7hP/wDwgcxktVR5CQAAAABJRU5ErkJggg==";

class IconsExample {
getInfo() {
return {
id: 'iconsexample',
name: 'Icons Example',
menuIconURI: blocksIcon,
blockIconURI: dangoIcon,
blocks: [
{
opcode: 'defaultIcon',
blockType: Scratch.BlockType.REPORTER,
text: 'reporter with default icon [INPUT]',
arguments: {
INPUT: {
type: Scratch.ArgumentType.STRING,
defaultValue: '0'
}
}
},
{
opcode: 'overriddenIcon',
blockType: Scratch.BlockType.COMMAND,
text: 'command with overridden icon [INPUT]',
blockIconURI: colorIcon,
arguments: {
INPUT: {
type: Scratch.ArgumentType.STRING,
defaultValue: '0'
}
}
}
]
};
}

defaultIcon() {
return 0;
}
overriddenIcon() {

}
}

Scratch.extensions.register(new IconsExample());

内联图像

你也可以使用类型为 IMAGE 的"参数"并在参数上设置 dataURI,在积木中的任何位置放置图像。与其他图像一样,这是一个 data: URL。首选 SVG,但至少 64x64 大小的 PNG 或 JPG 也能很好地工作。图标应该是方形的。

此外,如果你将 flipRTL 设置为 true,图像将在从右到左的语言中水平翻转。

inline-images.js - 尝试此扩展
// From the Pen Plus extension: https://github.com/TurboWarp/extensions/blob/master/extensions/penplus.js
const dangoIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABeCAYAAADc6BHlAAAAAXNSR0IArs4c6QAABItJREFUeF7tncuN2zAQhu0SctmCAuSQDnLZAlLCAjkG2BJSwF62gxwWSEG5pIQEFJYKRQ5f8+BzfLSoMfV/8yIl2/db+PrrvXUHxti3/LGJobeUndR5Sx9zRUmJWTquVCyF8a4UKOzj89Pt5em5VMxj3Idf34Pxfz5+y9nYHoQV4PR+I777ioGABM+pHQGyNYRqABjhfTAAiG0hRAH4ns8hvIIIc0RRcZUQ307Fi4btIiELQFJ8hXALevNLK9pC/N0h+CF/Amgp/s4QFECudxY+DtaAHt6/axQoAGEPz5kP1gE9vR+IguXb0tEBGCZLQ7gAGMH7jeI7Lc6GBOBB0AjIFRKJ404UKAAJgXM2dwLQdfUbA7ETAKPBAWGUIgwUYpfTUilpmCJccPsyFixTA+kOgCC8D2RKEN0AQMI//n7L1ebz+MvDpyUiostK2Be/RnhIdQDGNNHQFAC38C6MSEQMDyLYDZXqhCTFT4CYD4BUO+oCoKacXKHwomFoCOAdMe4oaCm+hTMLBPFbkj3EnwkCFJ5sWxM9xTcQZoiCWH5kgdAbwAwQsgAoRdkCkC66FUV5uIKcmhDpIa0RvH+GWpDzCDSEUbx/9DSUA3BuVbthnmtTR/J+IApKrjmX1diO10wG/ApT7psxvfP/SgDstdR8Me82IABzHTWOx+btkCHKRIpAKIA0PwoAyHIARQG0BXBJU6OIP3InxB0BQZ3oDSFx54w7JaNqxZIAKkXvemtzKQAp4b/8/BH10NfPX1PeK6XR8ZmSxo+C3CoFQeKnRI8pHoEhppOYYfuwlzQAX3iM6BAMAISIViJG3y/o/88fVDxuUlPJpMR35yANYloALcS3IDwIrJqxGgO8VywKXABcaScVfVIQpgTQWnzJSJAGYObOGgW9xJeC0AIAKwQLoEXaKeiOyPqRDRR2LZdNOmxr2tv7JaKgFYBLFGAXaL29f3YAJAijeD8AgeTEpJML048/DHXPYGAApC2dHgCCLWv7Rqo2jJJ+uNNQTwBBSoIiykJRAMh8U3ha0f1lY6tX+5lpSdGOjD6xUFjMsCQMBYCRlH7OCUUB0MXEWFAAGNWYzzkgaAQwq1phbigAXNvTIxbhGJNmAFxxYxG3LQDJNBR7OgKCoAAqclfJ0MyjKUHtccaTsgjp5JILYx4jloasoKn/T7CRwOX9pE0kZmFLzYm0o66gPgAzMfen/A2EnQGc+0ec7WgOgA/B8RZyBiEbKHVdxnFdoiACgawf2QCjsDWm2CH4RRhKRQAEsn5kAzWqMY69bNhxpaMeEGYFcNYCC3VWCDMDWALC7ACmh7ACAJuFWOpCakUsUZhXAhBEQ019yG1FWFvcEFYDAEYDsvtytbk+2ef93aO17/35XZG2RYOQFzDCacU3+wtWtyIQVgcQcwIjJuba2SFgJjGCZ/ecAysEBYBDyQZBAeAABB0XtjtSAHgALBAUAA0AGYICoAMgQVAAPADQEBQAHwAMhLsC4AVQBMHdslAA/ACyEBwAGgEy+h9WwcWav2GnESBIwIcAfJRGgKz+YST4u67/APKrBHxjStmdAAAAAElFTkSuQmCC";
const colorIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF4AAABeCAYAAACq0qNuAAAAAXNSR0IArs4c6QAABTFJREFUeF7t3b2KFEEUBeAecBVkk8nERBSMBEGMTDcxN/IhfATDRdinMDSaV5gn8REEo40MlBqoobrmVtWtqvtzWnYzd3tmer46ffrOr7tlOz9/mbu6Y27nuhniTnKBe+Gg7ivKzmhhlxbH/X577UAT+smnD81EP3r9vLnN/d2huc2yLOYO1jdYBOdA54Ic+PwyjYUw87C6IRJ8BDuFHIFPL19ZBHUX9RtYluUCfRY84s3Cx+spLICqjeaVq4FLw3ssgAa8OrgWvOUCSMOv0KUqpTSWSFVN6fqJChLzEruivMu10QOWNny4DS18CXjTlEtONZwBv1I/U3ZTF/ZIuRe8dPpn4N2Srn1yrR0JUtUzCu+ObtXx1CJI4I/AQ6B7wkvUTi88DLo3/Cz+MLzFuNiaOizGydY+ZLXD9mRvmE4wCOgIiS+MmixT1kaI6EjwRO00XZsboKKjwffiP8C3Srzj7z1934I/TzEove75yJWzBlx8FjwiOmLVECfbom8N/pz26xfPlj/vX3IW3HQbhHGS8ciWNC7Br9DTK0daAET4xx/fnbh+33xN2S6cu+HDtaHgI8FH8Kg9Al9Me35YeS8AAnwOnhrV8KnEs+HjjXgtgCf8/d1htz/eVt+Y1QPfje6J7wVfS3neCiX8PPHD8B4LYA3fA97qehI+jI+zPxb1YwU/Al7o+rO3GrzF9GMBP4uejZYk/HTNlI4SrfRrwkuA1+omTfwJXqJmrBZAA14SvFY3pvDS9SMJrwVOpP5kHuHVakYz/VLw2ujUUwhu8BLj5yy8BXip51fwmv3eGk9HTsCj8JbgpZ6HgR/p/154L3Cq56Hge+unB94bPZ/nIeG5C8CBRwAvJd58omn1ffr3WvfX4JHAqRNsSDw0fC39FDwi+KbhqQXI4ZHR81l+M4mn6ifCo4P/F4lPF+Dq+5ee04X7tumLIptMfBC8un663Pz4dsI8/vrpjsrZgU3DB/D4E+Hjv9EXYJPwKXgJHj39m4On0ANynvj0cEdM/2bgS+C1xOddi7QAOXzYV/VXnzgnn9XEknR56bK1xCOmP4HfwT1X00p5CsqFRzn5QsL3gPdUDXW0eNUPHPwIeuvk2qo2D/wifNhZy1ehRsFnE+/R//lb+Vxec50Fl4S36v8SvNlkI4U+WzXW3Z/WTLhts/fVSIJrJF67fprw0j2vAa4NL10/1Fu1Vd+0qomuUTVa9ZOnPa8asZ7XBrdKvFT9sOFH68YK3AN+tH7UPxFijW5VNbP1w4U/1w039R7gnonvqZ+eD5+x4T3BUeBb9dML38RHQPesGqp+wu/S539S9P3xNnzSezVBdn2yGwUcLfFU/Yx8sjtez+odZmjoiImPcIe3n89rQaWdmuPzo+iEv3/zqnR0uf6+94UQq51N4E+f/s5rhg2Pio8In6a99n+PtL4oaHWiRUs+GjwXnZP4B/iOfpKGh8VHSnwPOjfxF1MOSuWgwPei98LDJR8BfgR9Ch5h0vGGz9C7PDlTDTnbx1961o4n/Ax61wpl+quvhPLC94KfRZ+BX/W9V+14wEugz8K741vDS6FLwLviW8JLokvBX8z5VtVjAS8NHrFGpprag2jTk642vBa6dOLJ5GumXwueABe3kk58ejRcfAup9NgpDW8BrlU1VA2pLYAUvCW4JfzF5CP1qHcWvgAuXitUGjWrhpX+mUUYga9gm4BbJ776fA+1QpzzAQe+Ae3mYJ340iha/Trw2vw6+Df3++2+AwSc1iJA3VeonWmkl7sgm7hP/wDwgcxktVR5CQAAAABJRU5ErkJggg==";

class InlineImagesExample {
getInfo() {
return {
id: 'inlineimagesexample',
name: 'Inline Images Example',
blocks: [
{
opcode: 'reporter',
blockType: Scratch.BlockType.REPORTER,
text: 'some text [IMAGE] more text',
arguments: {
IMAGE: {
type: Scratch.ArgumentType.IMAGE,
dataURI: dangoIcon
}
}
},
{
opcode: 'command',
blockType: Scratch.BlockType.COMMAND,
blockIconURI: colorIcon,
text: 'some text [IMAGE] more text',
arguments: {
IMAGE: {
type: Scratch.ArgumentType.IMAGE,
dataURI: dangoIcon,
flipRTL: true
}
}
}
]
};
}

reporter() {
return 'Example block';
}
command() {

}
}

Scratch.extensions.register(new InlineImagesExample());

分隔符

如果你的扩展有很多积木,你可能想在积木组之间放一些空格。要做到这一点,应在 blocks 列表中加入 "---"

separators.js - 尝试此扩展
class SeparatorExample {
getInfo() {
return {
id: 'separatorexample',
name: 'Separator Example',
blocks: [
{
opcode: 'block1',
blockType: Scratch.BlockType.COMMAND,
text: 'group 1'
},
{
opcode: 'block2',
blockType: Scratch.BlockType.COMMAND,
text: 'also group 1',
},
'---',
{
opcode: 'block3',
blockType: Scratch.BlockType.COMMAND,
text: 'group 2'
},
'---',
{
opcode: 'block4',
blockType: Scratch.BlockType.COMMAND,
text: 'group 3',
},
]
};
}
block1() {}
block2() {}
block3() {}
block4() {}
}

Scratch.extensions.register(new SeparatorExample());

终端积木

要防止在 COMMAND 积木下方连接积木,请在积木上设置 isTerminal: true

虽然积木的形状看起来类似于"停止此脚本"和"停止全部",但其行为与两者都不匹配。例如,如果此积木放在循环末尾,循环将继续运行,除非其他代码停止当前线程。这只是防止在下方连接积木。

terminal.js - 尝试此扩展
class TerminalExample {
getInfo() {
return {
id: 'terminalexample',
name: 'Terminal Example',
blocks: [
{
opcode: 'terminalBlock',
blockType: Scratch.BlockType.COMMAND,
isTerminal: true,
text: 'you can not connect another block under this one!'
}
]
};
}
terminalBlock() {

}
}

Scratch.extensions.register(new TerminalExample());

下一步

接下来,让我们看看如何制作像"当我收到"或"当计时器大于"这样的积木。