
如何写出自己的KittenBlock扩展以ps2-controller为例从Blockly积木到Python代码生成全解【免费下载链接】ps2-controller源师兄扩展项目: PS2 | 由源师兄组织创建项目地址: https://gitcode.com/yuanshixiong/ps2-controller本文以 ps2-controller 项目为例完整拆解如何写一个KittenBlock 扩展它用 Blockly 积木定义“PS2手柄”积木分类让 PS2 无线手柄接入大师兄板用户拖拽积木即可自动生成完整的 Python 驱动代码。掌握下面这 3 个文件你就能从零搭建自己的“积木 → 代码生成”流水线。一、扩展全貌3 个文件构成完整扩展 文件作用config.json扩展元信息目标设备、名称、简介、帮助链接category.json积木分类分类名、统一颜色、包含哪些积木blocksdef.js核心积木的 UI 定义 Python 代码生成逻辑想查看完整源码先克隆仓库git clone https://gitcode.com/yuanshixiong/ps2-controller二、第 1 步config.json 声明扩展元信息config.json 的内容只有寥寥几行{ Device: 大师兄板, Name: PS2手柄, Description: PS2无线手柄 I2C 驱动与积木块 }Device声明扩展运行的目标开发板KittenBlock 编辑器据此加载对应扩展Name是积木面板里显示的分类名HelpUrl指向该扩展的帮助文档地址。三、第 2 步category.json 定义“PS2手柄”分类category.json 声明了一个紫色的积木分类并列出分类下的 3 个积木{ kind: CATEGORY, name: PS2手柄, colour: #9B59B6, contents: [ { kind: BLOCK, type: ohcode_extend_ps2_i2c_init }, { kind: BLOCK, type: ohcode_extend_ps2_i2c_button_pressed }, { kind: BLOCK, type: ohcode_extend_ps2_i2c_get_axis } ] }两个关键点colour决定了分类颜色ps2-controller 选用紫色#9B59B6contents中每个type都必须与 blocksdef.js 里定义的积木名一字不差地对应这是新手最容易踩的坑。四、第 3 步blocksdef.js 写积木定义与代码生成 扩展里的每块积木都有“双胞胎”Blockly 定义Blockly.Blocks[积木名]决定积木长什么样、能接什么代码生成器pythonGenerator.forBlock[积木名]决定生成代码时输出什么 Python。4.1 语句积木手柄(I2C) 初始化blocksdef.js 定义了一个无输入参数的语句积木this.setPreviousStatement(true, null); // 上方可拼接 this.setNextStatement(true, null); // 下方可拼接 this.setColour(#9B59B6);它的代码生成部分比较特别见 blocksdef.js。由于完整的PS2I2C驱动类很长按键位映射表、I2C 读取、缓存逻辑ps2-controller 不把它内联到积木里而是注入到pythonGenerator.definitions_definitions_[ps2_i2c_driver]PS2I2C类的完整源码definitions_[ps2_i2c_init]一句实例化代码ps2 PS2I2C()。definitions_是 Python 生成器的“延迟注入”机制——最终拼代码时自动把这些定义放到文件顶部并去重。所以哪怕用户拖多个初始化积木驱动类也只会在脚本里出现一次。4.2 值积木按键是否按下检测blocksdef.js 用下拉菜单让用户在 16 个按键中选择this.appendField(new Blockly.FieldDropdown([ [↑, UP], [△, TRIANGLE], [○, CIRCLE], [□, SQUARE], [START, START], ... ]), KEY); this.setOutput(true, Boolean);setOutput让它成为可插进if判断或变量赋值的值积木。生成器只有两行const key block.getFieldValue(KEY) || UP; return [ps2.is_button_pressed(${key}), pythonGenerator.ORDER_ATOMIC];ORDER_ATOMIC告诉生成器这个表达式优先级最高外面不需要加括号。4.3 值积木摇杆数值读取思路与按键检测完全相同只是把下拉选项换成 4 个摇杆轴输出类型改为Number见 blocksdef.jsreturn [ps2.get_axis(${axis}), pythonGenerator.ORDER_ATOMIC];返回值范围是 0~255128 左右即摇杆回中位置。五、最终生成的 Python 代码长什么样 用户把 3 块积木拼好后生成的脚本大致是from machine import I2C, Pin import time # ... PS2I2C 驱动类由 definitions_ 自动注入 ps2 PS2I2C() while True: if ps2.is_button_pressed(CROSS): pass # 前进 speed ps2.get_axis(LX)驱动类内部的几个要点I2C 设备地址为0x13按键数据在寄存器0xBB每次读取 6 字节_BUTTON_MAP把按键名映射到字节偏移位编号位值为 0 表示“按下”_ensure_data()带 10ms 缓存循环里连读多个按键实际只触发一次 I2C 读取避免总线被刷屏。六、写扩展的 5 条经验清单 ✅命名对齐blocksdef.js 的积木名与 category.json 的type必须一字不差颜色统一积木setColour与分类colour保持一致写好 tooltipsetTooltip是用户的“第一份文档”不能省值积木必须声明输出类型Boolean/Number否则无法插入其他积木长代码放definitions_驱动类、import 等公共内容走延迟注入避免重复输出。七、小结KittenBlock 扩展的编写流程可以浓缩为一句话config.json 声明设备 → category.json 划分类 → blocksdef.js 定义积木外观与代码生成。ps2-controller 用 3 个文件就给出了一个可参考的完整范例换个驱动和下拉选项同样的方法就能为你的任意外设写出自己的 KittenBlock 积木扩展。【免费下载链接】ps2-controller源师兄扩展项目: PS2 | 由源师兄组织创建项目地址: https://gitcode.com/yuanshixiong/ps2-controller创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考