CodeBlock 26.2
当前维护版本,包含最新的多窗口与编辑器功能。
推荐不离开游戏,改完就能看到结果。
程序每个 tick 跑一次,20 次/秒。读取相邻方块朝它发出的信号,把结果从任意面输出。
直接写完整的 Java 类,游戏内编译后运行;需要更多编译能力时可以配合 ECJ 模组。
改完代码不用退出世界,方块会按设定的间隔重新加载程序,调试红石时序很方便。
可以执行命令、读写记分板、发送可点击消息,把红石逻辑接到服务器玩法里。
主画面之外可以再开一个窗口,投放副画面或实时内容,不抢主画面焦点。
按游戏版本选择。下载包为官网直链,点开即可下载。
当前维护版本,包含最新的多窗口与编辑器功能。
推荐旧版本,仍可下载回退。后续新功能只做 26.2。
给用 JRE 启动游戏的玩家补充 Java 编译能力,可装可不装。
国内网络更稳,历史版本也保留在这里。
镜像源码与发布记录都在 Gitee。
红石 I/O、状态与等待、消息音效、文件命名、多窗口与 execute 用法。
把主画面 / HUD / F3 复刻到独立窗口
除了游戏主窗口,还能再开若干独立窗口,把主画面、HUD 特写或 F3 调试文字复刻进去,用来做分屏监视。窗口 API 挂在 CodeContext 上,只能写在 .java 程序里(.codescript 没有对应语法)。仅 26.2 线(v0.1.1 起)提供;1.21.11 线已停更,没有这些方法。
| 类型 | 说明 |
|---|---|
| 内置单窗口 | 固定 400×300 的副窗口,按预设或贴图集显示内容,用 renderSecondWindow() / setSecondWindowSource(String) 控制。 |
| 可配置多窗口 | 任意多个独立窗口,可设尺寸、坐标、背景色、标题与文字,支持拖动缩放、Alt+Enter 全屏、实时镜像 / HUD 特写 / 快照。所有方法第一个参数都是窗口 id。 |
| 方法 | 说明 |
|---|---|
void renderSecondWindow() | 请求重画一次内置窗口内容(改了显示源或贴图后调用)。 |
void setSecondWindowSource(String source) | 设置内置窗口显示源,取值见下表。传 null 回到默认图集。 |
void setSecondWindowPresetEnabled(boolean on) | 按当前界面自动切换预设画面;开启时会清掉手动设置的内置窗口显示源。 |
void setLipColor(int r, int g, int b, int a) | 给内置窗口画面叠一层颜色(0–255)。 |
void clearLipColor() | 取消颜色叠加。 |
| source | 说明 |
|---|---|
"blocks"(默认) | 石头 / 泥土 / 橡木板 / 铁块 / 玻璃 / 苔石 6 种方块贴图组成的图集。 |
"ui" | 原版 GUI 贴图图集(物品栏、熔炉、成就背景等)。 |
"screenshot" | 实时截取主画面(按固定间隔抓帧)。 |
预设模式按当前界面自动切换:物品栏(inv)、暂停菜单(pause)、死亡界面(death)、标题界面(title)、游戏内无界面(world)。
| 方法 | 说明 |
|---|---|
String createSecondWindow(String id, int w, int h, int x, int y, boolean closable, boolean fullscreenCap, boolean resizable, boolean focusable) | 创建窗口,返回 id;id 已存在返回原 id,参数非法返回空字符串。宽高最小 32px,x/y 是屏幕左上角坐标。closable=允许点 × 关,fullscreenCap=允许 Alt+Enter 全屏,resizable=允许拖拽缩放,focusable=创建后抢焦点(false 则后台创建,MC 不掉焦点)。 |
boolean hasSecondWindow(String id) | 窗口是否已经创建完成。创建是异步的,刚调 createSecondWindow 的同一刻可能还是 false。 |
void resizeSecondWindow(String id, int w, int h) | 改尺寸(最小 32×32)。 |
void moveSecondWindow(String id, int x, int y) | 移到屏幕坐标,比关掉重建轻得多。 |
void toggleSecondWindowFullscreen(String id) | 全屏 / 窗口化切换,仅 fullscreenCap=true 时生效。 |
void setSecondWindowColor(String id, float r, float g, float b, float a) | 清屏背景色,每个分量 0.0–1.0。 |
void setSecondWindowTitle(String id, String title) | 标题栏文字,自动去掉 § 颜色码;内容相同不会重复调用。 |
void setSecondWindowText(String id, String text) | 窗口内显示文字,支持 § 颜色码,超出宽度自动换行。 |
void setSecondWindowTextEx(String id, String text, int fontSize, int anchorX, int anchorY, int baseColor, int posX, int posY) | 完整版:文字 + 字号 + 九宫格位置 + 基础色 + 像素坐标,参数含义见下表。 |
void setSecondWindowTextPos(String id, int posX, int posY) | 只改文字像素坐标,-1 表示回到九宫格定位。 |
void setSecondWindowSource(String id, String source) | 设置显示源,默认每 10 帧抓一次。 |
void setSecondWindowSource(String id, String source, int interval) | 同上,interval 为每多少帧抓一次(1=每帧最流畅最吃资源,越大越省)。 |
void clearSecondWindow(String id) | 清掉文字与画面,恢复纯背景色;窗口本身不关闭。 |
void closeSecondWindow(String id) | 关闭窗口。脚本主动关闭总是允许,不受 closable 限制。 |
| source | 说明 |
|---|---|
""(默认) | 纯背景色 + 文字。 |
"screen" | 实时镜像主窗口画面,3D 世界与任意界面(原版 / 模组 GUI)都能复刻;按 interval 节流抓帧。 |
"snapshot" | 抓一帧后定格(内部自动切回 "",画面保留);要停止显示用 clearSecondWindow。 |
"hud" | HUD 特写:只保留快捷栏、血量、饥饿、护甲、经验条(元素级白名单),黑底居中按比例显示。 |
| 参数 | 说明 |
|---|---|
fontSize | 像素字高,最小 8;传 -2 为自动字号(窗口高 / 12,窗口越大字越大)。 |
anchorX | 0=左 1=中 2=右。 |
anchorY | 0=上 1=中 2=下。 |
baseColor | 基础色,格式 0xAARRGGBB;文字里写 § 颜色码会覆盖它。 |
posX / posY | 像素坐标定位;-1 表示跟随九宫格锚点。 |
| 方法 | 说明 |
|---|---|
void setSuppressMainRender(boolean on) / boolean isSuppressMainRender() | 把主窗口画面替换成纯黑(游戏照常运行),用于只想看小窗的场合;开启期间指向主画面的镜像窗也会一起变黑。 |
void setSuppressWindow(String id, boolean on) / boolean isWindowSuppressed(String id) | 让指定窗口只画背景色、跳过内容渲染(变黑),窗口不关闭。 |
String getF3Text() | 取当前 F3 调试文本:每行用 \n 分隔,左右两栏用 | 连接。没有 F3 内容时是空串。 |
boolean hasF3Content() | 当前有没有可用的 F3 文本(F3 未打开时为 false)。 |
void setF3MainSuppressed(boolean on) | 主窗口不显示 F3 覆盖层,只在小窗里看。 |
public void onTick(CodeContext ctx, long tick) {
// 主画面镜像:640×480,可关 / 可全屏 / 可缩放,后台创建不抢焦点
if (!ctx.hasSecondWindow("mirror")) {
ctx.createSecondWindow("mirror", 640, 480, 40, 40,
true, true, true, false);
ctx.setSecondWindowTitle("mirror", "主画面镜像");
ctx.setSecondWindowColor("mirror", 0.1f, 0.12f, 0.16f, 1f);
ctx.setSecondWindowSource("mirror", "screen", 10); // 每 10 帧抓一帧
}
// HUD 特写:只显示快捷栏 / 血量 / 饥饿 / 护甲 / 经验条
if (!ctx.hasSecondWindow("hud")) {
ctx.createSecondWindow("hud", 320, 180, 700, 40,
false, true, false, false);
ctx.setSecondWindowSource("hud", "hud", 4);
ctx.setSecondWindowTextEx("hud", "§bCodeBlock", -2, 1, 2, 0xFFFFFFFF, -1, -1);
}
// 每 5 秒把 F3 文本刷进第三个窗口
if (tick % 100 == 0) {
if (!ctx.hasSecondWindow("f3")) {
ctx.createSecondWindow("f3", 420, 300, 40, 540,
true, false, true, false);
}
if (ctx.hasF3Content()) {
ctx.setSecondWindowText("f3", ctx.getF3Text());
}
}
ctx.sleepTicks(20); // 别空转占核
}
onTick 里调即可。不要自己开线程或用 LWJGL 直接碰 GL 上下文。
focusable=false 创建的窗口只做监视,不影响操作。窗口尺寸、位置改了之后镜像纹理会按新尺寸自动重建;拖动窗口期间抓屏会自动暂停。
写任何代码方块程序,第一行必须先引入下面两个库,否则编译器找不到接口、直接报错。
import codeblockmod.api.CodeBlockProgram;
import codeblockmod.api.CodeContext;
| 库 | 作用 |
|---|---|
codeblockmod.api.CodeBlockProgram | 程序入口接口。你写的类必须 implements CodeBlockProgram,并实现它的 onTick(CodeContext ctx, long tick) 方法——这是代码方块运行你程序的唯一入口。 |
codeblockmod.api.CodeContext | 上下文接口。onTick 拿到的 ctx 就是它的实例,所有 API(红石读写、状态存储、消息、音效、命令、数组等)都挂在 ctx 上调用。 |
BlockPos、Level 等)只有在你手动用到时才需要额外 import,积木生成的代码不会用到。O、右键方块重载。
你的 onTick 跑在后台守护线程里,不阻塞服务端主线程。
ctx 里凡是触碰世界的操作(读红石、写输出、发消息、放音)都会自动经
runOnMain() 调度回服务端主线程执行,所以你不需要自己加锁或调度,
直接在 onTick 里调用即可。
| 通道 | 方向 | 说明 |
|---|---|---|
0 | 下 DOWN | 方块底面 |
1 | 上 UP | 方块顶面 |
2 | 北 NORTH | —Z 方向 |
3 | 南 SOUTH | +Z 方向 |
4 | 西 WEST | —X 方向 |
5 | 东 EAST | +X 方向 |
| 方法 | 说明 |
|---|---|
int readInput(int channel) | 读某面外部输入的红石强度(0–15)。已排除本方块自身在该面发出的信号,避免自激。 |
void writeOutput(int channel, int value) | 向某面输出强度,自动 clamp 到 0–15。 |
int readInputMax() | 返回 6 个面中最大的输入强度。 |
void writeOutputAll(int value) | 6 个面同时输出相同强度(自动 clamp)。 |
String debugInputs() | 返回 6 个方向当前输入的可读字符串。接线不确定时用它确认拉杆/压力板到底接在哪一面。已实现 |
readInput 只排除本方块自身发射量,排除不了同一段红石线的反射。
public void onTick(CodeContext ctx, long tick) {
int v = ctx.readInput(4); // 读西面
ctx.writeOutput(5, v >= 8 ? 15 : 0); // 东面:够强就满输出
}
计数器、计时器、延时
| 方法 | 说明 |
|---|---|
int getStateInt(String key) | 读取跨 tick 持久化的整数状态(计数器/计时器/标志位)。key 不存在返回 0。 |
void setState(String key, int value) | 写入整数状态。每个代码方块有自己独立的状态表。 |
void sleepTicks(long n) | 真阻塞 n 个游戏 tick(1 tick ≈ 50ms),期间让出 CPU。用于延时/降频。 |
void sleep(long millis) | 真阻塞指定毫秒。在 while(true) 里用它让出 CPU 降频。 |
public void onTick(CodeContext ctx, long tick) {
int n = ctx.getStateInt("count");
ctx.setState("count", n + 1);
ctx.writeOutput(5, n % 16); // 0–F 循环输出
ctx.sleepTicks(20); // 约 1 秒一次,同时让出 CPU
}
while(true) 里如果没有
sleepTicks() 或 sleep(),会纯空转占满一个 CPU 核心(看门狗只会打日志,不会帮你停)。
跟玩家沟通
| 方法 | 说明 |
|---|---|
void sendMessage(String text) | 聊天框发一条消息,方圆 64 格内玩家可见。支持 § 颜色码。同文本 1 秒内去重。 |
void sendClickable(String text, String url) | 可点击消息(悬停下划线)。以 http 开头=打开链接,否则当作 MC 命令执行。3 秒去重。 |
void playSound(String soundId) | 播放原版音效,方圆 16 格可听到。例:block.note_block.harp、entity.player.levelup。ID 无效时回退竖琴音。 |
void sendActionBar(String text) | 物品栏上方短暂文字(Action Bar),约 3 秒消失。 |
void sendTitle(String text) | 屏幕中央大标题。 |
ctx.sendClickable("§b点我打开文档", "https://jky.ccwu.cc/codeblock.html#docs");
ctx.sendClickable("§a点我回到出生点", "/spawn");
播放你自己的 mp3 / wav / ogg
音频文件放在存档目录的 res/media/ 下,用文件名直接播放(流式 SourceDataLine,mp3 已内置解码)。
| 方法 | 说明 |
|---|---|
void playAudio(String filename, float volume) | 播放 res/media/ 下的音频。调一次播一次,次数完全由你的代码决定。音量 >1 视为百分比(100=满音量),否则按 0.0–1.0。 |
void stopAudio() | 停止该方块正在播放的所有自定义音频。 |
void stopAudio(String filename) | 停止指定文件名的音频。 |
ctx.playAudio("ding.mp3", 80); // 80% 音量
// ...
ctx.stopAudio("ding.mp3"); // 只停这一首
| 路径 / 文件 | 用途 |
|---|---|
<存档>/res/program/ | 程序目录(随存档走) |
CB_<名字>.java | Java 源码(游戏内 javac 实时编译;JRE 用户需装 ECJ 附加模组) |
CB_<名字>.class | 编译产物。存在且不旧于源码时直接加载、跳过编译(编译缓存) |
CB_<名字>.codescript | 零依赖 DSL 脚本(记事本即可写,无需编译器) |
CB_<名字>.blocks | Blockly 图形积木 XML,供图形编辑器还原 |
<存档>/res/media/ | 音频文件(playAudio 从这里取) |
block1 → 代码文件固定为 CB_block1.java,名字与代码绑定。CB_<旧名>.* 文件,并自动改写 .java 里的类名、删除陈旧 .class(下次编译重建)。CB_<名字>.java。res/program/。代码 API 与编辑器积木完整参考
本页分两部分:① 代码 API(直接写 Java 用的方法清单)、② 编辑器积木(图形化拖拽对应的积木清单)。两者一一对应。
名单不用显式创建:arrayAdd("名单名", "值") 发现 key 不存在就自动建空数组,跨 tick 持久化,key 支持中文。
| 方法 | 用途 |
|---|---|
void arrayAdd(key, v) | 往名单末尾加一个值,允许重复。 |
void arrayAddOnce(key, v) | 只在名单里没有这个值时才加(去重),最常用于"白名单/已领奖名单"。 |
void arrayRemove(key, v) | 从名单里删掉第一个匹配的值。 |
void arrayClear(key) | 清空整个名单。 |
int arraySize(key) | 名单里有几个元素。 |
String arrayGet(key, i) | 取第 i 个元素(从 0 开始数),越界返回空字符串。 |
int arrayFind(key, v) | 找这个值在第几位(0 起),找不到返回 -1。判断"在不在名单里"就用 arrayFind(...) >= 0。 |
String arrayJoin(key, sep) | 把名单所有元素用分隔符拼成一个字符串,方便 sendMessage 打印。 |
void setString(key, v) / String getString(key) | 存/取单个字符串状态(不是数组,就是一个 key→一个字符串)。 |
arrayFind("vip", playerName) >= 0 一行搞定,无需建 objective。
行 × 列的表格,存成绩表 / 配置矩阵。同样用 key 自动创建。编辑器里「创建二维数组」积木直接填行数和列数,下面自动长方格。
| 方法 | 用途 |
|---|---|
void array2DSet(key, r, c, v) | 写第 r 行第 c 列(都从 0 起),行/列不够自动补空行。 |
String array2DGet(key, r, c) | 读第 r 行第 c 列,越界返回空字符串。 |
int array2DRows(key) / int array2DCols(key) | 表格有几行 / 几列。 |
int array2DFind(key, v) | 全表找这个值在第几行,找不到 -1。 |
String array2DRowJoin(key, r, sep) | 把某一行用分隔符拼成字符串。 |
void array2DClear(key) | 清空整张表。 |
| 方法 | 用途 |
|---|---|
boolean inputChanged(channel) | 某一面的红石值跟上一次比有没有变。按钮去抖用这个——按下瞬间变一次返回 true,按住不放持续返回 false。 |
boolean valueChanged(key, value) | 通用边沿检测:跟上次同 key 记录的值比,变了返回 true。不限红石,任意整数都行(比如变量、计算结果)。 |
监听玩家右键交互,不靠"谁离得近"猜——多人围在一起时,只有真正按下去的人会被记到。
| 方法 | 用途 |
|---|---|
String whoUsed(dx, dy, dz) | 谁最后按过相对本方块 (dx,dy,dz) 处的方块。按钮在西面一格 → whoUsed(-1,0,0)。默认只认 1 秒内的操作。 |
String whoUsed(dx, dy, dz, withinTicks) | 同上,自定义时间窗(tick 数);0 或负数=不限时间。 |
String whoUsedNearby(radius) | 不想算坐标时用:半径内最近交互过的人。 |
String nearestPlayer() / nearestPlayer(r) | 兜底:最近的玩家名。 |
int playerCount() | 当前在线玩家数。 |
所有命令都在最高权限下跑——服务器关了命令、玩家不是 OP 也能执行。位置默认在方块中心。
| 方法 | 用途 |
|---|---|
void executeCommand(cmd) | 执行一条命令。/execute 的各种子命令(if/as/at/store 等)直接写在 cmd 字符串里即可,无需专门 API。 |
void executeCommandAs(player, cmd) | 以指定玩家身份执行,命令里的 @s 指向他,仍最高权限。 |
int executeCommandResult(cmd) | 执行并拿到返回值:0=失败/条件不成立,1=成功,其他=命令本身的返回值(如 /list 人数、data get 取到的数)。 |
boolean executeCommandTest(cmd) | 等价于 executeCommandResult(cmd) > 0,专门给 /execute if 条件判断用,放进 if 更顺手。 |
int executeCommandResultAs(player, cmd) | 以玩家身份执行并取返回值。 |
需要存数值(如金币数、击杀数)时用。目标不存在时自动创建 dummy 目标,开箱即用。纯判断"在不在组里"用字符串数组更简单,不必用记分板。
| 方法 | 用途 |
|---|---|
int getScore(objective, player) | 读某玩家在某记分板目标上的分数,查不到返回 0。 |
void setScore(objective, player, v) | 直接设分数。 |
void addScore(objective, player, delta) | 加/减分数(负数即减)。 |
积木按工具箱分类排列,每个积木的 Java 生成代码在括号里标注。
| 积木 | 用途 |
|---|---|
| 读取某面强度 | ctx.readInput(面),0-15。 |
| 读取所有面最大值 | ctx.readInputMax()。 |
| 输入变化? | ctx.inputChanged(面),边沿检测,按钮去抖。 |
| 值变化? 键 □ 当前值 □ | ctx.valueChanged(key, value),通用边沿检测(任意整数)。 |
| 输出到 □ 强度 □ | ctx.writeOutput(面, 值)。 |
| 向所有面输出 □ | ctx.writeOutputAll(值)。 |
| 调试: 打印所有输入 | 聊天框打印 6 个面的红石强度,排查接线用。 |
| 积木 | 用途 |
|---|---|
| 执行命令 □ | ctx.executeCommand(cmd),原始执行任意命令。 |
| 以玩家 □ 身份执行命令 □ | ctx.executeCommandAs(玩家, cmd),@s 指向该玩家。 |
| 命令成立? □ | ctx.executeCommandTest(cmd),execute 条件判断,返回真/假。 |
| 执行命令 □ 取结果 | ctx.executeCommandResult(cmd),拿返回值(数字)。 |
| 以玩家 □ 执行命令 □ 取结果 | ctx.executeCommandResultAs(玩家, cmd)。 |
| execute 若方块 相对 x y z 是 □ 则运行 □ | execute if block ~x ~y ~z 方块 run cmd。 |
| execute 若存在实体 □ 则运行 □ | execute if entity 选择器 run cmd。 |
| execute 若不存在实体 □ 则运行 □ | execute unless entity 选择器 run cmd。 |
| execute 若实体 □ 槽位 □ 含物品 □ 则运行 □ | execute if items entity 选择器 槽位 物品 run cmd。 |
| execute 若谓词 □ 成立 则运行 □ | execute if predicate 谓词 run cmd。 |
| execute 以 □ 身份 在其位置运行 □ | execute as 选择器 at @s run cmd,as+at 合体。 |
| execute 以 □ 身份运行 □ | execute as 选择器 run cmd,只改执行者。 |
| execute 在 □ 位置运行 □ | execute at 选择器 run cmd,只改位置。 |
| execute 在坐标 x y z 运行 □ | execute positioned x y z run cmd。 |
| execute 存结果到 玩家 □ 记分板 □ 运行 □ | execute store result score 玩家 目标 run cmd。 |
| execute 若 玩家 □ 记分板 □ 比较符 □ 值 □ 则运行 □ | execute if score 玩家 目标 比较符 值 run cmd,记分板条件。 |
| execute 若玩家 □ 在名单 □ 里 则运行 □ | 字符串数组做白名单判断(替代记分板)。 |
| execute 若名单 □ 包含 □ 则运行 □ | 通用版,值不限玩家名。 |
| execute 若名单 □ 不包含 □ 则运行 □ | 反向判断(黑名单)。 |
| 对名单 □ 中每个元素存入变量 □ 执行 □ | 遍历名单逐个处理,替代 @a[scores=...] 批量执行。 |
| 名单 □ 包含 □ ? | ctx.arrayFind(key,值) >= 0,返回真/假,直接接 if。 |
| 积木 | 用途 |
|---|---|
| 往名单 □ 追加 □ | ctx.arrayAdd(key, 值),允许重复。 |
| 往名单 □ 追加(去重)□ | ctx.arrayAddOnce(key, 值),已存在就不加。 |
| 从名单 □ 删除 □ | ctx.arrayRemove(key, 值)。 |
| 清空名单 □ | ctx.arrayClear(key)。 |
| 名单 □ 长度 | ctx.arraySize(key),元素个数。 |
| 名单 □ 取第 □ 个 | ctx.arrayGet(key, 下标),0 起。 |
| 名单 □ 查找 □ | ctx.arrayFind(key, 值),返回位置,找不到 -1。 |
| 名单 □ 用 □ 拼接 | ctx.arrayJoin(key, 分隔符)。 |
| 设置字符串 □ = □ | ctx.setString(key, 值),存单个字符串。 |
| 读取字符串 □ | ctx.getString(key)。 |
| 积木 | 用途 |
|---|---|
| [State] 状态/计时 | |
| 读状态 □ | ctx.getStateInt(key)。 |
| 写状态 □ = □ | ctx.setState(key, 值)。 |
| 等待 □ 刻 / 秒 / 毫秒 | ctx.sleepTicks(n) / sleep(ms)。while 循环必须加。 |
| 当前 tick 数 | 程序启动后经过的游戏刻数。 |
| [Player] 玩家 | |
| 谁按过 相对 x y z 的方块 | ctx.whoUsed(dx,dy,dz),精确识别。 |
| 谁按过 半径 □ 内的方块 | ctx.whoUsedNearby(r)。 |
| 最近玩家 / 最近玩家(半径) | ctx.nearestPlayer()。 |
| 在线玩家数 | ctx.playerCount()。 |
| [CMD] 普通命令积木(直接生成命令字符串) | |
| 给予 / 传送 / 说 / 召唤 / 效果 / 放方块 / 填充 / 击杀 / 游戏模式 / 时间 / 天气 / 标题 | 图形化填参数 → 自动拼命令 → ctx.executeCommand(...)。 |
| 原始命令 □ | 直接写完整命令文本。 |
| 读分数 / 设分数 / 改分数 | ctx.getScore/setScore/addScore。 |
| [Chat] 聊天 | |
| 发消息 / 可点击消息 / 音效 / ActionBar / Title | 对应 sendMessage / sendClickable / playSound / sendActionBar / sendTitle。 |
| [Audio] 自定义音频 | |
| 播放音频 □ 音量 □ | ctx.playAudio(文件名, 音量),文件放存档 res/media/。 |
| 停止所有音频 / 停止 □ | ctx.stopAudio() / stopAudio(文件名)。 |
// 西面按钮按下时
if (ctx.inputChanged(4) && ctx.readInput(4) > 0) {
String p = ctx.whoUsed(-1, 0, 0); // 是谁按的
if (!p.isEmpty()) {
if (ctx.arrayFind("vip", p) >= 0) { // 在 VIP 名单里?
ctx.executeCommand("give " + p + " diamond 1"); // 发钻石
} else {
ctx.arrayAddOnce("vip", p); // 不在就加入名单
}
}
}
/execute 子命令语法、用途与示例
/execute 是 MC 最强大的命令——改执行者、改位置、加条件、存结果,一条命令全搞定。代码方块里所有 execute 积木最终都是拼出 execute ... run ... 字符串交给 ctx.executeCommand() 执行。
execute [修饰子命令] [条件子命令] [store子命令] run <要执行的命令>
子命令从左到右依次生效,run 只能放最后。除 run 外,其他子命令可多个串联、可重复。
| 子命令 | 用途 + 示例 |
|---|---|
as <选择器> |
改执行者(命令里的 @s 指向它),不改位置。例: execute as @a run say 你好 → 每个玩家都说"你好"。 |
at <选择器> |
改执行位置/朝向/维度,不改执行者。 例: execute at @p run setblock ~ ~ ~ stone → 在最近玩家脚下放石头。 |
as <选择器> at @s |
执行者+位置一起改(最常用)。 例: execute as @a at @s run particle flame ~ ~1 ~ → 每个玩家头上冒火焰粒子。 |
positioned <x> <y> <z> |
指定绝对/相对坐标。~ = 相对当前位置,^ = 相对朝向。例: execute positioned ~ ~1 ~ run setblock ~ ~ ~ diamond_block → 头顶放钻石块。 |
in <维度> |
切换执行维度:minecraft:overworld / the_nether / the_end。 |
| 子命令 | 用途 + 示例 |
|---|---|
if/unless entity <选择器> |
实体存在/不存在。 例: execute if entity @e[type=zombie,r=10] run say 附近有僵尸! |
if/unless block <x y z> <方块> |
某位置是不是指定方块。 例: execute if block ~ ~-1 ~ minecraft:gold_block run say 脚下是金块! |
if/unless blocks <x1 y1 z1> <x2 y2 z2> <x y z> all|masked |
两个区域方块是否一致。all=全比,masked=只比非空气。 |
if/unless items entity <选择器> <槽位> <物品> |
实体某槽位是否有某物品。槽位如 weapon.mainhand、armor.head、hotbar.0。例: execute if items entity @s weapon.mainhand minecraft:diamond run say 手持钻石! |
if/unless predicate <谓词> |
数据包谓词条件(高级,用于复杂判定)。 |
if/unless score <目标> <记分项> <操作符> <值> |
记分板分数比较。操作符:= > >= < <=,或 matches 范围。例: execute if score @s money matches 100.. run say 我有100块以上! |
| 子命令 | 用途 + 示例 |
|---|---|
store result score <玩家> <记分项> run <命令> |
把 run 后命令的返回值存进记分板。 例: execute store result score @s online run list → 把在线人数存进 @s 的 online 分数。 |
store success score <玩家> <记分项> |
存命令是否成功(0/1)。 |
ctx.executeCommandResult("execute ... run ...") 直接拿到这个返回值,不用 store 到记分板。
// 1. 让所有玩家传送到代码方块位置
ctx.executeCommand("execute as @a at @s run tp ~ ~ ~");
// 2. 头顶是钻石块就给最近玩家发钻石
if (ctx.executeCommandTest("execute if block ~ ~1 ~ minecraft:diamond_block")) {
ctx.executeCommand("give @p diamond 1");
}
// 3. 统计半径 5 格内的僵尸数量,存进记分板
int zombieCount = ctx.executeCommandResult(
"execute if entity @e[type=zombie,distance=..5]");
ctx.sendMessage("附近僵尸数: " + zombieCount);
// 4. 对 VIP 名单里的每个玩家发奖励(用字符串数组,不用记分板)
for (int i = 0; i < ctx.arraySize("vip"); i++) {
String p = ctx.arrayGet("vip", i);
ctx.executeCommand("give " + p + " diamond 1");
}
// 5. 手持钻石剑才执行后续命令
ctx.executeCommand("execute if items entity @s weapon.mainhand minecraft:diamond_sword run effect give @s strength 10 1");
[Exec] 执行/判断命令 分类里拖,不用手敲命令字符串。带返回值的用「命令成立?」「取结果」积木。