MCIO Plugins MCIO Plugins
首页
爱发电 (opens new window)
无法下载? (opens new window)

人间工作P

我每天都好困… 最近在学习和进行 VOCALOID 创作
首页
爱发电 (opens new window)
无法下载? (opens new window)
  • PluginBase

  • Item-NBT-API

  • VectorDisplays

    • VectorDisplays 简介
    • 内嵌依赖
    • 控件定位
    • 动态添加元素
    • 使用案例
      • 显示二维码
      • 显示图片
      • 播放 Bad Apple!!
      • 贝塞尔曲线变速运动
  • 开发文档
  • VectorDisplays
2025-11-04
目录

使用案例

在这里存放一些 VectorDisplays 使用案例。这些案例可能需要最新开发版的 VectorDisplays 才能使用。

# 显示二维码

额外使用依赖库 top.mrxiaom:qrcode-encoder:1.0.0

public static void applyQRCode(Terminal<?> terminal, QRCode code) {
    int moduleCount = code.getModuleCount();
    double block = 2.0;
    double pos = -(moduleCount * block) / 2.0;
    for (int y = 0; y < moduleCount; y++) {
        for (int x = 0; x < moduleCount; x++) {
            if (!code.isDark(y, x)) continue;
            double posX = pos + x * block, posY = pos + y * block;
            terminal.addElement(new Label("qrcode_" + x + "_" + y), e -> {
                e.setEnabled(false);
                e.setAlign(EnumAlign.CENTER);
                e.setText("        "); // 玄学问题: 文本长度越长,精度越高;只有一个空格的时候精度堪忧
                e.setBackgroundColor(0xFFFFFFFF);
                e.setShadow(false);
                e.setFullBrightness();
                double oldWidth = HologramFont.getWidth(e.getHologram().getTextAsComponent());
                double oldHeight = HologramUtils.LINE_HEIGHT;
                e.setScaleX(HologramUtils.calculateScale(oldWidth, block));
                e.setScaleY(HologramUtils.calculateScale(oldHeight, block));
                e.setPos(posX, posY);
            });
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 显示图片

警告

VectorDisplays 1.0.1 版本暂未对数量非常庞大的悬浮字进行支持。尺寸过大的图片一定会占用多的带宽(即使是本地回环),让服务器暂时停止运行,并且会因为长期无响应导致你的服务器崩溃!
另外,玩家的客户端也无法承载非常庞大的悬浮字数量,可能会使得玩家的 FPS 降低至 0。

除非有特别需要,或者纯粹想装逼,请配合资源包的字体贴图来显示图片,而不是使用这种方法。

public static void applyImage(Terminal<?> terminal, BufferedImage image) {
    double width = 30.0; // 简单地进行等比缩放,宽度在界面上会显示多宽
    int imageWidth = image.getWidth(), imageHeight = image.getHeight();
    double pixelSize = width / imageWidth; // 计算单个像素点的尺寸
    // 图像居中
    double imageX = -pixelSize * imageWidth / 2;
    double imageY = -pixelSize * imageHeight / 2;
    // 提前算好缩放大小,省得在循环里面计算
    double oldWidth = HologramFont.getWidth(Component.text("        "));
    double oldHeight = HologramUtils.LINE_HEIGHT;
    float scaleX = HologramUtils.calculateScale(oldWidth, pixelSize);
    float scaleY = HologramUtils.calculateScale(oldHeight, pixelSize);
    // 按每一行扫描每一个像素,添加为一个 Label
    for (int y = 0; y < imageHeight; y++) {
        for (int x = 0; x < imageWidth; x++) {
            int color = image.getRGB(x, y);
            if (((color >> 24) & 0xFF) == 0) continue; // 忽略透明像素
            double posX = imageX + (x * pixelSize);
            double posY = imageY + (y * pixelSize);
            terminal.addElement(new Label("image_pixel_x" + x + "_y" + y), e -> {
                e.setEnabled(false);
                e.setAlign(EnumAlign.CENTER);
                e.setText("        ");
                e.setFullBrightness();
                e.setBackgroundColor(color);
                e.setShadow(false);
                e.setScaleX(scaleX);
                e.setScaleY(scaleY);
                e.setPos(posX, posY);
            });
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 播放 Bad Apple!!

使用文本展示实体播放 Bad Apple!! 坏苹果(开放源代码)【我的世界/Minecraft】 (opens new window)

# 贝塞尔曲线变速运动

使用类似于 CSS 中 cubic-bezier(a, b, c, d) 的贝塞尔曲线变速动画。

数值可以在 cubic-bezier.com (opens new window) 生成并预览。

public static void spawnWithBezier3(Terminal<?> terminal, Location loc) {
    // 动画机示例 https://cubic-bezier.com/#0,0,.58,1
    spawnWithBezier3(terminal, loc, Bezier3.cubicBezier(.0f, .0f, .58f, 1.0f));
}
public static void spawnWithBezier3(Terminal<?> terminal, Location loc, Bezier3 ani) {
    double distance = 3.0; // y轴移动距离
    long duration = 2000L; // 动画持续时间 (毫秒)
    TerminalManager manager = TerminalManager.inst();
    
    // 设置插值,使得悬浮字移动相对平滑
    for (EntityDisplay<?> display : Terminal.resolveAllEntityDisplay(terminal)) {
        display.setInterpolationDurationRotation(1);
    }

    // 位置计算
    World world = loc.getWorld();
    double x = loc.getX(), y = loc.getY(), z = loc.getZ();
    Function<Float, Location> func = v -> new Location(world, x, y + ((1.0 - v) * distance), z);
    terminal.setLocation(func.apply(0f));

    // 注册并生成悬浮字
    manager.spawn(terminal);

    // 通过异步定时器更新位置
    AtomicReference<IRunTask> task = new AtomicReference<>(null);
    task.set(manager.getPlugin().getScheduler().runTaskTimerAsynchronously(() -> {
        if (ani.getStartTime() == 0L) {
            // 初始化动画机时间
            ani.setStartTime(System.currentTimeMillis());
            ani.setDuration(duration);
        }
        // 更新位置
        terminal.setLocation(func.apply(ani.getPoint()[1]));
        // 若动画已结束,停止定时器
        if (ani.hasEnd() && task.get() != null) {
            task.get().cancel();
            task.set(null);
        }
    }, 2L, 1L));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
上次更新: 2025/12/08, 04:32:33
动态添加元素

← 动态添加元素

使用主题 Vdoing | Copyright © 2018-2025 人间工作P | 到爱发电支持我 | 8490200

除非特别说明,本站点所有文章均以 CC BY-SA 协议授权

《我的世界》和《Minecraft》是微软公司和 Mojang Synergies AB 的商标,本站点与微软公司等没有从属关系。

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式