可眩晕的

可眩晕的

一个mod,会在敌人周围显示一个方框/轮廓,让你知道何时开始尝试眩晕猛击。

游戏机制

🟢 眩晕模组(Stunnable Mod)

一个极简、高性能的客户端 Fabric 模组,可在范围内对目标玩家周围添加高度可自定义的动态视觉渲染框和轮廓线。

非常适合保持空间感知,并通过流畅动画、彩虹效果和呼吸渐变来监控眩晕/交互范围。🌟


📋 目录


⚡ 快速入门

  1. 确保你已安装:

    • Fabric Loader
    • Fabric API
    • Cloth Config
    • AutoConfig
  2. stunnable.jar 文件放入你的:

.minecraft/mods
  1. 启动游戏。

  2. 直接通过 ModMenu 打开配置界面。🛠️

自定义:

  • 颜色 🎨
  • 彩虹渲染 🌈
  • 呼吸透明度渐变 🫁
  • 轮廓线宽度 📏
  • 填充透明度 🔥

将 HUD 风格完美调校至你的偏好。


🧠 工作原理 — 核心架构

该模组完全在客户端运行,直接挂接 Minecraft 的渲染生命周期,在附近目标周围绘制平滑覆盖层。🖥️


🔄 核心初始化

该模组使用标准 Fabric 入口点进行初始化和配置设置。

StunnableClient

实现:

ClientModInitializer

负责:

  • 客户端初始化
  • 辅助配置处理

Stunnable

实现:

ClientModInitializer

负责:

  • 注册 AutoConfig 架构
  • 挂接 Fabric 渲染生命周期事件

🎨 渲染生命周期挂接

Stunnable.java 中,模组订阅:

WorldRenderEvents.END_MAIN.register(context -> {
    ...
});

这确保:

  • 每帧更新渲染
  • 无游戏刻延迟
  • 无方块更新依赖
  • 极其平滑的视觉追踪

📐 定位与计算流程

🎯 范围限制

模组通过实体属性动态提取玩家交互范围:

double reach = mc.player.getAttributeValue(Attributes.ENTITY_INTERACTION_RANGE);

📦 相对位移渲染

边界框被转换为相机相对局部坐标以消除渲染抖动:

AABB box = player.getBoundingBox().move(-camPos.x, -camPos.y, -camPos.z);

🚫 目标排除

渲染器遍历已加载玩家,同时排除本地玩家:

if (player != mc.player && playerPos.distanceTo(player.position()) <= reach)

⚙️ 配置选项

该模组包含完整的可配置渲染系统,可通过以下方式访问:

  • ModMenu
  • Cloth Config UI
  • AutoConfig 配置文件

🖼️ 渲染类别

控制:

  • 盒子视觉效果
  • 轮廓线宽度
  • 透明度
  • 基础颜色
选项 类型 默认值 用途
fillColor 颜色选择器(十六进制) 0x00FF00 盒子内部面颜色
outlineColor 颜色选择器(十六进制) 0x00FF00 边界边缘颜色
onlyOutline 布尔值 false 禁用填充渲染
fillOpacity 有界离散值(0-100) 50 填充透明度
outlineWidth 有界离散值(1-5) 2 线条粗细

🌈 效果类别

处理:

  • 动态颜色
  • 动画透明度
  • 程序化视觉效果
选项 类型 默认值 用途
rainbowMode 布尔值 false 启用 HSV 彩虹循环
rainbowSpeed 有界离散值(1-20) 5 色相过渡速度
rainbowFillOnly 布尔值 true 彩虹仅影响填充
breathingEnabled 布尔值 false 启用透明度呼吸
breathingSpeed 有界离散值(1-20) 5 呼吸循环速度
breathingStrength 有界离散值(0-100) 50 呼吸强度

✨ 视觉效果系统


🌈 颜色数学(HSV → RGB)

当彩虹模式启用时,使用时间同步的 HSV 计算动态生成颜色。

这创建了:

  • 平滑渐变
  • 无卡顿
  • 连续光谱过渡
private int hsvToRgb(float hue, float saturation, float value) {
    int h = (int) (hue * 6);
    float f = hue * 6 - h;
    float p = value * (1 - saturation);
    float q = value * (1 - f * saturation);
    float t = value * (1 - (1 - f) * saturation);

    float r, g, b;

    switch (h % 6) {
        case 0 -> {
            r = value;
            g = t;
            b = p;
        }
        case 1 -> {
            r = q;
            g = value;
            b = p;
        }
        case 2 -> {
            r = p;
            g = value;
            b = t;
        }
        case 3 -> {
            r = p;
            g = q;
            b = value;
        }
        case 4 -> {
            r = t;
            g = p;
            b = value;
        }
        case 5 -> {
            r = value;
            g = p;
            b = q;
        }
        default -> {
            r = 0;
            g = 0;
            b = 0;
        }
    }

    return ((int) (r * 255) << 16)
        | ((int) (g * 255) << 8)
        | (int) (b * 255);
}

🫁 呼吸数学

呼吸系统使用平滑的三角函数正弦波周期修改透明度:

float cycle = (float) (
    Math.sin(time * config.breathingSpeed * 0.003)
    * 0.5 + 0.5
);

float strength = config.breathingStrength / 100f;

breathMod = 1f - (
    1f - (0.3f + 0.7f * cycle)
) * strength;

这产生:

  • 平滑脉冲过渡
  • 非线性淡出行为
  • 可调节动画强度

📐 底层顶点缓冲区

渲染通过 Minecraft 内部顶点管线使用 VertexConsumer 原生处理。


🟩 填充盒子

使用:

RenderTypes.debugFilledBox()

手动构建所有六个面:

  • 底部
  • 顶部
  • 北面
  • 南面
  • 东面
  • 西面

示例:

buffer.addVertex(pose, minX, minY, minZ)
    .setColor(r, g, b, a);

buffer.addVertex(pose, maxX, minY, minZ)
    .setColor(r, g, b, a);

buffer.addVertex(pose, maxX, minY, maxZ)
    .setColor(r, g, b, a);

buffer.addVertex(pose, minX, minY, maxZ)
    .setColor(r, g, b, a);

📏 轮廓盒子

使用:

RenderTypes.LINES

在边界坐标上映射显式线段,包含法线和宽度参数。

private void vertex(
    Matrix4f pose,
    VertexConsumer buffer,
    float x,
    float y,
    float z,
    float r,
    float g,
    float b,
    float a,
    float nx,
    float ny,
    float nz,
    float w
) {
    buffer.addVertex(pose, x, y, z)
        .setColor(r, g, b, a)
        .setNormal(nx, ny, nz)
        .setLineWidth(w);
}

🔌 集成与 ModMenu

该模组直接与 ModMenu 集成,实现即时 GUI 配置访问。


📄 ModMenuIntegration.java

package frqme.isa.dev.stunnable.config;

import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import me.shedaniel.autoconfig.AutoConfig;

public class ModMenuIntegration implements ModMenuApi {

    @Override
    @SuppressWarnings("removal")
    public ConfigScreenFactory<?> getModConfigScreenFactory() {
        return parent ->
            AutoConfig
                .getConfigScreen(ModConfig.class, parent)
                .get();
    }
}

这自动桥接:

  • Cloth Config
  • AutoConfig
  • ModMenu

无需:

  • 命令
  • 手动 GUI 处理
  • 自定义界面注册

🛠️