跳到主要内容

进阶积木 API 用法

一次性添加/删除积木

ClipCC 提供一次性添加/删除积木的支持。 你可以使用 api.addBlocks(blocks: BlockPrototype[])api.removeBlocks(blocksOpcode: string[]) 来实现它们。

显示条件

ClipCC 从 3.1.4 开始提供对积木显示条件的支持。 以下是一个示例:

api.addBlock({
opcode: 'example.block',
type: type.BlockType.COMMAND,
messageId: 'example.block',
categoryId: 'example.category',
function: () => {...},
option: {
// 仅在舞台中显示
filter: type.FilterType.STAGE
}
});

对于更多积木选项, 请查看 BlockPrototype - BlockOption

菜单

ClipCC 从 3.1.2 开始提供对菜单输入的支持。正确定义菜单的方式是在 parameter 属性内定义包含菜单项的menu属性。

菜单

param: {
PARAMETER: {
type: type.ParameterType.STRING,
menu: [{
messageId: 'example.extension.menu.type',
value: 'type'
}, {
messageId: 'example.extension.menu.rainbow',
value: 'rainbow'
}, {
messageId: 'example.extension.menu.zoom',
value: 'zoom'
}],
default: 'rainbow'
}
}

动态菜单

caution

以下所涉及的扩展API能处于草案阶段,所涉及的内容可能在未来被修改。

param: {
PARAMETER: {
type: type.ParameterType.STRING,
menu: () => {
// 返回当前所有角色
const vm = api.getVmInstance();
const sprites = [];
for (const targetId in vm.runtime.targets) {
if (!vm.runtime.targets.hasOwnProperty(targetId)) continue;
const name = vm.runtime.targets[targetId].sprite.name;
sprites.push([name, name]);
}
return sprites;
},
default: 'rainbow'
}
}

如果你想定义一个不可动态输入的菜单, 那么你可以将field 属性设置为 true.

param: {
PARAMETER: {
type: type.ParameterType.STRING,
default: 'something',
field: true,
menu: [...]
}
},

帽状积木

这个简单的实例阐述了如何定义一个 HAT 类型的积木:

api.addBlock({
opcode: 'example.hat',
type: type.BlockType.HAT,
messageId: 'example.hat',
categoryId: 'example.category',
param: {
CONDITION: {
type: type.ParameterType.BOOLEAN
}
},
function: (args) => {
if (!!hasReported) {
window.hasReported = false;
return false;
}
const result = !!args.CONDITION;
if (result) {
hasReported = true;
return true;
}
return false;
}
});

当积木被拖拽至工作区后,项目会进入“假”运行状态(绿旗高亮,但没有脚本被触发)。编辑器每帧都会检查该 HAT 是否被触发。只有当上一帧返回false且当前帧返回true时积木才会正常被调用。

树状积木

ClipCC 从 3.1.4 开始提供对树状积木的支持。以下是一个定义树状积木的定义:

index.js
api.addBlock({
opcode: 'example.if',
type: type.BlockType.COMMAND,
messageId: 'example.if',
categoryId: 'example.category',
branchCount: 1,
param: {
COND: {
type: type.ParameterType.BOOLEAN
}
},
function: (args, util) => {
// If the condition is true, start the branch.
if (!!args.COND) util.startBranch(1, false);
}
});
en.json
{
"example.if": "if [COND] [SUBSTACK]"
}

  你需要在 BlockPrototype 中指定 "branchCount", 它意味着树状积木的分支数量。 你还需要在语言文件中以 [SUBSTACKX] 的命名方式定义分支参数。   对于一个树状积木, 你可以通过 util 对象中的 startBranch 方法来进行流程控制。

/**
* 在当前积木下触发某个分支
* @param {number} branchNum 触发分支的编号 (i.e., 1, 2).
* @param {boolean} isLoop 这个分支是否是一个循环
*/
startBranch (branchNum, isLoop) {...}

isLoop 参数被设为 true 时, 积木将被重复调用,直到startBranch 不再被触发。当被设为 false 时, 当前积木将被立刻跳出。 当branchNum参数未被指定时, 默认为1。这里有一个关于流程控制的 更为详细的范例.

编写这类积木通常需要对线程和调度器进行修改, 所以你需要对 Scratch/ClipCC 的代码具有一定程度上的理解。通常情况下,我们不推荐你定义这类积木。